From 6c0a4f47e37f8c4ca177e278ce4a186714ae20e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Thu, 1 Jan 2015 20:03:07 +0100 Subject: a few more data race fixes / cleanups (nw) --- src/osd/sdl/sdlwork.c | 58 ++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 26 deletions(-) (limited to 'src/osd/sdl/sdlwork.c') diff --git a/src/osd/sdl/sdlwork.c b/src/osd/sdl/sdlwork.c index 216858af36e..32fe3a8fe1e 100644 --- a/src/osd/sdl/sdlwork.c +++ b/src/osd/sdl/sdlwork.c @@ -139,6 +139,7 @@ int osd_num_processors = 0; static int effective_num_processors(void); 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); //============================================================ @@ -617,17 +618,11 @@ static void *worker_thread_entry(void *param) if (queue->exiting) break; + if (!queue_has_list_items(queue)) { - INT32 lockslot = osd_scalable_lock_acquire(queue->lock); - bool wait_for_event = (queue->list == NULL); - osd_scalable_lock_release(queue->lock, lockslot); - - if (wait_for_event) - { - begin_timing(thread->waittime); - osd_event_wait(thread->wakeevent, INFINITE); - end_timing(thread->waittime); - } + begin_timing(thread->waittime); + osd_event_wait(thread->wakeevent, INFINITE); + end_timing(thread->waittime); } if (queue->exiting) @@ -661,7 +656,7 @@ static void *worker_thread_entry(void *param) } // if nothing more, release the processor - if (queue->list == NULL) + if (!queue_has_list_items(queue)) break; add_to_stat(&queue->spinloops, 1); } @@ -694,26 +689,31 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa { osd_work_item *item; + bool end_loop = false; + // use a critical section to synchronize the removal of items - INT32 lockslot = osd_scalable_lock_acquire(queue->lock); { + INT32 lockslot = osd_scalable_lock_acquire(queue->lock); if (queue->list == NULL) { - osd_scalable_lock_release(queue->lock, lockslot); - break; + end_loop = true; } - - - // pull the item from the queue - item = (osd_work_item *)queue->list; - if (item != NULL) + else { - queue->list = item->next; - if (queue->list == NULL) - queue->tailptr = (osd_work_item **)&queue->list; + // pull the item from the queue + item = (osd_work_item *)queue->list; + if (item != NULL) + { + queue->list = item->next; + if (queue->list == NULL) + queue->tailptr = (osd_work_item **)&queue->list; + } } + osd_scalable_lock_release(queue->lock, lockslot); } - osd_scalable_lock_release(queue->lock, lockslot); + + if (end_loop) + break; // process non-NULL items if (item != NULL) @@ -745,8 +745,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa } // if we removed an item and there's still work to do, bump the stats - // TODO: data race - if (queue->list != NULL) + if (queue_has_list_items(queue)) add_to_stat(&queue->extraitems, 1); } } @@ -761,4 +760,11 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa end_timing(thread->runtime); } -#endif // SDLMAME_NOASM +bool queue_has_list_items(osd_work_queue *queue) +{ + INT32 lockslot = osd_scalable_lock_acquire(queue->lock); + bool has_list_items = (queue->list != NULL); + osd_scalable_lock_release(queue->lock, lockslot); + return has_list_items; +} +#endif // SDLMAME_NOASM \ No newline at end of file -- cgit v1.2.3