summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
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
commit6c0a4f47e37f8c4ca177e278ce4a186714ae20e7 (patch)
tree4244028377a2b479cf4c18235eafbca0c6936c4c /src
parent1c94c3f40892165b5d7a822cc80a90ef16b42342 (diff)
a few more data race fixes / cleanups (nw)
Diffstat (limited to 'src')
-rw-r--r--src/osd/sdl/sdlwork.c58
-rw-r--r--src/osd/windows/winwork.c59
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;
+}