a few more data race fixes / cleanups (nw)

This commit is contained in:
Oliver Stöneberg 2015-01-01 20:03:07 +01:00
parent 1c94c3f408
commit 6c0a4f47e3
2 changed files with 65 additions and 52 deletions

View File

@ -139,6 +139,7 @@ int osd_num_processors = 0;
static int effective_num_processors(void); static int effective_num_processors(void);
static void * worker_thread_entry(void *param); static void * worker_thread_entry(void *param);
static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread); 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) if (queue->exiting)
break; break;
if (!queue_has_list_items(queue))
{ {
INT32 lockslot = osd_scalable_lock_acquire(queue->lock); begin_timing(thread->waittime);
bool wait_for_event = (queue->list == NULL); osd_event_wait(thread->wakeevent, INFINITE);
osd_scalable_lock_release(queue->lock, lockslot); end_timing(thread->waittime);
if (wait_for_event)
{
begin_timing(thread->waittime);
osd_event_wait(thread->wakeevent, INFINITE);
end_timing(thread->waittime);
}
} }
if (queue->exiting) if (queue->exiting)
@ -661,7 +656,7 @@ static void *worker_thread_entry(void *param)
} }
// if nothing more, release the processor // if nothing more, release the processor
if (queue->list == NULL) if (!queue_has_list_items(queue))
break; break;
add_to_stat(&queue->spinloops, 1); 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; osd_work_item *item;
bool end_loop = false;
// use a critical section to synchronize the removal of items // 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) if (queue->list == NULL)
{ {
osd_scalable_lock_release(queue->lock, lockslot); end_loop = true;
break;
} }
else
// pull the item from the queue
item = (osd_work_item *)queue->list;
if (item != NULL)
{ {
queue->list = item->next; // pull the item from the queue
if (queue->list == NULL) item = (osd_work_item *)queue->list;
queue->tailptr = (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 // process non-NULL items
if (item != NULL) 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 // if we removed an item and there's still work to do, bump the stats
// TODO: data race if (queue_has_list_items(queue))
if (queue->list != NULL)
add_to_stat(&queue->extraitems, 1); 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); 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;
}
#endif // SDLMAME_NOASM #endif // SDLMAME_NOASM

View File

@ -149,6 +149,7 @@ int osd_num_processors = 0;
static int effective_num_processors(void); static int effective_num_processors(void);
static void * worker_thread_entry(void *param); static void * worker_thread_entry(void *param);
static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread); 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) if (queue->exiting)
break; break;
if (!queue_has_list_items(queue))
{ {
INT32 lockslot = osd_scalable_lock_acquire(queue->lock); begin_timing(thread->waittime);
bool wait_for_event = (queue->list == NULL); osd_event_wait(thread->wakeevent, INFINITE);
osd_scalable_lock_release(queue->lock, lockslot); end_timing(thread->waittime);
if (wait_for_event)
{
begin_timing(thread->waittime);
osd_event_wait(thread->wakeevent, INFINITE);
end_timing(thread->waittime);
}
} }
if (queue->exiting) if (queue->exiting)
@ -657,7 +652,7 @@ static void *worker_thread_entry(void *param)
} }
// if nothing more, release the processor // if nothing more, release the processor
if (queue->list == NULL) if (!queue_has_list_items(queue))
break; break;
add_to_stat(&queue->spinloops, 1); 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; osd_work_item *item;
bool end_loop = false;
// use a critical section to synchronize the removal of items // 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) if (queue->list == NULL)
{ {
osd_scalable_lock_release(queue->lock, lockslot); end_loop = true;
break;
} }
else
// pull the item from the queue
item = (osd_work_item *)queue->list;
if (item != NULL)
{ {
queue->list = item->next; // pull the item from the queue
if (queue->list == NULL) item = (osd_work_item *)queue->list;
queue->tailptr = (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 // process non-NULL items
if (item != NULL) 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 // if we removed an item and there's still work to do, bump the stats
// TODO: data race if (queue_has_list_items(queue))
if (queue->list != NULL)
add_to_stat(&queue->extraitems, 1); 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); 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;
}