diff options
-rw-r--r-- | common/threads.c | 87 | ||||
-rw-r--r-- | common/threads.h | 9 |
2 files changed, 96 insertions, 0 deletions
diff --git a/common/threads.c b/common/threads.c index dbd196e8..c1b062cd 100644 --- a/common/threads.c +++ b/common/threads.c @@ -389,6 +389,56 @@ void alcnd_destroy(alcnd_t *cond) #endif /* defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600 */ +int alsem_init(alsem_t *sem, unsigned int initial) +{ + *sem = CreateSemaphore(NULL, initial, INT_MAX, NULL); + if(*sem != NULL) return althrd_success; + return althrd_error; +} + +void alsem_destroy(alsem_t *sem) +{ + CloseHandle(*sem); +} + +int alsem_post(alsem_t *sem) +{ + DWORD ret = ReleaseSemaphore(*sem, 1, NULL); + if(ret) return althrd_success; + return althrd_error; +} + +int alsem_wait(alsem_t *sem) +{ + DWORD ret = WaitForSingleObject(*sem, INFINITE); + if(ret == WAIT_OBJECT_0) return althrd_success; + return althrd_error; +} + +int alsem_timedwait(alsem_t *sem, const struct timespec *time_point) +{ + struct timespec curtime; + DWORD sleeptime, ret; + + if(altimespec_get(&curtime, AL_TIME_UTC) != AL_TIME_UTC) + return althrd_error; + + if(curtime.tv_sec > time_point->tv_sec || (curtime.tv_sec == time_point->tv_sec && + curtime.tv_nsec >= time_point->tv_nsec)) + sleeptime = 0; + else + { + sleeptime = (DWORD)(time_point->tv_sec - curtime.tv_sec)*1000; + sleeptime += (time_point->tv_nsec - curtime.tv_nsec + 999999)/1000000; + } + + ret = WaitForSingleObject(*sem, sleeptime); + if(ret == WAIT_OBJECT_0) return althrd_success; + if(ret == WAIT_TIMEOUT) return althrd_timedout; + return althrd_error; +} + + /* An associative map of uint:void* pairs. The key is the TLS index (given by * TlsAlloc), and the value is the altss_dtor_t callback. When a thread exits, * we iterate over the TLS indices for their thread-local value and call the @@ -699,6 +749,43 @@ void alcnd_destroy(alcnd_t *cond) } +int alsem_init(alsem_t *sem, unsigned int initial) +{ + int ret = sem_init(sem, 0, initial); + if(ret == 0) return althrd_success; + return althrd_error; +} + +void alsem_destroy(alsem_t *sem) +{ + sem_destroy(sem); +} + +int alsem_post(alsem_t *sem) +{ + int ret = sem_post(sem); + if(ret == 0) return althrd_success; + return althrd_error; +} + +int alsem_wait(alsem_t *sem) +{ + int ret = sem_wait(sem); + if(ret == 0) return althrd_success; + if(errno == EINTR) return -2; + return althrd_error; +} + +int alsem_timedwait(alsem_t *sem, const struct timespec *time_point) +{ + int ret = sem_timedwait(sem, time_point); + if(ret == 0) return althrd_success; + if(errno == ETIMEDOUT) return althrd_timedout; + if(errno == EINTR) return -2; + return althrd_error; +} + + int altss_create(altss_t *tss_id, altss_dtor_t callback) { if(pthread_key_create(tss_id, callback) != 0) diff --git a/common/threads.h b/common/threads.h index 87b8a6f5..a8096546 100644 --- a/common/threads.h +++ b/common/threads.h @@ -57,6 +57,7 @@ typedef CONDITION_VARIABLE alcnd_t; #else typedef struct { void *Ptr; } alcnd_t; #endif +typedef HANDLE alsem_t; typedef DWORD altss_t; typedef LONG alonce_flag; @@ -127,11 +128,13 @@ inline int altss_set(altss_t tss_id, void *val) #include <stdint.h> #include <errno.h> #include <pthread.h> +#include <semaphore.h> typedef pthread_t althrd_t; typedef pthread_mutex_t almtx_t; typedef pthread_cond_t alcnd_t; +typedef sem_t alsem_t; typedef pthread_key_t altss_t; typedef pthread_once_t alonce_flag; @@ -233,6 +236,12 @@ int alcnd_wait(alcnd_t *cond, almtx_t *mtx); int alcnd_timedwait(alcnd_t *cond, almtx_t *mtx, const struct timespec *time_point); void alcnd_destroy(alcnd_t *cond); +int alsem_init(alsem_t *sem, unsigned int initial); +void alsem_destroy(alsem_t *sem); +int alsem_post(alsem_t *sem); +int alsem_wait(alsem_t *sem); +int alsem_timedwait(alsem_t *sem, const struct timespec *time_point); + int altss_create(altss_t *tss_id, altss_dtor_t callback); void altss_delete(altss_t tss_id); |