diff --git a/scripts/src/osd/osdmini.lua b/scripts/src/osd/osdmini.lua index 76bb2ac97de..91b9d11a3d5 100644 --- a/scripts/src/osd/osdmini.lua +++ b/scripts/src/osd/osdmini.lua @@ -96,25 +96,7 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/lib", MAME_DIR .. "src/lib/util", } - - if _OPTIONS["targetos"]=="linux" then - BASE_TARGETOS = "unix" - SDLOS_TARGETOS = "unix" - SYNC_IMPLEMENTATION = "tc" - end - - if _OPTIONS["targetos"]=="windows" then - BASE_TARGETOS = "win32" - SDLOS_TARGETOS = "win32" - SYNC_IMPLEMENTATION = "windows" - end - - if _OPTIONS["targetos"]=="macosx" then - BASE_TARGETOS = "unix" - SDLOS_TARGETOS = "macosx" - SYNC_IMPLEMENTATION = "ntc" - end - + files { MAME_DIR .. "src/osd/osdnet.cpp", MAME_DIR .. "src/osd/osdnet.h", @@ -126,5 +108,5 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/osdmini/minifile.cpp", MAME_DIR .. "src/osd/osdmini/minimisc.cpp", MAME_DIR .. "src/osd/osdmini/minitime.cpp", - MAME_DIR .. "src/osd/modules/sync/work_mini.cpp", + MAME_DIR .. "src/osd/modules/sync/work_osd.cpp", } diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua index 5a64013ffdf..fa3e85c2454 100644 --- a/scripts/src/osd/sdl.lua +++ b/scripts/src/osd/sdl.lua @@ -222,27 +222,20 @@ end BASE_TARGETOS = "unix" SDLOS_TARGETOS = "unix" -SYNC_IMPLEMENTATION = "tc" SDL_NETWORK = "" if _OPTIONS["targetos"]=="linux" then SDL_NETWORK = "taptun" elseif _OPTIONS["targetos"]=="openbsd" then - SYNC_IMPLEMENTATION = "ntc" elseif _OPTIONS["targetos"]=="netbsd" then - SYNC_IMPLEMENTATION = "ntc" SDL_NETWORK = "pcap" elseif _OPTIONS["targetos"]=="haiku" then - SYNC_IMPLEMENTATION = "ntc" elseif _OPTIONS["targetos"]=="asmjs" then - SYNC_IMPLEMENTATION = "mini" elseif _OPTIONS["targetos"]=="windows" then BASE_TARGETOS = "win32" SDLOS_TARGETOS = "win32" - SYNC_IMPLEMENTATION = "windows" SDL_NETWORK = "pcap" elseif _OPTIONS["targetos"]=="macosx" then SDLOS_TARGETOS = "macosx" - SYNC_IMPLEMENTATION = "ntc" SDL_NETWORK = "pcap" end @@ -476,20 +469,11 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/modules/osdmodule.h", MAME_DIR .. "src/osd/modules/lib/osdlib_" .. SDLOS_TARGETOS .. ".cpp", MAME_DIR .. "src/osd/modules/lib/osdlib.h", - MAME_DIR .. "src/osd/modules/sync/sync_" .. SYNC_IMPLEMENTATION .. ".cpp", + MAME_DIR .. "src/osd/modules/sync/osdsync.cpp", MAME_DIR .. "src/osd/modules/sync/osdsync.h", + MAME_DIR .. "src/osd/modules/sync/work_osd.cpp", } - if _OPTIONS["NOASM"]=="1" then - files { - MAME_DIR .. "src/osd/modules/sync/work_mini.cpp", - } - else - files { - MAME_DIR .. "src/osd/modules/sync/work_osd.cpp", - } - end - if _OPTIONS["targetos"]=="macosx" then files { MAME_DIR .. "src/osd/sdl/osxutils.h", diff --git a/scripts/src/osd/sdl_cfg.lua b/scripts/src/osd/sdl_cfg.lua index 641a00b924e..3d5a84783f4 100644 --- a/scripts/src/osd/sdl_cfg.lua +++ b/scripts/src/osd/sdl_cfg.lua @@ -67,7 +67,6 @@ end defines { "OSD_SDL", - "SYNC_IMPLEMENTATION=" .. SYNC_IMPLEMENTATION, } if BASE_TARGETOS=="unix" then diff --git a/scripts/src/osd/windows.lua b/scripts/src/osd/windows.lua index 950e15d1e46..877d1503915 100644 --- a/scripts/src/osd/windows.lua +++ b/scripts/src/osd/windows.lua @@ -224,7 +224,6 @@ project ("ocore_" .. _OPTIONS["osd"]) BASE_TARGETOS = "win32" SDLOS_TARGETOS = "win32" - SYNC_IMPLEMENTATION = "windows" includedirs { MAME_DIR .. "src/osd/windows", @@ -245,7 +244,7 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/windows/main.cpp", MAME_DIR .. "src/osd/windows/windir.cpp", MAME_DIR .. "src/osd/windows/winfile.cpp", - MAME_DIR .. "src/osd/modules/sync/sync_windows.cpp", + MAME_DIR .. "src/osd/modules/sync/osdsync.cpp", MAME_DIR .. "src/osd/modules/sync/osdsync.h", MAME_DIR .. "src/osd/windows/winutf8.cpp", MAME_DIR .. "src/osd/windows/winutf8.h", @@ -258,18 +257,9 @@ project ("ocore_" .. _OPTIONS["osd"]) MAME_DIR .. "src/osd/modules/osdmodule.cpp", MAME_DIR .. "src/osd/modules/osdmodule.h", MAME_DIR .. "src/osd/modules/lib/osdlib_win32.cpp", + MAME_DIR .. "src/osd/modules/sync/work_osd.cpp", } - if _OPTIONS["NOASM"] == "1" then - files { - MAME_DIR .. "src/osd/modules/sync/work_mini.cpp", - } - else - files { - MAME_DIR .. "src/osd/modules/sync/work_osd.cpp", - } - end - -------------------------------------------------- -- ledutil diff --git a/src/osd/modules/sync/osdsync.cpp b/src/osd/modules/sync/osdsync.cpp new file mode 100644 index 00000000000..08926e14e37 --- /dev/null +++ b/src/osd/modules/sync/osdsync.cpp @@ -0,0 +1,131 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles,Miodrag Milanovic +//============================================================ +// +// osdsync.cpp -OSD core synchronization functions +// +//============================================================ +// MAME headers +#include "osdcore.h" +#include "osdsync.h" + +// C++ headers +#include +#include +#include +//============================================================ +// TYPE DEFINITIONS +//============================================================ + +struct osd_event { + std::mutex *mutex; + std::condition_variable *cond; + std::atomic autoreset; + std::atomic signalled; +}; + +//============================================================ +// osd_event_alloc +//============================================================ + +osd_event *osd_event_alloc(int manualreset, int initialstate) +{ + osd_event *ev; + + ev = (osd_event *)calloc(1, sizeof(osd_event)); + if (ev == nullptr) + return nullptr; + + ev->mutex = new std::mutex(); + ev->cond = new std::condition_variable(); + ev->signalled = initialstate; + ev->autoreset = !manualreset; + + return ev; +} + +//============================================================ +// osd_event_free +//============================================================ + +void osd_event_free(osd_event *event) +{ + delete event->mutex; + delete event->cond; + free(event); +} + +//============================================================ +// osd_event_set +//============================================================ + +void osd_event_set(osd_event *event) +{ + event->mutex->lock(); + if (event->signalled == FALSE) + { + event->signalled = TRUE; + if (event->autoreset) + event->cond->notify_one(); + else + event->cond->notify_all(); + } + event->mutex->unlock(); +} + +//============================================================ +// osd_event_reset +//============================================================ + +void osd_event_reset(osd_event *event) +{ + event->mutex->lock(); + event->signalled = FALSE; + event->mutex->unlock(); +} + +//============================================================ +// 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; + + std::unique_lock lock(*event->mutex); + if (!timeout) + { + if (!event->signalled) + { + return FALSE; + } + } + else + { + if (!event->signalled) + { + UINT64 msec = timeout * 1000 / osd_ticks_per_second(); + + do { + if (event->cond->wait_for(lock, std::chrono::milliseconds(msec)) == std::cv_status::timeout) + { + if (!event->signalled) + { + return FALSE; + } + else + break; + } else + break; + + } while (TRUE); + } + } + + if (event->autoreset) + event->signalled = 0; + + return TRUE; +} + diff --git a/src/osd/modules/sync/osdsync.h b/src/osd/modules/sync/osdsync.h index e6e5e2f99c9..e88d4a223f2 100644 --- a/src/osd/modules/sync/osdsync.h +++ b/src/osd/modules/sync/osdsync.h @@ -103,75 +103,4 @@ void osd_event_set(osd_event *event); -----------------------------------------------------------------------------*/ void osd_event_free(osd_event *event); -/*************************************************************************** - SYNCHRONIZATION INTERFACES - Threads -***************************************************************************/ - -/* osd_thread is an opaque type which represents a thread */ -struct osd_thread; - - -/* osd_thread_callback is a callback function that will be called from the thread */ -typedef void *(*osd_thread_callback)(void *param); - - -/*----------------------------------------------------------------------------- - osd_thread_create: create a new thread - - Parameters: - - callback - The callback function to be called once the thread is up - cbparam - The parameter to pass to the callback function. - - Return value: - - A pointer to the created thread. ------------------------------------------------------------------------------*/ -osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam); - -/*----------------------------------------------------------------------------- - osd_thread_adjust_priority: adjust priority of a thread - - Parameters: - - thread - A pointer to a previously created thread. - adjust - signed integer to add to the thread priority - - Return value: - - TRUE on success, FALSE on failure ------------------------------------------------------------------------------*/ -int osd_thread_adjust_priority(osd_thread *thread, int adjust); - - -/*----------------------------------------------------------------------------- - osd_thread_cpu_affinity: change cpu affinity of a thread - - Parameters: - - thread - A pointer to a previously created thread - or NULL for main thread - mask - bitmask to which cpus to bind - i.e. 0x01 1st cpu, 0x02, 2nd cpu, 0x04 3rd cpu - - Return value: - - TRUE on success, FALSE on failure ------------------------------------------------------------------------------*/ -int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask); - - -/*----------------------------------------------------------------------------- - osd_thread_wait_free: wait for thread to finish and free resources - - Parameters: - - thread - A pointer to a previously created thread. - - Return value: - - None. ------------------------------------------------------------------------------*/ -void osd_thread_wait_free(osd_thread *thread); - #endif /* __OSDSYNC__ */ diff --git a/src/osd/modules/sync/sync_mini.cpp b/src/osd/modules/sync/sync_mini.cpp deleted file mode 100644 index 5829eb6d63c..00000000000 --- a/src/osd/modules/sync/sync_mini.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// sdlsync_mini.c - Minimal core synchronization functions -// -//============================================================ - -#include "osdcore.h" -#include "osdsync.h" - -struct _osd_event -{ - void * ptr; -}; - -struct _osd_thread { - void * ptr; -}; - - -//============================================================ -// osd_event_alloc -//============================================================ - -osd_event *osd_event_alloc(int manualreset, int initialstate) -{ - return nullptr; -} - - -//============================================================ -// osd_event_free -//============================================================ - -void osd_event_free(osd_event *event) -{ -} - - -//============================================================ -// osd_event_set -//============================================================ - -void osd_event_set(osd_event *event) -{ -} - - -//============================================================ -// osd_event_reset -//============================================================ - -void osd_event_reset(osd_event *event) -{ -} - - -//============================================================ -// osd_event_wait -//============================================================ - -int osd_event_wait(osd_event *event, osd_ticks_t timeout) -{ - return TRUE; -} - - -//============================================================ -// osd_thread_create -//============================================================ - -osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) -{ - return nullptr; -} - - -//============================================================ -// osd_thread_adjust_priority -//============================================================ - -int osd_thread_adjust_priority(osd_thread *thread, int adjust) -{ - return FALSE; -} - - -//============================================================ -// 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) -{ -} diff --git a/src/osd/modules/sync/sync_ntc.cpp b/src/osd/modules/sync/sync_ntc.cpp deleted file mode 100644 index 4ff70a57c09..00000000000 --- a/src/osd/modules/sync/sync_ntc.cpp +++ /dev/null @@ -1,248 +0,0 @@ -// 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 -#include -#endif - -#if defined(SDLMAME_NETBSD) || defined(SDLMAME_OPENBSD) -/* for SIGKILL */ -#include -#endif - -// standard C headers -#include -#include - -// MAME headers -#include "osdcore.h" -#include "osdsync.h" - -#include "eminline.h" - -#include -#include -#include - -struct osd_event { - pthread_mutex_t mutex; - pthread_cond_t cond; - volatile INT32 autoreset; - volatile INT32 signalled; - // Fill a 64-byte cache line (a bit more padding with smaller pointers) - INT8 padding[(sizeof(void *) >= 8) ? 40 : 48]; -}; - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -struct osd_thread { - pthread_t thread; -}; - -//============================================================ -// 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); -#ifndef SDLMAME_HAIKU - pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); -#endif - 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) -{ - return TRUE; -} - -//============================================================ -// osd_thread_wait_free -//============================================================ - -void osd_thread_wait_free(osd_thread *thread) -{ - pthread_join(thread->thread, NULL); - free(thread); -} diff --git a/src/osd/modules/sync/sync_sdl.cpp b/src/osd/modules/sync/sync_sdl.cpp deleted file mode 100644 index c667f17cedb..00000000000 --- a/src/osd/modules/sync/sync_sdl.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert, R. Belmont -//============================================================ -// -// sdlsync.c - SDL core synchronization functions -// -// SDLMAME by Olivier Galibert and R. Belmont -// -//============================================================ - -#include "sdlinc.h" - -// standard C headers -#include -#include -#include -#include - -// MAME headers -#include "osdcore.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; -}; - - -//============================================================ -// osd_event_alloc -//============================================================ - -osd_event *osd_event_alloc(int manualreset, int initialstate) -{ - osd_event *ev; - - ev = (osd_event *)calloc(1, sizeof(osd_event)); - if (ev == NULL) - return NULL; - - 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")); - if (timeout == OSD_EVENT_WAIT_INFINITE) - timeout = osd_ticks_per_second() * (osd_ticks_t)10000; - 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); - return int(intptr_t(res)); -} - -osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) -{ - osd_thread *thread; - - thread = (osd_thread *)calloc(1, sizeof(osd_thread)); - if (thread == NULL) - return NULL; - thread->callback = callback; - thread->param = cbparam; - thread->thread = SDL_CreateThread(worker_thread_entry, "Thread", 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); -} diff --git a/src/osd/modules/sync/sync_tc.cpp b/src/osd/modules/sync/sync_tc.cpp deleted file mode 100644 index 1ebb2879ccf..00000000000 --- a/src/osd/modules/sync/sync_tc.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// 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; - // Fill a 64-byte cache line (a bit more padding with smaller pointers) - INT8 padding[(sizeof(void *) >= 8) ? 40 : 48]; -}; - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -struct osd_thread { - pthread_t thread; -}; - -//============================================================ -// 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); -} diff --git a/src/osd/modules/sync/sync_windows.cpp b/src/osd/modules/sync/sync_windows.cpp deleted file mode 100644 index c8819f01bc2..00000000000 --- a/src/osd/modules/sync/sync_windows.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Aaron Giles -//============================================================ -// -// winsync.c - Win32 OSD core synchronization functions -// -//============================================================ - -// standard windows headers -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -// MAME headers -#include "osdcore.h" -#include "eminline.h" -#include "osdsync.h" - -// C++ headers -#include - - -//============================================================ -// DEBUGGING -//============================================================ - -#define DEBUG_SLOW_LOCKS 0 - - -//============================================================ -// TYPE DEFINITIONS -//============================================================ - -typedef BOOL (WINAPI *try_enter_critical_section_ptr)(LPCRITICAL_SECTION lpCriticalSection); - -struct osd_event -{ - void * ptr; -}; - -struct osd_thread { - HANDLE handle; - osd_thread_callback callback; - void *param; -}; - - -//============================================================ -// osd_event_alloc -//============================================================ - -osd_event *osd_event_alloc(int manualreset, int initialstate) -{ - return (osd_event *) CreateEvent(nullptr, manualreset, initialstate, nullptr); -} - -//============================================================ -// osd_event_free -//============================================================ - -void osd_event_free(osd_event *event) -{ - CloseHandle((HANDLE) event); -} - -//============================================================ -// osd_event_set -//============================================================ - -void osd_event_set(osd_event *event) -{ - SetEvent((HANDLE) event); -} - -//============================================================ -// osd_event_reset -//============================================================ - -void osd_event_reset(osd_event *event) -{ - ResetEvent((HANDLE) event); -} - -//============================================================ -// osd_event_wait -//============================================================ - -int osd_event_wait(osd_event *event, osd_ticks_t timeout) -{ - DWORD timeout_param; - if (timeout == OSD_EVENT_WAIT_INFINITE) - timeout_param = INFINITE; - else - timeout_param = timeout * 1000 / osd_ticks_per_second(); - - int ret = WaitForSingleObject((HANDLE) event, timeout_param); - return (ret == WAIT_OBJECT_0); -} - -//============================================================ -// osd_thread_create -//============================================================ - -static unsigned __stdcall worker_thread_entry(void *param) -{ - osd_thread *thread = (osd_thread *) param; - void *res; - res = thread->callback(thread->param); - return unsigned(uintptr_t(res)); -} - -osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam) -{ - osd_thread *thread; - uintptr_t handle; - - thread = (osd_thread *)calloc(1, sizeof(osd_thread)); - if (thread == nullptr) - return nullptr; - thread->callback = callback; - thread->param = cbparam; - handle = _beginthreadex(nullptr, 0, worker_thread_entry, thread, 0, nullptr); - if (handle == 0) - { - free(thread); - return nullptr; - } - thread->handle = (HANDLE) handle; - return thread; -} - -//============================================================ -// osd_thread_wait_free -//============================================================ - -void osd_thread_wait_free(osd_thread *thread) -{ - WaitForSingleObject(thread->handle, INFINITE); - CloseHandle(thread->handle); - free(thread); -} - -//============================================================ -// osd_thread_adjust_priority -//============================================================ - -int osd_thread_adjust_priority(osd_thread *thread, int adjust) -{ - if (adjust) - SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL); - else - SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread())); - return TRUE; -} - -//============================================================ -// osd_thread_cpu_affinity -//============================================================ - -int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask) -{ - return TRUE; -} diff --git a/src/osd/modules/sync/work_osd.cpp b/src/osd/modules/sync/work_osd.cpp index 3f4abbf0ee6..b06babbc37a 100644 --- a/src/osd/modules/sync/work_osd.cpp +++ b/src/osd/modules/sync/work_osd.cpp @@ -6,7 +6,7 @@ // //============================================================ -#if defined(OSD_WINDOWS) +#if defined(OSD_WINDOWS) || (SDLMAME_WIN32) // standard windows headers #define WIN32_LEAN_AND_MEAN #include @@ -20,6 +20,7 @@ #endif #include #include +#include // MAME headers #include "osdcore.h" @@ -32,7 +33,9 @@ #if defined(SDLMAME_MACOSX) #include "osxutils.h" #endif - +#if defined(SDLMAME_LINUX) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) || defined(SDLMAME_MACOSX) +#include +#endif #if defined(OSD_SDL) typedef void *PVOID; #endif @@ -95,7 +98,7 @@ static void spin_while_not(const volatile _AtomType * volatile atom, const _Main struct work_thread_info { osd_work_queue * queue; // pointer back to the queue - osd_thread * handle; // handle to the thread + std::thread * handle; // handle to the thread osd_event * wakeevent; // wake event for the thread std::atomic active; // are we actively processing work? @@ -160,6 +163,33 @@ 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); +//============================================================ +// osd_thread_adjust_priority +//============================================================ + +int thread_adjust_priority(std::thread *thread, int adjust) +{ +#if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) + if (adjust) + SetThreadPriority((HANDLE)thread->native_handle(), THREAD_PRIORITY_ABOVE_NORMAL); + else + SetThreadPriority((HANDLE)thread->native_handle(), GetThreadPriority(GetCurrentThread())); +#endif +#if defined(SDLMAME_LINUX) || defined(SDLMAME_BSD) || defined(SDLMAME_HAIKU) || defined(SDLMAME_EMSCRIPTEN) || defined(SDLMAME_DARWIN) + struct sched_param sched; + int policy; + + if (pthread_getschedparam(thread->native_handle(), &policy, &sched) == 0) + { + sched.sched_priority += adjust; + if (pthread_setschedparam(thread->native_handle(), policy, &sched) == 0) + return TRUE; + else + return FALSE; + } +#endif + return TRUE; +} //============================================================ // osd_work_queue_alloc @@ -237,16 +267,16 @@ osd_work_queue *osd_work_queue_alloc(int flags) goto error; // create the thread - thread->handle = osd_thread_create(worker_thread_entry, thread); - if (thread->handle == NULL) + thread->handle = new std::thread(worker_thread_entry, thread); + if (thread->handle == nullptr) goto error; // set its priority: I/O threads get high priority because they are assumed to be // blocked most of the time; other threads just match the creator's priority if (flags & WORK_QUEUE_FLAG_IO) - osd_thread_adjust_priority(thread->handle, 1); + thread_adjust_priority(thread->handle, 1); else - osd_thread_adjust_priority(thread->handle, 0); + thread_adjust_priority(thread->handle, 0); } // start a timer going for "waittime" on the main thread @@ -357,7 +387,8 @@ void osd_work_queue_free(osd_work_queue *queue) // block on the thread going away, then close the handle if (thread->handle != NULL) { - osd_thread_wait_free(thread->handle); + thread->handle->join(); + delete thread->handle; } // clean up the wake event @@ -446,12 +477,11 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call // first allocate a new work item; try the free list first { - queue->lock->lock(); + std::lock_guard lock(*queue->lock); do { item = (osd_work_item *)queue->free; - } while (item != NULL && !queue->free.compare_exchange_weak(item, item->next, std::memory_order_release, std::memory_order_relaxed)); - queue->lock->unlock(); + } while (item != NULL && !queue->free.compare_exchange_weak(item, item->next, std::memory_order_release, std::memory_order_relaxed)); } // if nothing, allocate something new @@ -486,10 +516,9 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call // enqueue the whole thing within the critical section { - queue->lock->lock(); + std::lock_guard lock(*queue->lock); *queue->tailptr = itemlist; - queue->tailptr = item_tailptr; - queue->lock->unlock(); + queue->tailptr = item_tailptr; } // increment the number of items in the queue @@ -544,9 +573,8 @@ int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout) // if we don't have an event, create one if (item->event == NULL) { - item->queue->lock->lock(); - item->event = osd_event_alloc(TRUE, FALSE); // manual reset, not signalled - item->queue->lock->unlock(); + std::lock_guard lock(*item->queue->lock); + item->event = osd_event_alloc(TRUE, FALSE); // manual reset, not signalled } else osd_event_reset(item->event); @@ -589,13 +617,12 @@ void osd_work_item_release(osd_work_item *item) osd_work_item_wait(item, 100 * osd_ticks_per_second()); // add us to the free list on our queue - item->queue->lock->lock(); + std::lock_guard lock(*item->queue->lock); do { next = (osd_work_item *)item->queue->free; item->next = next; } while (!item->queue->free.compare_exchange_weak(next, item, std::memory_order_release, std::memory_order_relaxed)); - item->queue->lock->unlock(); } @@ -716,7 +743,8 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa // use a critical section to synchronize the removal of items { - queue->lock->lock(); + std::lock_guard lock(*queue->lock); + if (queue->list.load() == nullptr) { end_loop = true; @@ -732,7 +760,6 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa queue->tailptr = (osd_work_item **)&queue->list; } } - queue->lock->unlock(); } if (end_loop) @@ -758,13 +785,13 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa // set the result and signal the event else { - queue->lock->lock(); + std::lock_guard lock(*queue->lock); + if (item->event != NULL) { osd_event_set(item->event); add_to_stat(item->queue->setevents, 1); } - queue->lock->unlock(); } // if we removed an item and there's still work to do, bump the stats @@ -785,8 +812,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa bool queue_has_list_items(osd_work_queue *queue) { - queue->lock->lock(); + std::lock_guard lock(*queue->lock); bool has_list_items = (queue->list.load() != nullptr); - queue->lock->unlock(); return has_list_items; } diff --git a/src/osd/sdl/watchdog.cpp b/src/osd/sdl/watchdog.cpp index 6d3aa3c7f69..eaa216dd0f8 100644 --- a/src/osd/sdl/watchdog.cpp +++ b/src/osd/sdl/watchdog.cpp @@ -45,7 +45,7 @@ watchdog::watchdog(void) { m_do_exit = 0; m_event = osd_event_alloc(1, 0); - m_thread = osd_thread_create(watchdog_thread, this); + m_thread = new std::thread(watchdog_thread, this); m_timeout = 60 * osd_ticks_per_second(); } @@ -53,7 +53,8 @@ watchdog::~watchdog(void) { m_do_exit = 1; osd_event_set(m_event); - osd_thread_wait_free(m_thread); + m_thread->join(); + delete m_thread; osd_event_free(m_event); } diff --git a/src/osd/sdl/watchdog.h b/src/osd/sdl/watchdog.h index 18aa11a54f5..cddba0100ef 100644 --- a/src/osd/sdl/watchdog.h +++ b/src/osd/sdl/watchdog.h @@ -12,6 +12,7 @@ #include "modules/sync/osdsync.h" #include +#include class watchdog { @@ -27,7 +28,7 @@ public: void setTimeout(int timeout); private: osd_event * m_event; - osd_thread * m_thread; + std::thread* m_thread; std::atomic m_do_exit; osd_ticks_t m_timeout;