diff options
Diffstat (limited to 'src/osd/modules/sync/sync_sdl.c')
-rw-r--r-- | src/osd/modules/sync/sync_sdl.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/src/osd/modules/sync/sync_sdl.c b/src/osd/modules/sync/sync_sdl.c new file mode 100644 index 00000000000..fe1fdafe0bc --- /dev/null +++ b/src/osd/modules/sync/sync_sdl.c @@ -0,0 +1,352 @@ +//============================================================ +// +// sdlsync.c - SDL core synchronization functions +// +// Copyright (c) 1996-2010, Nicola Salmoria and the MAME Team. +// Visit http://mamedev.org for licensing and usage restrictions. +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#include "sdlinc.h" + +// standard C headers +#include <unistd.h> + +// MAME headers +#include "osdcore.h" +#include "osinline.h" +#include "osdsync.h" + +#include "eminline.h" + +#define VERBOSE (0) + +#if VERBOSE +#define LOG( x ) do { printf x; printf("\n"); } while (0) +#else +#define LOG( x ) +#endif +struct hidden_mutex_t { + SDL_mutex * id; + volatile INT32 locked; + volatile INT32 threadid; +}; + +struct osd_event { + SDL_mutex * mutex; + SDL_cond * cond; + volatile INT32 autoreset; + volatile INT32 signalled; +}; + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +struct osd_thread { + SDL_Thread * thread; + osd_thread_callback callback; + void *param; +}; + +struct osd_scalable_lock +{ + SDL_mutex * mutex; +}; + +//============================================================ +// Scalable Locks +//============================================================ + +osd_scalable_lock *osd_scalable_lock_alloc(void) +{ + osd_scalable_lock *lock; + + lock = (osd_scalable_lock *)calloc(1, sizeof(*lock)); + + lock->mutex = SDL_CreateMutex(); + return lock; +} + + +INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock) +{ + SDL_mutexP(lock->mutex); + return 0; +} + + +void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot) +{ + SDL_mutexV(lock->mutex); +} + +void osd_scalable_lock_free(osd_scalable_lock *lock) +{ + SDL_DestroyMutex(lock->mutex); + free(lock); +} + +//============================================================ +// osd_lock_alloc +//============================================================ + +osd_lock *osd_lock_alloc(void) +{ + hidden_mutex_t *mutex; + + mutex = (hidden_mutex_t *)calloc(1, sizeof(hidden_mutex_t)); + + mutex->id = SDL_CreateMutex(); + + return (osd_lock *)mutex; +} + +//============================================================ +// osd_lock_acquire +//============================================================ + +void osd_lock_acquire(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + LOG(("osd_lock_acquire")); + /* get the lock */ + mutex->locked++; /* signal that we are *about* to lock - prevent osd_lock_try */ + SDL_mutexP(mutex->id); + mutex->threadid = SDL_ThreadID(); +} + +//============================================================ +// osd_lock_try +//============================================================ + +int osd_lock_try(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + LOG(("osd_lock_try")); + if (mutex->locked && mutex->threadid == SDL_ThreadID()) + { + /* get the lock */ + SDL_mutexP(mutex->id); + mutex->locked++; + mutex->threadid = SDL_ThreadID(); + return 1; + } + else if ((mutex->locked == 0)) + { + /* get the lock */ + mutex->locked++; + SDL_mutexP(mutex->id); + mutex->threadid = SDL_ThreadID(); + return 1; + } + else + { + /* fail */ + return 0; + } +} + +//============================================================ +// osd_lock_release +//============================================================ + +void osd_lock_release(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + LOG(("osd_lock_release")); + mutex->locked--; + if (mutex->locked == 0) + mutex->threadid = -1; + SDL_mutexV(mutex->id); +} + +//============================================================ +// osd_lock_free +//============================================================ + +void osd_lock_free(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + LOG(("osd_lock_free")); + //osd_lock_release(lock); + SDL_DestroyMutex(mutex->id); + free(mutex); +} + +//============================================================ +// osd_event_alloc +//============================================================ + +osd_event *osd_event_alloc(int manualreset, int initialstate) +{ + osd_event *ev; + + ev = (osd_event *)calloc(1, sizeof(osd_event)); + + ev->mutex = SDL_CreateMutex(); + ev->cond = SDL_CreateCond(); + ev->signalled = initialstate; + ev->autoreset = !manualreset; + + return ev; +} + +//============================================================ +// osd_event_free +//============================================================ + +void osd_event_free(osd_event *event) +{ + SDL_DestroyMutex(event->mutex); + SDL_DestroyCond(event->cond); + free(event); +} + +//============================================================ +// osd_event_set +//============================================================ + +void osd_event_set(osd_event *event) +{ + LOG(("osd_event_set")); + SDL_mutexP(event->mutex); + if (event->signalled == FALSE) + { + event->signalled = TRUE; + if (event->autoreset) + SDL_CondSignal(event->cond); + else + SDL_CondBroadcast(event->cond); + } + SDL_mutexV(event->mutex); +} + +//============================================================ +// osd_event_reset +//============================================================ + +void osd_event_reset(osd_event *event) +{ + LOG(("osd_event_reset")); + SDL_mutexP(event->mutex); + event->signalled = FALSE; + SDL_mutexV(event->mutex); +} + +//============================================================ +// osd_event_wait +//============================================================ + +int osd_event_wait(osd_event *event, osd_ticks_t timeout) +{ + LOG(("osd_event_wait")); + SDL_mutexP(event->mutex); + if (!timeout) + { + if (!event->signalled) + { + SDL_mutexV(event->mutex); + return FALSE; + } + } + else + { + if (!event->signalled) + { + UINT64 msec = (timeout * 1000) / osd_ticks_per_second(); + + do { + int ret = SDL_CondWaitTimeout(event->cond, event->mutex, msec); + if ( ret == SDL_MUTEX_TIMEDOUT ) + { + if (!event->signalled) + { + SDL_mutexV(event->mutex); + return FALSE; + } + else + break; + } + if (ret == 0) + break; + printf("Error %d while waiting for pthread_cond_timedwait: %s\n", ret, strerror(ret)); + } while (TRUE); + } + } + + if (event->autoreset) + event->signalled = 0; + + SDL_mutexV(event->mutex); + + return TRUE; +} + +//============================================================ +// osd_thread_create +//============================================================ + +static int worker_thread_entry(void *param) +{ + osd_thread *thread = (osd_thread *) param; + void *res; + + res = thread->callback(thread->param); +#ifdef PTR64 + return (int) (INT64) res; +#else + return (int) res; +#endif +} + +osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) +{ + osd_thread *thread; + + thread = (osd_thread *)calloc(1, sizeof(osd_thread)); + thread->callback = callback; + thread->param = cbparam; + thread->thread = SDL_CreateThread(worker_thread_entry, thread); + if ( thread->thread == NULL ) + { + free(thread); + return NULL; + } + return thread; +} + +//============================================================ +// osd_thread_adjust_priority +//============================================================ + +int osd_thread_adjust_priority(osd_thread *thread, int adjust) +{ + return TRUE; +} + +//============================================================ +// osd_thread_cpu_affinity +//============================================================ + +int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask) +{ + return TRUE; +} + +//============================================================ +// osd_thread_wait_free +//============================================================ + +void osd_thread_wait_free(osd_thread *thread) +{ + int status; + SDL_WaitThread(thread->thread, &status); + free(thread); +} |