diff options
Diffstat (limited to 'src/osd/osdsync.cpp')
-rw-r--r-- | src/osd/osdsync.cpp | 112 |
1 files changed, 54 insertions, 58 deletions
diff --git a/src/osd/osdsync.cpp b/src/osd/osdsync.cpp index f8143aa2c51..b2300e93ee6 100644 --- a/src/osd/osdsync.cpp +++ b/src/osd/osdsync.cpp @@ -10,10 +10,10 @@ #include <windows.h> #include <process.h> #include <tchar.h> -#include <stdlib.h> +#include <cstdlib> #ifdef __GNUC__ -#include <stdint.h> +#include <cstdint> #endif #endif #include <mutex> @@ -85,14 +85,15 @@ static void spin_while_not(const volatile _AtomType * volatile atom, const _Main // osd_num_processors //============================================================ -int osd_get_num_processors(void) +int osd_get_num_processors(bool heavy_mt) { #if defined(SDLMAME_EMSCRIPTEN) // multithreading is not supported at this time return 1; #else + unsigned int threads = std::thread::hardware_concurrency(); // max out at 4 for now since scaling above that seems to do poorly - return std::min(std::thread::hardware_concurrency(), 4U); + return heavy_mt ? threads : std::min(std::thread::hardware_concurrency(), 4U); #endif } @@ -103,28 +104,27 @@ int osd_get_num_processors(void) struct work_thread_info { work_thread_info(uint32_t aid, osd_work_queue &aqueue) - : queue(aqueue) - , handle(nullptr) - , wakeevent(false, false) // auto-reset, not signalled - , active(0) - , id(aid) + : queue(aqueue) + , handle(nullptr) + , wakeevent(true, false) // manual reset, not signalled + , id(aid) #if KEEP_STATISTICS - , itemsdone(0) - , actruntime(0) - , runtime(0) - , spintime(0) - , waittime(0) + , itemsdone(0) + , actruntime(0) + , runtime(0) + , spintime(0) + , waittime(0) #endif { } + osd_work_queue & queue; // pointer back to the queue std::thread * handle; // handle to the thread osd_event wakeevent; // wake event for the thread - std::atomic<int32_t> active; // are we actively processing work? - uint32_t id; + uint32_t id; #if KEEP_STATISTICS - int32_t itemsdone; + int32_t itemsdone; osd_ticks_t actruntime; osd_ticks_t runtime; osd_ticks_t spintime; @@ -136,21 +136,21 @@ struct work_thread_info struct osd_work_queue { osd_work_queue() - : list(nullptr) - , tailptr(nullptr) - , free(nullptr) - , items(0) - , livethreads(0) - , waiting(0) - , exiting(0) - , threads(0) - , flags(0) - , doneevent(true, true) // manual reset, signalled + : list(nullptr) + , tailptr(nullptr) + , free(nullptr) + , items(0) + , livethreads(0) + , waiting(0) + , exiting(0) + , threads(0) + , flags(0) + , doneevent(true, true) // manual reset, signalled #if KEEP_STATISTICS - , itemsqueued(0) - , setevents(0) - , extraitems(0) - , spinloops(0) + , itemsqueued(0) + , setevents(0) + , extraitems(0) + , spinloops(0) #endif { } @@ -180,14 +180,14 @@ struct osd_work_queue struct osd_work_item { osd_work_item(osd_work_queue &aqueue) - : next(nullptr) - , queue(aqueue) - , callback(nullptr) - , param(nullptr) - , result(nullptr) - , event(nullptr) // manual reset, not signalled - , flags(0) - , done(false) + : next(nullptr) + , queue(aqueue) + , callback(nullptr) + , param(nullptr) + , result(nullptr) + , event(nullptr) // manual reset, not signalled + , flags(0) + , done(false) { } @@ -197,7 +197,7 @@ struct osd_work_item void * param; // callback parameter void * result; // callback result osd_event * event; // event signalled when complete - uint32_t flags; // creation flags + uint32_t flags; // creation flags std::atomic<int32_t> done; // is the item done? }; @@ -211,8 +211,8 @@ int osd_num_processors = 0; // FUNCTION PROTOTYPES //============================================================ -static int effective_num_processors(void); -static void * worker_thread_entry(void *param); +static int effective_num_processors(bool heavy_mt); +static void *worker_thread_entry(void *param); static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread); static bool queue_has_list_items(osd_work_queue *queue); @@ -251,7 +251,7 @@ int thread_adjust_priority(std::thread *thread, int adjust) osd_work_queue *osd_work_queue_alloc(int flags) { int threadnum; - int numprocs = effective_num_processors(); + int numprocs = effective_num_processors(!(flags & WORK_QUEUE_FLAG_HIGH_FREQ)); osd_work_queue *queue; int osdthreadnum = 0; int allocthreadnum; @@ -287,7 +287,7 @@ osd_work_queue *osd_work_queue_alloc(int flags) if (flags & WORK_QUEUE_FLAG_MULTI) allocthreadnum = queue->threads + 1; else - allocthreadnum = queue->threads; + allocthreadnum = std::max(queue->threads, 1u); #if KEEP_STATISTICS printf("osdprocs: %d effecprocs: %d threads: %d allocthreads: %d osdthreads: %d maxthreads: %d queuethreads: %d\n", osd_num_processors, numprocs, threadnum, allocthreadnum, osdthreadnum, WORK_MAX_THREADS, queue->threads); @@ -445,20 +445,18 @@ void osd_work_queue_free(osd_work_queue *queue) // free all items in the free list while (queue->free.load() != nullptr) { - osd_work_item *item = (osd_work_item *)queue->free; + auto *item = (osd_work_item *)queue->free; queue->free = item->next; - if (item->event != nullptr) - delete item->event; + delete item->event; delete item; } // free all items in the active list while (queue->list.load() != nullptr) { - osd_work_item *item = (osd_work_item *)queue->list; + auto *item = (osd_work_item *)queue->list; queue->list = item->next; - if (item->event != nullptr) - delete item->event; + delete item->event; delete item; } @@ -546,10 +544,9 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call { work_thread_info *thread = queue->thread[threadnum]; - // if this thread is not active, wake him up - if (!thread->active) + // Attempt to wake the thread + if (thread->wakeevent.set()) { - thread->wakeevent.set(); add_to_stat(queue->setevents, 1); // for non-shared, the first one we find is good enough @@ -641,9 +638,9 @@ void osd_work_item_release(osd_work_item *item) // effective_num_processors //============================================================ -static int effective_num_processors(void) +static int effective_num_processors(bool heavy_mt) { - int physprocs = osd_get_num_processors(); + int physprocs = osd_get_num_processors(heavy_mt); // osd_num_processors == 0 for 'auto' if (osd_num_processors > 0) @@ -672,7 +669,7 @@ static int effective_num_processors(void) static void *worker_thread_entry(void *param) { - work_thread_info *thread = (work_thread_info *)param; + auto *thread = (work_thread_info *)param; osd_work_queue &queue = thread->queue; // loop until we exit @@ -694,7 +691,6 @@ static void *worker_thread_entry(void *param) break; // indicate that we are live - thread->active = true; ++queue.livethreads; // process work items @@ -719,7 +715,7 @@ static void *worker_thread_entry(void *param) } // decrement the live thread count - thread->active = false; + thread->wakeevent.reset(); --queue.livethreads; } |