diff options
author | Oliver Stöneberg <oliverst@online.de> | 2015-01-01 20:03:07 +0100 |
---|---|---|
committer | Oliver Stöneberg <oliverst@online.de> | 2015-01-01 20:03:07 +0100 |
commit | 6c0a4f47e37f8c4ca177e278ce4a186714ae20e7 (patch) | |
tree | 4244028377a2b479cf4c18235eafbca0c6936c4c /src | |
parent | 1c94c3f40892165b5d7a822cc80a90ef16b42342 (diff) |
a few more data race fixes / cleanups (nw)
Diffstat (limited to 'src')
-rw-r--r-- | src/osd/sdl/sdlwork.c | 58 | ||||
-rw-r--r-- | src/osd/windows/winwork.c | 59 |
2 files changed, 65 insertions, 52 deletions
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 diff --git a/src/osd/windows/winwork.c b/src/osd/windows/winwork.c index c987cca7c33..34f2379cedb 100644 --- a/src/osd/windows/winwork.c +++ b/src/osd/windows/winwork.c @@ -149,6 +149,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); //============================================================ @@ -450,7 +451,7 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call item->callback = callback; item->param = parambase; item->result = NULL; - item->flags = flags; + item->flags = flags; // advance to the next lastitem = item; @@ -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) @@ -657,7 +652,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); } @@ -685,26 +680,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) @@ -736,8 +736,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); } } @@ -751,3 +750,11 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa end_timing(thread->runtime); } + +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; +} |