diff options
-rw-r--r-- | Alc/helpers.c | 256 | ||||
-rw-r--r-- | Alc/threads.c | 255 |
2 files changed, 255 insertions, 256 deletions
diff --git a/Alc/helpers.c b/Alc/helpers.c index 78367c77..bf8c5ca1 100644 --- a/Alc/helpers.c +++ b/Alc/helpers.c @@ -309,127 +309,8 @@ void RestoreFPUMode(const FPUCtl *ctl) } -extern inline int althrd_equal(althrd_t thr0, althrd_t thr1); -extern inline void althrd_exit(int res); -extern inline void althrd_yield(void); - -extern inline int almtx_lock(almtx_t *mtx); -extern inline int almtx_unlock(almtx_t *mtx); -extern inline int almtx_trylock(almtx_t *mtx); - #ifdef _WIN32 -#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ - -typedef struct thread_cntr { - althrd_start_t func; - void *arg; -} thread_cntr; - -static DWORD WINAPI thread_starter(void *arg) -{ - thread_cntr cntr; - memcpy(&cntr, arg, sizeof(cntr)); - free(arg); - - return (DWORD)((*cntr.func)(cntr.arg)); -} - - -int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) -{ - thread_cntr *cntr; - DWORD dummy; - HANDLE hdl; - - cntr = malloc(sizeof(*cntr)); - if(!cntr) return althrd_nomem; - - cntr->func = func; - cntr->arg = arg; - - hdl = CreateThread(NULL, THREAD_STACK_SIZE, thread_starter, cntr, 0, &dummy); - if(!hdl) - { - free(cntr); - return althrd_error; - } - - *thr = hdl; - return althrd_success; -} - -int althrd_detach(althrd_t thr) -{ - if(!thr) return althrd_error; - CloseHandle(thr); - - return althrd_success; -} - -int althrd_join(althrd_t thr, int *res) -{ - DWORD code; - - if(!thr) return althrd_error; - - WaitForSingleObject(thr, INFINITE); - GetExitCodeThread(thr, &code); - CloseHandle(thr); - - *res = (int)code; - return althrd_success; -} - -int althrd_sleep(const struct timespec *ts, struct timespec* UNUSED(rem)) -{ - DWORD msec; - msec = ts->tv_sec * 1000; - msec += (ts->tv_nsec+999999) / 1000000; - Sleep(msec); - return 0; -} - - -int almtx_init(almtx_t *mtx, int type) -{ - if(!mtx) return althrd_error; - type &= ~(almtx_recursive|almtx_timed|almtx_normal|almtx_errorcheck); - if(type != 0) return althrd_error; - - InitializeCriticalSection(mtx); - return althrd_success; -} - -void almtx_destroy(almtx_t *mtx) -{ - DeleteCriticalSection(mtx); -} - -int almtx_timedlock(almtx_t *mtx, const struct timespec *ts) -{ - DWORD start, timelen; - int ret; - - if(!mtx || !ts) - return althrd_error; - - timelen = ts->tv_sec * 1000; - timelen += (ts->tv_nsec+999999) / 1000000; - - start = timeGetTime(); - while((ret=almtx_trylock(mtx)) == althrd_busy) - { - DWORD now = timeGetTime(); - if(now-start >= timelen) - break; - SwitchToThread(); - } - - return ret; -} - - extern inline int alsched_yield(void); void althread_once(althread_once_t *once, void (*callback)(void)) @@ -533,148 +414,11 @@ FILE *al_fopen(const char *fname, const char *mode) #else -#include <pthread.h> -#ifdef HAVE_PTHREAD_NP_H -#include <pthread_np.h> -#endif #include <sched.h> #include <time.h> #include <sys/time.h> -extern inline althrd_t althrd_current(void); -extern inline int althrd_sleep(const struct timespec *ts, struct timespec *rem); - - -#define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ - -typedef struct thread_cntr { - althrd_start_t func; - void *arg; -} thread_cntr; - -static void *thread_starter(void *arg) -{ - thread_cntr cntr; - memcpy(&cntr, arg, sizeof(cntr)); - free(arg); - - return (void*)(intptr_t)((*cntr.func)(cntr.arg)); -} - - -int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) -{ - thread_cntr *cntr; - pthread_attr_t attr; - - cntr = malloc(sizeof(*cntr)); - if(!cntr) return althrd_nomem; - - if(pthread_attr_init(&attr) != 0) - { - free(cntr); - return althrd_error; - } - if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0) - { - pthread_attr_destroy(&attr); - free(cntr); - return althrd_error; - } - - cntr->func = func; - cntr->arg = arg; - if(pthread_create(thr, &attr, thread_starter, cntr) != 0) - { - pthread_attr_destroy(&attr); - free(cntr); - return althrd_error; - } - pthread_attr_destroy(&attr); - - return althrd_success; -} - -int althrd_detach(althrd_t thr) -{ - if(pthread_detach(thr) != 0) - return althrd_error; - return althrd_success; -} - -int althrd_join(althrd_t thr, int *res) -{ - void *code; - - if(!res) return althrd_error; - - if(pthread_join(thr, &code) != 0) - return althrd_error; - *res = (int)(intptr_t)code; - return althrd_success; -} - - -int almtx_init(almtx_t *mtx, int type) -{ - int ret; - - if(!mtx) return althrd_error; - if((type&~(almtx_normal|almtx_recursive|almtx_timed|almtx_errorcheck)) != 0) - return althrd_error; - - type &= ~almtx_timed; - if(type == almtx_plain) - ret = pthread_mutex_init(mtx, NULL); - else - { - pthread_mutexattr_t attr; - - ret = pthread_mutexattr_init(&attr); - if(ret) return althrd_error; - - switch(type) - { - case almtx_normal: - ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - break; - case almtx_recursive: - ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -#ifdef HAVE_PTHREAD_NP_H - if(ret != 0) - ret = pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE); -#endif - break; - case almtx_errorcheck: - ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); - break; - default: - ret = 1; - } - if(ret == 0) - ret = pthread_mutex_init(mtx, &attr); - pthread_mutexattr_destroy(&attr); - } - return ret ? althrd_error : althrd_success; -} - -void almtx_destroy(almtx_t *mtx) -{ - pthread_mutex_destroy(mtx); -} - -int almtx_timedlock(almtx_t *mtx, const struct timespec *ts) -{ - if(!mtx || !ts) - return althrd_error; - - if(pthread_mutex_timedlock(mtx, ts) != 0) - return althrd_busy; - return althrd_success; -} - - /* NOTE: This wrapper isn't quite accurate as it returns an ALuint, as opposed * to the expected DWORD. Both are defined as unsigned 32-bit types, however. * Additionally, Win32 is supposed to measure the time since Windows started, diff --git a/Alc/threads.c b/Alc/threads.c index 64586ae9..d910716c 100644 --- a/Alc/threads.c +++ b/Alc/threads.c @@ -28,12 +28,23 @@ #include "alMain.h" #include "alThunk.h" + +extern inline int althrd_equal(althrd_t thr0, althrd_t thr1); +extern inline void althrd_exit(int res); +extern inline void althrd_yield(void); + +extern inline int almtx_lock(almtx_t *mtx); +extern inline int almtx_unlock(almtx_t *mtx); +extern inline int almtx_trylock(almtx_t *mtx); + + #define THREAD_STACK_SIZE (1*1024*1024) /* 1MB */ #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include <mmsystem.h> typedef struct althread_info { ALuint (*func)(ALvoid*); @@ -115,9 +126,122 @@ void SetThreadName(const char *name) #endif } + +typedef struct thread_cntr { + althrd_start_t func; + void *arg; +} thread_cntr; + +static DWORD WINAPI althrd_starter(void *arg) +{ + thread_cntr cntr; + memcpy(&cntr, arg, sizeof(cntr)); + free(arg); + + return (DWORD)((*cntr.func)(cntr.arg)); +} + + +int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) +{ + thread_cntr *cntr; + DWORD dummy; + HANDLE hdl; + + cntr = malloc(sizeof(*cntr)); + if(!cntr) return althrd_nomem; + + cntr->func = func; + cntr->arg = arg; + + hdl = CreateThread(NULL, THREAD_STACK_SIZE, althrd_starter, cntr, 0, &dummy); + if(!hdl) + { + free(cntr); + return althrd_error; + } + + *thr = hdl; + return althrd_success; +} + +int althrd_detach(althrd_t thr) +{ + if(!thr) return althrd_error; + CloseHandle(thr); + + return althrd_success; +} + +int althrd_join(althrd_t thr, int *res) +{ + DWORD code; + + if(!thr) return althrd_error; + + WaitForSingleObject(thr, INFINITE); + GetExitCodeThread(thr, &code); + CloseHandle(thr); + + *res = (int)code; + return althrd_success; +} + +int althrd_sleep(const struct timespec *ts, struct timespec* UNUSED(rem)) +{ + DWORD msec; + msec = ts->tv_sec * 1000; + msec += (ts->tv_nsec+999999) / 1000000; + Sleep(msec); + return 0; +} + + +int almtx_init(almtx_t *mtx, int type) +{ + if(!mtx) return althrd_error; + type &= ~(almtx_recursive|almtx_timed|almtx_normal|almtx_errorcheck); + if(type != 0) return althrd_error; + + InitializeCriticalSection(mtx); + return althrd_success; +} + +void almtx_destroy(almtx_t *mtx) +{ + DeleteCriticalSection(mtx); +} + +int almtx_timedlock(almtx_t *mtx, const struct timespec *ts) +{ + DWORD start, timelen; + int ret; + + if(!mtx || !ts) + return althrd_error; + + timelen = ts->tv_sec * 1000; + timelen += (ts->tv_nsec+999999) / 1000000; + + start = timeGetTime(); + while((ret=almtx_trylock(mtx)) == althrd_busy) + { + DWORD now = timeGetTime(); + if(now-start >= timelen) + break; + SwitchToThread(); + } + + return ret; +} + + #else #include <pthread.h> +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif typedef struct althread_info { ALuint (*func)(ALvoid*); @@ -197,4 +321,135 @@ void SetThreadName(const char *name) #endif } + +extern inline althrd_t althrd_current(void); +extern inline int althrd_sleep(const struct timespec *ts, struct timespec *rem); + + +typedef struct thread_cntr { + althrd_start_t func; + void *arg; +} thread_cntr; + +static void *althrd_starter(void *arg) +{ + thread_cntr cntr; + memcpy(&cntr, arg, sizeof(cntr)); + free(arg); + + return (void*)(intptr_t)((*cntr.func)(cntr.arg)); +} + + +int althrd_create(althrd_t *thr, althrd_start_t func, void *arg) +{ + thread_cntr *cntr; + pthread_attr_t attr; + + cntr = malloc(sizeof(*cntr)); + if(!cntr) return althrd_nomem; + + if(pthread_attr_init(&attr) != 0) + { + free(cntr); + return althrd_error; + } + if(pthread_attr_setstacksize(&attr, THREAD_STACK_SIZE) != 0) + { + pthread_attr_destroy(&attr); + free(cntr); + return althrd_error; + } + + cntr->func = func; + cntr->arg = arg; + if(pthread_create(thr, &attr, althrd_starter, cntr) != 0) + { + pthread_attr_destroy(&attr); + free(cntr); + return althrd_error; + } + pthread_attr_destroy(&attr); + + return althrd_success; +} + +int althrd_detach(althrd_t thr) +{ + if(pthread_detach(thr) != 0) + return althrd_error; + return althrd_success; +} + +int althrd_join(althrd_t thr, int *res) +{ + void *code; + + if(!res) return althrd_error; + + if(pthread_join(thr, &code) != 0) + return althrd_error; + *res = (int)(intptr_t)code; + return althrd_success; +} + + +int almtx_init(almtx_t *mtx, int type) +{ + int ret; + + if(!mtx) return althrd_error; + if((type&~(almtx_normal|almtx_recursive|almtx_timed|almtx_errorcheck)) != 0) + return althrd_error; + + type &= ~almtx_timed; + if(type == almtx_plain) + ret = pthread_mutex_init(mtx, NULL); + else + { + pthread_mutexattr_t attr; + + ret = pthread_mutexattr_init(&attr); + if(ret) return althrd_error; + + switch(type) + { + case almtx_normal: + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + break; + case almtx_recursive: + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); +#ifdef HAVE_PTHREAD_NP_H + if(ret != 0) + ret = pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE); +#endif + break; + case almtx_errorcheck: + ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); + break; + default: + ret = 1; + } + if(ret == 0) + ret = pthread_mutex_init(mtx, &attr); + pthread_mutexattr_destroy(&attr); + } + return ret ? althrd_error : althrd_success; +} + +void almtx_destroy(almtx_t *mtx) +{ + pthread_mutex_destroy(mtx); +} + +int almtx_timedlock(almtx_t *mtx, const struct timespec *ts) +{ + if(!mtx || !ts) + return althrd_error; + + if(pthread_mutex_timedlock(mtx, ts) != 0) + return althrd_busy; + return althrd_success; +} + #endif |