summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/osdsync.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/osdsync.cpp')
-rw-r--r--src/osd/osdsync.cpp112
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;
}