summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Oliver Stöneberg <firewave@users.noreply.github.com>2014-09-13 10:04:16 +0000
committer Oliver Stöneberg <firewave@users.noreply.github.com>2014-09-13 10:04:16 +0000
commit4d5cd617652e189f6c7fcdb2db3096a078a40c19 (patch)
tree79f8892ffd280f4226871ad4c2b82e53d07841e5
parent0f15f0ab00187002c23b99648286a0f58a270a3a (diff)
some refactoring to make SDL and Windows OSD code match / Windows SDL code did not delete the critical section in osd_scalable_lock_free() (nw)
-rw-r--r--.gitattributes1
-rw-r--r--src/osd/sdl/sdlsync_win32.c4
-rw-r--r--src/osd/windows/winsync.c75
-rw-r--r--src/osd/windows/winsync.h27
-rw-r--r--src/osd/windows/winwork.c98
5 files changed, 121 insertions, 84 deletions
diff --git a/.gitattributes b/.gitattributes
index 9b175fdbd08..19f6453d3d9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -9556,6 +9556,7 @@ src/osd/windows/winprefix.h svneol=native#text/plain
src/osd/windows/winptty.c svneol=native#text/plain
src/osd/windows/winsocket.c svneol=native#text/plain
src/osd/windows/winsync.c svneol=native#text/plain
+src/osd/windows/winsync.h svneol=native#text/plain
src/osd/windows/wintime.c svneol=native#text/plain
src/osd/windows/winutf8.c svneol=native#text/plain
src/osd/windows/winutf8.h svneol=native#text/plain
diff --git a/src/osd/sdl/sdlsync_win32.c b/src/osd/sdl/sdlsync_win32.c
index 7e006f16828..97915c32ad8 100644
--- a/src/osd/sdl/sdlsync_win32.c
+++ b/src/osd/sdl/sdlsync_win32.c
@@ -156,6 +156,10 @@ void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot)
void osd_scalable_lock_free(osd_scalable_lock *lock)
{
+#if USE_SCALABLE_LOCKS
+#else
+ DeleteCriticalSection(&lock->section);
+#endif
free(lock);
}
diff --git a/src/osd/windows/winsync.c b/src/osd/windows/winsync.c
index 3a3b449b341..d1d16333a78 100644
--- a/src/osd/windows/winsync.c
+++ b/src/osd/windows/winsync.c
@@ -21,6 +21,7 @@
//============================================================
#define DEBUG_SLOW_LOCKS 0
+#define USE_SCALABLE_LOCKS (0)
@@ -35,6 +36,19 @@ struct osd_lock
CRITICAL_SECTION critsect;
};
+struct osd_scalable_lock
+{
+#if USE_SCALABLE_LOCKS
+ struct
+ {
+ volatile INT32 haslock; // do we have the lock?
+ INT32 filler[64/4-1]; // assumes a 64-byte cache line
+ } slot[WORK_MAX_THREADS]; // one slot per thread
+ volatile INT32 nextindex; // index of next slot to use
+#else
+ CRITICAL_SECTION section;
+#endif
+};
//============================================================
@@ -169,3 +183,64 @@ INT32 win_atomic_add32(INT32 volatile *ptr, INT32 delta)
{
return InterlockedExchangeAdd((LONG *) ptr, delta) + delta;
}
+
+//============================================================
+// Scalable Locks
+//============================================================
+
+osd_scalable_lock *osd_scalable_lock_alloc(void)
+{
+ osd_scalable_lock *lock;
+
+ lock = (osd_scalable_lock *)calloc(1, sizeof(*lock));
+
+ memset(lock, 0, sizeof(*lock));
+#if USE_SCALABLE_LOCKS
+ lock->slot[0].haslock = TRUE;
+#else
+ InitializeCriticalSection(&lock->section);
+#endif
+ return lock;
+}
+
+
+INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock)
+{
+#if USE_SCALABLE_LOCKS
+ INT32 myslot = (atomic_increment32(&lock->nextindex) - 1) & (WORK_MAX_THREADS - 1);
+ INT32 backoff = 1;
+
+ while (!lock->slot[myslot].haslock)
+ {
+ INT32 backcount;
+ for (backcount = 0; backcount < backoff; backcount++)
+ osd_yield_processor();
+ backoff <<= 1;
+ }
+ lock->slot[myslot].haslock = FALSE;
+ return myslot;
+#else
+ EnterCriticalSection(&lock->section);
+ return 0;
+#endif
+}
+
+
+void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot)
+{
+#if USE_SCALABLE_LOCKS
+ atomic_exchange32(&lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock, TRUE);
+#else
+ LeaveCriticalSection(&lock->section);
+#endif
+}
+
+
+void osd_scalable_lock_free(osd_scalable_lock *lock)
+{
+#if USE_SCALABLE_LOCKS
+#else
+ DeleteCriticalSection(&lock->section);
+#endif
+ free(lock);
+} \ No newline at end of file
diff --git a/src/osd/windows/winsync.h b/src/osd/windows/winsync.h
new file mode 100644
index 00000000000..ddfd9150204
--- /dev/null
+++ b/src/osd/windows/winsync.h
@@ -0,0 +1,27 @@
+//============================================================
+//
+// winsync.h - Windows core synchronization functions
+//
+// Copyright (c) 1996-2014, Nicola Salmoria and the MAME Team.
+// Visit http://mamedev.org for licensing and usage restrictions.
+//
+//============================================================
+
+#ifndef __WINSYNC__
+#define __WINSYNC__
+
+//============================================================
+// Scalable Locks
+//============================================================
+
+struct osd_scalable_lock;
+
+osd_scalable_lock *osd_scalable_lock_alloc(void);
+
+INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock);
+
+void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot);
+
+void osd_scalable_lock_free(osd_scalable_lock *lock);
+
+#endif /* __WINSYNC__ */ \ No newline at end of file
diff --git a/src/osd/windows/winwork.c b/src/osd/windows/winwork.c
index aaa10995177..a4dc3bc881a 100644
--- a/src/osd/windows/winwork.c
+++ b/src/osd/windows/winwork.c
@@ -19,6 +19,9 @@
// MAME headers
#include "osdcore.h"
+
+#include "winsync.h"
+
#include "eminline.h"
@@ -27,9 +30,6 @@
//============================================================
#define KEEP_STATISTICS (0)
-#define USE_SCALABLE_LOCKS (0)
-
-
//============================================================
// PARAMETERS
@@ -79,21 +79,6 @@ INLINE void osd_yield_processor(void)
// TYPE DEFINITIONS
//============================================================
-struct scalable_lock
-{
-#if USE_SCALABLE_LOCKS
- struct
- {
- volatile INT32 haslock; // do we have the lock?
- INT32 filler[64/4-1]; // assumes a 64-byte cache line
- } slot[WORK_MAX_THREADS]; // one slot per thread
- volatile INT32 nextindex; // index of next slot to use
-#else
- CRITICAL_SECTION section;
-#endif
-};
-
-
struct work_thread_info
{
osd_work_queue * queue; // pointer back to the queue
@@ -113,7 +98,7 @@ struct work_thread_info
struct osd_work_queue
{
- scalable_lock lock; // lock for protecting the queue
+ osd_scalable_lock * lock; // lock for protecting the queue
osd_work_item * volatile list; // list of items in the queue
osd_work_item ** volatile tailptr; // pointer to the tail pointer of work items in the queue
osd_work_item * volatile free; // free list of work items
@@ -162,63 +147,6 @@ static unsigned __stdcall worker_thread_entry(void *param);
static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread);
-
-//============================================================
-// Scalable Locks
-//============================================================
-
-INLINE void scalable_lock_init(scalable_lock *lock)
-{
- memset(lock, 0, sizeof(*lock));
-#if USE_SCALABLE_LOCKS
- lock->slot[0].haslock = TRUE;
-#else
- InitializeCriticalSection(&lock->section);
-#endif
-}
-
-
-INLINE INT32 scalable_lock_acquire(scalable_lock *lock)
-{
-#if USE_SCALABLE_LOCKS
- INT32 myslot = (atomic_increment32(&lock->nextindex) - 1) & (WORK_MAX_THREADS - 1);
- INT32 backoff = 1;
-
- while (!lock->slot[myslot].haslock)
- {
- INT32 backcount;
- for (backcount = 0; backcount < backoff; backcount++)
- osd_yield_processor();
- backoff <<= 1;
- }
- lock->slot[myslot].haslock = FALSE;
- return myslot;
-#else
- EnterCriticalSection(&lock->section);
- return 0;
-#endif
-}
-
-
-INLINE void scalable_lock_release(scalable_lock *lock, INT32 myslot)
-{
-#if USE_SCALABLE_LOCKS
- atomic_exchange32(&lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock, TRUE);
-#else
- LeaveCriticalSection(&lock->section);
-#endif
-}
-
-
-INLINE void scalable_lock_delete(scalable_lock *lock)
-{
-#if USE_SCALABLE_LOCKS
-#else
- DeleteCriticalSection(&lock->section);
-#endif
-}
-
-
//============================================================
// osd_work_queue_alloc
//============================================================
@@ -246,7 +174,9 @@ osd_work_queue *osd_work_queue_alloc(int flags)
goto error;
// initialize the critical section
- scalable_lock_init(&queue->lock);
+ queue->lock = osd_scalable_lock_alloc();
+ if (queue->lock == NULL)
+ goto error;
// determine how many threads to create...
// on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
@@ -341,7 +271,6 @@ int osd_work_queue_wait(osd_work_queue *queue, osd_ticks_t timeout)
if (queue->flags & WORK_QUEUE_FLAG_MULTI)
{
work_thread_info *thread = &queue->thread[queue->threads];
- osd_ticks_t stopspin = osd_ticks() + timeout;
end_timing(thread->waittime);
@@ -351,6 +280,8 @@ int osd_work_queue_wait(osd_work_queue *queue, osd_ticks_t timeout)
// if we're a high frequency queue, spin until done
if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ)
{
+ osd_ticks_t stopspin = osd_ticks() + timeout;
+
// spin until we're done
begin_timing(thread->spintime);
while (queue->items != 0 && osd_ticks() < stopspin)
@@ -435,8 +366,6 @@ void osd_work_queue_free(osd_work_queue *queue)
if (queue->thread != NULL)
free(queue->thread);
- scalable_lock_delete(&queue->lock);
-
// free all the events
if (queue->doneevent != NULL)
CloseHandle(queue->doneevent);
@@ -468,6 +397,7 @@ void osd_work_queue_free(osd_work_queue *queue)
printf("Spin loops = %9d\n", queue->spinloops);
#endif
+ osd_scalable_lock_free(queue->lock);
// free the queue itself
free(queue);
}
@@ -522,10 +452,10 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call
}
// enqueue the whole thing within the critical section
- lockslot = scalable_lock_acquire(&queue->lock);
+ lockslot = osd_scalable_lock_acquire(queue->lock);
*queue->tailptr = itemlist;
queue->tailptr = item_tailptr;
- scalable_lock_release(&queue->lock, lockslot);
+ osd_scalable_lock_release(queue->lock, lockslot);
// increment the number of items in the queue
atomic_add32(&queue->items, numitems);
@@ -732,7 +662,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa
INT32 lockslot;
// use a critical section to synchronize the removal of items
- lockslot = scalable_lock_acquire(&queue->lock);
+ lockslot = osd_scalable_lock_acquire(queue->lock);
{
// pull the item from the queue
item = (osd_work_item *)queue->list;
@@ -743,7 +673,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa
queue->tailptr = (osd_work_item **)&queue->list;
}
}
- scalable_lock_release(&queue->lock, lockslot);
+ osd_scalable_lock_release(queue->lock, lockslot);
// process non-NULL items
if (item != NULL)