From 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Sun, 8 Nov 2015 12:56:12 +0100 Subject: Rename *.c -> *.cpp in our source (nw) --- src/osd/modules/sync/sync_tc.cpp | 390 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 src/osd/modules/sync/sync_tc.cpp (limited to 'src/osd/modules/sync/sync_tc.cpp') diff --git a/src/osd/modules/sync/sync_tc.cpp b/src/osd/modules/sync/sync_tc.cpp new file mode 100644 index 00000000000..06dc699edce --- /dev/null +++ b/src/osd/modules/sync/sync_tc.cpp @@ -0,0 +1,390 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +//============================================================ +// +// sdlsync.c - SDL core synchronization functions +// +// SDLMAME by Olivier Galibert and R. Belmont +// +//============================================================ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // for PTHREAD_MUTEX_RECURSIVE; needs to be here before other glibc headers are included +#endif + +#include "sdlinc.h" + +#ifdef SDLMAME_MACOSX +#include +#endif + +// standard C headers +#include +#include +#include + +// MAME headers +#include "osdcomm.h" +#include "osdcore.h" + +#include "osdsync.h" + +#include +#include +#include +#include + +struct hidden_mutex_t { + pthread_mutex_t id; +}; + +struct osd_event { + pthread_mutex_t mutex; + pthread_cond_t cond; + volatile INT32 autoreset; + volatile INT32 signalled; +#ifdef PTR64 + INT8 padding[40]; // Fill a 64-byte cache line +#else + INT8 padding[48]; // A bit more padding +#endif +}; + +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +struct osd_thread { + pthread_t thread; +}; + +struct osd_scalable_lock +{ + osd_lock *lock; +}; + +//============================================================ +// Scalable Locks +//============================================================ + +osd_scalable_lock *osd_scalable_lock_alloc(void) +{ + osd_scalable_lock *lock; + + lock = (osd_scalable_lock *)calloc(1, sizeof(*lock)); + if (lock == NULL) + return NULL; + + lock->lock = osd_lock_alloc(); + return lock; +} + + +INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock) +{ + osd_lock_acquire(lock->lock); + return 0; +} + + +void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot) +{ + osd_lock_release(lock->lock); +} + +void osd_scalable_lock_free(osd_scalable_lock *lock) +{ + osd_lock_free(lock->lock); + free(lock); +} + + +//============================================================ +// osd_lock_alloc +//============================================================ + +osd_lock *osd_lock_alloc(void) +{ + hidden_mutex_t *mutex; + pthread_mutexattr_t mtxattr; + + mutex = (hidden_mutex_t *)calloc(1, sizeof(hidden_mutex_t)); + if (mutex == NULL) + return NULL; + + pthread_mutexattr_init(&mtxattr); + pthread_mutexattr_settype(&mtxattr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mutex->id, &mtxattr); + + return (osd_lock *)mutex; +} + +//============================================================ +// osd_lock_acquire +//============================================================ + +void osd_lock_acquire(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + int r; + + r = pthread_mutex_lock(&mutex->id); + if (r==0) + return; + //osd_printf_error("Error on lock: %d: %s\n", r, strerror(r)); +} + +//============================================================ +// osd_lock_try +//============================================================ + +int osd_lock_try(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + int r; + + r = pthread_mutex_trylock(&mutex->id); + if (r==0) + return 1; + //if (r!=EBUSY) + // osd_printf_error("Error on trylock: %d: %s\n", r, strerror(r)); + return 0; +} + +//============================================================ +// osd_lock_release +//============================================================ + +void osd_lock_release(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + pthread_mutex_unlock(&mutex->id); +} + +//============================================================ +// osd_lock_free +//============================================================ + +void osd_lock_free(osd_lock *lock) +{ + hidden_mutex_t *mutex = (hidden_mutex_t *) lock; + + //pthread_mutex_unlock(&mutex->id); + pthread_mutex_destroy(&mutex->id); + free(mutex); +} + +//============================================================ +// osd_event_alloc +//============================================================ + +osd_event *osd_event_alloc(int manualreset, int initialstate) +{ + osd_event *ev; + pthread_mutexattr_t mtxattr; + + ev = (osd_event *)calloc(1, sizeof(osd_event)); + if (ev == NULL) + return NULL; + + pthread_mutexattr_init(&mtxattr); + pthread_mutex_init(&ev->mutex, &mtxattr); + pthread_cond_init(&ev->cond, NULL); + ev->signalled = initialstate; + ev->autoreset = !manualreset; + + return ev; +} + +//============================================================ +// osd_event_free +//============================================================ + +void osd_event_free(osd_event *event) +{ + pthread_mutex_destroy(&event->mutex); + pthread_cond_destroy(&event->cond); + free(event); +} + +//============================================================ +// osd_event_set +//============================================================ + +void osd_event_set(osd_event *event) +{ + pthread_mutex_lock(&event->mutex); + if (event->signalled == FALSE) + { + event->signalled = TRUE; + if (event->autoreset) + pthread_cond_signal(&event->cond); + else + pthread_cond_broadcast(&event->cond); + } + pthread_mutex_unlock(&event->mutex); +} + +//============================================================ +// osd_event_reset +//============================================================ + +void osd_event_reset(osd_event *event) +{ + pthread_mutex_lock(&event->mutex); + event->signalled = FALSE; + pthread_mutex_unlock(&event->mutex); +} + +//============================================================ +// osd_event_wait +//============================================================ + +int osd_event_wait(osd_event *event, osd_ticks_t timeout) +{ + if (timeout == OSD_EVENT_WAIT_INFINITE) + timeout = osd_ticks_per_second() * (osd_ticks_t)10000; + + pthread_mutex_lock(&event->mutex); + if (!timeout) + { + if (!event->signalled) + { + pthread_mutex_unlock(&event->mutex); + return FALSE; + } + } + else + { + if (!event->signalled) + { + struct timespec ts; + struct timeval tp; + UINT64 msec = timeout * 1000 / osd_ticks_per_second(); + UINT64 nsec; + + gettimeofday(&tp, NULL); + + ts.tv_sec = tp.tv_sec; + nsec = (UINT64) tp.tv_usec * (UINT64) 1000 + (msec * (UINT64) 1000000); + ts.tv_nsec = nsec % (UINT64) 1000000000; + ts.tv_sec += nsec / (UINT64) 1000000000; + + do { + int ret = pthread_cond_timedwait(&event->cond, &event->mutex, &ts); + if ( ret == ETIMEDOUT ) + { + if (!event->signalled) + { + pthread_mutex_unlock(&event->mutex); + return FALSE; + } + else + break; + } + if (ret == 0) + break; + if ( ret != EINTR) + { + printf("Error %d while waiting for pthread_cond_timedwait: %s\n", ret, strerror(ret)); + } + + } while (TRUE); + } + } + + if (event->autoreset) + event->signalled = 0; + + pthread_mutex_unlock(&event->mutex); + + return TRUE; +} + +//============================================================ +// osd_thread_create +//============================================================ + +osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) +{ + osd_thread *thread; + pthread_attr_t attr; + + thread = (osd_thread *)calloc(1, sizeof(osd_thread)); + if (thread == NULL) + return NULL; + pthread_attr_init(&attr); + pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); + if ( pthread_create(&thread->thread, &attr, callback, cbparam) != 0 ) + { + free(thread); + return NULL; + } + return thread; +} + +//============================================================ +// osd_thread_adjust_priority +//============================================================ + +int osd_thread_adjust_priority(osd_thread *thread, int adjust) +{ + struct sched_param sched; + int policy; + + if ( pthread_getschedparam( thread->thread, &policy, &sched ) == 0 ) + { + sched.sched_priority += adjust; + if ( pthread_setschedparam(thread->thread, policy, &sched ) == 0) + return TRUE; + else + return FALSE; + } + else + return FALSE; +} + +//============================================================ +// osd_thread_cpu_affinity +//============================================================ + +int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask) +{ +#if !defined(NO_AFFINITY_NP) + cpu_set_t cmask; + pthread_t lthread; + int bitnum; + + CPU_ZERO(&cmask); + for (bitnum=0; bitnum<32; bitnum++) + if (mask & (1<thread; + + if (pthread_setaffinity_np(lthread, sizeof(cmask), &cmask) <0) + { + /* Not available during link in all targets */ + fprintf(stderr, "error %d setting cpu affinity to mask %08x", errno, mask); + return FALSE; + } + else + return TRUE; +#else + return TRUE; +#endif +} + +//============================================================ +// osd_thread_wait_free +//============================================================ + +void osd_thread_wait_free(osd_thread *thread) +{ + pthread_join(thread->thread, NULL); + free(thread); +} -- cgit v1.2.3