mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
Used std::thread and std::condition_variable (nw)
This commit is contained in:
parent
6d0c46eacc
commit
d9510ed04d
@ -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",
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -67,7 +67,6 @@ end
|
||||
|
||||
defines {
|
||||
"OSD_SDL",
|
||||
"SYNC_IMPLEMENTATION=" .. SYNC_IMPLEMENTATION,
|
||||
}
|
||||
|
||||
if BASE_TARGETOS=="unix" then
|
||||
|
@ -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
|
||||
|
131
src/osd/modules/sync/osdsync.cpp
Normal file
131
src/osd/modules/sync/osdsync.cpp
Normal file
@ -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 <mutex>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
//============================================================
|
||||
// TYPE DEFINITIONS
|
||||
//============================================================
|
||||
|
||||
struct osd_event {
|
||||
std::mutex *mutex;
|
||||
std::condition_variable *cond;
|
||||
std::atomic<INT32> autoreset;
|
||||
std::atomic<INT32> 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<std::mutex> 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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
@ -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 <mach/mach.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#if defined(SDLMAME_NETBSD) || defined(SDLMAME_OPENBSD)
|
||||
/* for SIGKILL */
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
// standard C headers
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// MAME headers
|
||||
#include "osdcore.h"
|
||||
#include "osdsync.h"
|
||||
|
||||
#include "eminline.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
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);
|
||||
}
|
@ -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 <cstdint>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
|
||||
// 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);
|
||||
}
|
@ -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 <mach/mach.h>
|
||||
#endif
|
||||
|
||||
// standard C headers
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// MAME headers
|
||||
#include "osdcomm.h"
|
||||
#include "osdcore.h"
|
||||
|
||||
#include "osdsync.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
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<<bitnum))
|
||||
CPU_SET(bitnum, &cmask);
|
||||
|
||||
if (thread == NULL)
|
||||
lthread = pthread_self();
|
||||
else
|
||||
lthread = thread->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);
|
||||
}
|
@ -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 <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <process.h>
|
||||
|
||||
// MAME headers
|
||||
#include "osdcore.h"
|
||||
#include "eminline.h"
|
||||
#include "osdsync.h"
|
||||
|
||||
// C++ headers
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
//============================================================
|
||||
// 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;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#if defined(OSD_WINDOWS)
|
||||
#if defined(OSD_WINDOWS) || (SDLMAME_WIN32)
|
||||
// standard windows headers
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
@ -20,6 +20,7 @@
|
||||
#endif
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
// 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 <pthread.h>
|
||||
#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<INT32> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> lock(*queue->lock);
|
||||
bool has_list_items = (queue->list.load() != nullptr);
|
||||
queue->lock->unlock();
|
||||
return has_list_items;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "modules/sync/osdsync.h"
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
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<INT32> m_do_exit;
|
||||
|
||||
osd_ticks_t m_timeout;
|
||||
|
Loading…
Reference in New Issue
Block a user