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 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

View File

@ -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;
}