summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/windows/winsync.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/windows/winsync.c')
-rw-r--r--src/osd/windows/winsync.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/osd/windows/winsync.c b/src/osd/windows/winsync.c
new file mode 100644
index 00000000000..4d86d2ef061
--- /dev/null
+++ b/src/osd/windows/winsync.c
@@ -0,0 +1,157 @@
+//============================================================
+//
+// winsync.c - Win32 OSD core synchronization functions
+//
+// Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
+// Visit http://mamedev.org for licensing and usage restrictions.
+//
+//============================================================
+
+// standard windows headers
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+// MAME headers
+#include "osdcore.h"
+
+
+//============================================================
+// DEBUGGING
+//============================================================
+
+#define DEBUG_SLOW_LOCKS 0
+
+
+
+//============================================================
+// TYPE DEFINITIONS
+//============================================================
+
+typedef BOOL (WINAPI *try_enter_critical_section_ptr)(LPCRITICAL_SECTION lpCriticalSection);
+
+struct _osd_lock
+{
+ CRITICAL_SECTION critsect;
+};
+
+
+
+//============================================================
+// GLOBAL VARIABLES
+//============================================================
+
+static try_enter_critical_section_ptr try_enter_critical_section = NULL;
+static int checked_for_try_enter = FALSE;
+
+
+
+//============================================================
+// osd_lock_alloc
+//============================================================
+
+osd_lock *osd_lock_alloc(void)
+{
+ osd_lock *lock = malloc(sizeof(*lock));
+ if (lock == NULL)
+ return NULL;
+ InitializeCriticalSection(&lock->critsect);
+ return lock;
+}
+
+
+//============================================================
+// osd_lock_acquire
+//============================================================
+
+void osd_lock_acquire(osd_lock *lock)
+{
+#if DEBUG_SLOW_LOCKS
+ osd_ticks_t ticks = osd_ticks();
+#endif
+
+ // block until we can acquire the lock
+ EnterCriticalSection(&lock->critsect);
+
+#if DEBUG_SLOW_LOCKS
+ // log any locks that take more than 1ms
+ ticks = osd_ticks() - ticks;
+ if (ticks > osd_ticks_per_second() / 1000) mame_printf_debug("Blocked %d ticks on lock acquire\n", (int)ticks);
+#endif
+}
+
+
+//============================================================
+// osd_lock_try
+//============================================================
+
+int osd_lock_try(osd_lock *lock)
+{
+ int result = TRUE;
+
+ // if we haven't yet checked for the TryEnter API, do it now
+ if (!checked_for_try_enter)
+ {
+ // see if we can use TryEnterCriticalSection
+ HMODULE library = LoadLibrary(TEXT("kernel32.dll"));
+ if (library != NULL)
+ try_enter_critical_section = (try_enter_critical_section_ptr)GetProcAddress(library, "TryEnterCriticalSection");
+ checked_for_try_enter = TRUE;
+ }
+
+ // if we have it, use it, otherwise just block
+ if (try_enter_critical_section != NULL)
+ result = (*try_enter_critical_section)(&lock->critsect);
+ else
+ EnterCriticalSection(&lock->critsect);
+ return result;
+}
+
+
+//============================================================
+// osd_lock_release
+//============================================================
+
+void osd_lock_release(osd_lock *lock)
+{
+ LeaveCriticalSection(&lock->critsect);
+}
+
+
+//============================================================
+// osd_lock_free
+//============================================================
+
+void osd_lock_free(osd_lock *lock)
+{
+ DeleteCriticalSection(&lock->critsect);
+ free(lock);
+}
+
+
+//============================================================
+// osd_compare_exchange32
+//============================================================
+
+#ifndef osd_compare_exchange32
+INT32 osd_compare_exchange32(INT32 volatile *ptr, INT32 compare, INT32 exchange)
+{
+ return InterlockedCompareExchange((LPLONG)ptr, (LONG)exchange, (LONG)compare);
+}
+#endif
+
+
+//============================================================
+// osd_compare_exchange64
+//============================================================
+
+#ifdef PTR64
+#ifndef osd_compare_exchange64
+INT64 osd_compare_exchange64(INT64 volatile *ptr, INT64 compare, INT64 exchange)
+{
+ return InterlockedCompareExchange64((LONGLONG*)ptr, (LONGLONG)exchange, (LONGLONG)compare);
+}
+#endif
+#endif