From e355c83f59ace15850d4de6935e9fb6512a6afb5 Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Thu, 30 Jun 2005 10:20:18 +0000 Subject: [PATCH] Add system-specific implementations of idle_{wait,resume} functions. --- BasiliskII/src/BeOS/timer_beos.cpp | 19 +++++++ BasiliskII/src/Unix/configure.ac | 1 + BasiliskII/src/Unix/timer_unix.cpp | 69 ++++++++++++++++++++++++ BasiliskII/src/Windows/timer_windows.cpp | 19 +++++++ BasiliskII/src/include/timer.h | 4 ++ 5 files changed, 112 insertions(+) diff --git a/BasiliskII/src/BeOS/timer_beos.cpp b/BasiliskII/src/BeOS/timer_beos.cpp index df941900..f3998ee6 100644 --- a/BasiliskII/src/BeOS/timer_beos.cpp +++ b/BasiliskII/src/BeOS/timer_beos.cpp @@ -130,3 +130,22 @@ void Delay_usec(uint32 usec) { snooze(usec); } + + +/* + * Suspend emulator thread, virtual CPU in idle mode + */ + +void idle_wait(void) +{ + sleep(16667); +} + + +/* + * Resume execution of emulator thread, events just arrived + */ + +void idle_resume(void) +{ +} diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 16a2d4b7..f2e2e398 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -202,6 +202,7 @@ AC_CHECK_LIB(pthread, pthread_create, , [ if [[ "x$HAVE_PTHREADS" = "xyes" ]]; then AC_DEFINE(HAVE_PTHREADS, 1, [Define if pthreads are available.]) fi +AC_CHECK_FUNCS(pthread_cond_init) AC_CHECK_FUNCS(pthread_cancel pthread_testcancel) AC_CHECK_FUNCS(pthread_mutexattr_setprotocol) AC_CHECK_FUNCS(pthread_mutexattr_settype) diff --git a/BasiliskII/src/Unix/timer_unix.cpp b/BasiliskII/src/Unix/timer_unix.cpp index f2f91bcc..11587433 100644 --- a/BasiliskII/src/Unix/timer_unix.cpp +++ b/BasiliskII/src/Unix/timer_unix.cpp @@ -297,3 +297,72 @@ void Delay_usec(uint32 usec) #endif } while (was_error && (errno == EINTR)); } + + +/* + * Suspend emulator thread, virtual CPU in idle mode + */ + +#ifdef HAVE_PTHREADS +#if defined(HAVE_PTHREAD_COND_INIT) +#define IDLE_USES_COND_WAIT 1 +static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t idle_cond = PTHREAD_COND_INITIALIZER; +#elif defined(HAVE_SEM_INIT) +#define IDLE_USES_SEMAPHORE 1 +#include +#ifdef HAVE_SPINLOCKS +static spinlock_t idle_lock = SPIN_LOCK_UNLOCKED; +#define LOCK_IDLE spin_lock(&idle_lock) +#define UNLOCK_IDLE spin_unlock(&idle_lock) +#else +static pthread_mutex_t idle_lock = PTHREAD_MUTEX_INITIALIZER; +#define LOCK_IDLE pthread_mutex_lock(&idle_lock) +#define UNLOCK_IDLE pthread_mutex_unlock(&idle_lock) +#endif +static sem_t idle_sem; +static int idle_sem_ok = -1; +#endif +#endif + +void idle_wait(void) +{ +#ifdef IDLE_USES_COND_WAIT + pthread_cond_wait(&idle_cond, &idle_lock); +#else +#ifdef IDLE_USES_SEMAPHORE + if (idle_sem_ok < 0) + idle_sem_ok = (sem_init(&idle_sem, 0, 0) == 0); + if (idle_sem_ok > 0) { + LOCK_IDLE; + idle_sem_ok++; + UNLOCK_IDLE; + sem_wait(&idle_sem); + return; + } +#endif + Delay_usec(10000); +#endif +} + + +/* + * Resume execution of emulator thread, events just arrived + */ + +void idle_resume(void) +{ +#ifdef IDLE_USES_COND_WAIT + pthread_cond_signal(&idle_cond); +#else +#ifdef IDLE_USES_SEMAPHORE + if (idle_sem_ok > 1) { + LOCK_IDLE; + idle_sem_ok--; + UNLOCK_IDLE; + sem_post(&idle_sem); + return; + } +#endif +#endif +} diff --git a/BasiliskII/src/Windows/timer_windows.cpp b/BasiliskII/src/Windows/timer_windows.cpp index 39ad61dd..3ed729bf 100755 --- a/BasiliskII/src/Windows/timer_windows.cpp +++ b/BasiliskII/src/Windows/timer_windows.cpp @@ -195,3 +195,22 @@ void Delay_usec(uint32 usec) // millisecond resolution anyway Sleep(usec / 1000); } + + +/* + * Suspend emulator thread, virtual CPU in idle mode + */ + +void idle_wait(void) +{ + Delay_usec(10000); +} + + +/* + * Resume execution of emulator thread, events just arrived + */ + +void idle_resume(void) +{ +} diff --git a/BasiliskII/src/include/timer.h b/BasiliskII/src/include/timer.h index c9105620..cd99ef34 100644 --- a/BasiliskII/src/include/timer.h +++ b/BasiliskII/src/include/timer.h @@ -42,4 +42,8 @@ extern int timer_cmp_time(tm_time_t a, tm_time_t b); extern void timer_mac2host_time(tm_time_t &res, int32 mactime); extern int32 timer_host2mac_time(tm_time_t hosttime); +// Suspend execution of emulator thread and resume it on events +extern void idle_wait(void); +extern void idle_resume(void); + #endif