From 5af94b6759a9c4a31996982103b248b71ac36674 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Sep 2021 14:01:25 +0200 Subject: [PATCH] Rewrote thread.c so it uses Win32 threads on Windows. --- src/thread.c | 214 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 176 insertions(+), 38 deletions(-) diff --git a/src/thread.c b/src/thread.c index d95c337d1..3dd41ed08 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1,52 +1,191 @@ -#include +#include #include +#include #include -#include -#include +#ifdef __APPLE__ +#include +#endif #include <86box/86box.h> #include <86box/plat.h> +#if (defined WIN32) || (defined _WIN32) || (defined _WIN32) +#include +#include + +typedef struct { + HANDLE handle; +} win_event_t; + + +thread_t * +thread_create(void (*func)(void *param), void *param) +{ + uintptr_t bt = _beginthread(func, 0, param); + return((thread_t *)bt); +} + + +int +thread_wait(thread_t *arg, int timeout) +{ + if (arg == NULL) return(0); + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(arg, timeout)) return(1); + + return(0); +} + + +event_t * +thread_create_event(void) +{ + win_event_t *ev = malloc(sizeof(win_event_t)); + + ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return((event_t *)ev); +} + + +void +thread_set_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + SetEvent(ev->handle); +} + + +void +thread_reset_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + ResetEvent(ev->handle); +} + + +int +thread_wait_event(event_t *arg, int timeout) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return(0); + + if (ev->handle == NULL) return(0); + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(ev->handle, timeout)) return(1); + + return(0); +} + + +void +thread_destroy_event(event_t *arg) +{ + win_event_t *ev = (win_event_t *)arg; + + if (arg == NULL) return; + + CloseHandle(ev->handle); + + free(ev); +} + + +mutex_t * +thread_create_mutex(void) +{ + mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); + + InitializeCriticalSection(mutex); + + return mutex; +} + + +mutex_t * +thread_create_mutex_with_spin_count(unsigned int spin_count) +{ + mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION)); + + InitializeCriticalSectionAndSpinCount(mutex, spin_count); + + return mutex; +} + + +int +thread_wait_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return(0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + EnterCriticalSection(critsec); + + return 1; +} + + +int +thread_release_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return(0); + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + LeaveCriticalSection(critsec); + + return 1; +} + + +void +thread_close_mutex(mutex_t *mutex) +{ + if (mutex == NULL) return; + + LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex; + + DeleteCriticalSection(critsec); + + free(critsec); +} +#else +#include +#include typedef struct event_pthread_t { pthread_cond_t cond; pthread_mutex_t mutex; - int state; + int state; } event_pthread_t; -typedef struct thread_param -{ - void (*thread_rout)(void*); - void * param; -} thread_param; - - typedef struct pt_mutex_t { pthread_mutex_t mutex; } pt_mutex_t; -void * -thread_run_wrapper(thread_param* arg) -{ - thread_param localparam = *arg; - free(arg); - localparam.thread_rout(localparam.param); - return NULL; -} - - thread_t * thread_create(void (*thread_rout)(void *param), void *param) { pthread_t *thread = malloc(sizeof(pthread_t)); - thread_param *thrparam = malloc(sizeof(thread_param)); - thrparam->thread_rout = thread_rout; - thrparam->param = param; - pthread_create(thread, NULL, (void* (*)(void*))thread_run_wrapper, thrparam); + pthread_create(thread, NULL, (void*)thread_rout, param); return thread; } @@ -101,10 +240,13 @@ thread_wait_event(event_t *handle, int timeout) event_pthread_t *event = (event_pthread_t *)handle; struct timespec abstime; -#ifdef HAS_TIMESPEC_GET - timespec_get(&abstime, TIME_UTC); -#else +#ifdef __linux__ clock_gettime(CLOCK_REALTIME, &abstime); +#else + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec; + abstime.tv_nsec = now.tv_usec*1000UL; #endif abstime.tv_nsec += (timeout % 1000) * 1000000; abstime.tv_sec += (timeout / 1000); @@ -156,26 +298,21 @@ thread_create_mutex_with_spin_count(unsigned int spin_count) } -int +void thread_wait_mutex(mutex_t *_mutex) { - if (_mutex == NULL) - return(0); pt_mutex_t *mutex = (pt_mutex_t *)_mutex; - return - pthread_mutex_lock(&mutex->mutex) != 0; + pthread_mutex_lock(&mutex->mutex); } -int -thread_release_mutex(mutex_t *_mutex) +void +thread_unlock_mutex(mutex_t *_mutex) { - if (_mutex == NULL) - return(0); pt_mutex_t *mutex = (pt_mutex_t *)_mutex; - return pthread_mutex_unlock(&mutex->mutex) != 0; + pthread_mutex_unlock(&mutex->mutex); } @@ -188,3 +325,4 @@ thread_close_mutex(mutex_t *_mutex) free(mutex); } +#endif