diff --git a/osdep/win32/include/pthread.h b/osdep/win32/include/pthread.h index 7b82eb2651..e1324a0bb0 100644 --- a/osdep/win32/include/pthread.h +++ b/osdep/win32/include/pthread.h @@ -25,19 +25,21 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); typedef struct { - char static_mutex; - INIT_ONCE static_init; - CRITICAL_SECTION cs; + char use_cs; + union { + SRWLOCK srw; + CRITICAL_SECTION cs; + } lock; } pthread_mutex_t; -#define PTHREAD_MUTEX_INITIALIZER {1, INIT_ONCE_STATIC_INIT} +// Assume SRWLOCK_INIT is {0} so we can easily remain C89-compatible. +#define PTHREAD_MUTEX_INITIALIZER {0} #define pthread_mutexattr_t int #define pthread_mutexattr_destroy(attr) (void)0 #define pthread_mutexattr_init(attr) (*(attr) = 0) -#define pthread_mutexattr_settype(attr, type) (void)0 -// CRITICAL_SECTION is always recursive -#define PTHREAD_MUTEX_RECURSIVE 0 +#define pthread_mutexattr_settype(attr, type) (*(attr) = (type)) +#define PTHREAD_MUTEX_RECURSIVE 1 int pthread_mutex_destroy(pthread_mutex_t *mutex); int pthread_mutex_init(pthread_mutex_t *restrict mutex, diff --git a/osdep/win32/pthread.c b/osdep/win32/pthread.c index 4838df48b7..b215e46ba2 100644 --- a/osdep/win32/pthread.c +++ b/osdep/win32/pthread.c @@ -32,35 +32,40 @@ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) int pthread_mutex_destroy(pthread_mutex_t *mutex) { - DeleteCriticalSection(&mutex->cs); + if (mutex->use_cs) + DeleteCriticalSection(&mutex->lock.cs); return 0; } int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr) { - InitializeCriticalSection(&mutex->cs); + mutex->use_cs = attr && (*attr & PTHREAD_MUTEX_RECURSIVE); + if (mutex->use_cs) { + InitializeCriticalSection(&mutex->lock.cs); + } else { + InitializeSRWLock(&mutex->lock.srw); + } return 0; } int pthread_mutex_lock(pthread_mutex_t *mutex) { - if (mutex->static_mutex) { - BOOL pending; - if (!InitOnceBeginInitialize(&mutex->static_init, 0, &pending, NULL)) - abort(); - if (pending) { - InitializeCriticalSection(&mutex->cs); - InitOnceComplete(&mutex->static_init, 0, NULL); - } + if (mutex->use_cs) { + EnterCriticalSection(&mutex->lock.cs); + } else { + AcquireSRWLockExclusive(&mutex->lock.srw); } - EnterCriticalSection(&mutex->cs); return 0; } int pthread_mutex_unlock(pthread_mutex_t *mutex) { - LeaveCriticalSection(&mutex->cs); + if (mutex->use_cs) { + LeaveCriticalSection(&mutex->lock.cs); + } else { + ReleaseSRWLockExclusive(&mutex->lock.srw); + } return 0; } @@ -68,7 +73,13 @@ static int cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, DWORD ms) { - return SleepConditionVariableCS(cond, &mutex->cs, ms) ? 0 : ETIMEDOUT; + BOOL res; + if (mutex->use_cs) { + res = SleepConditionVariableCS(cond, &mutex->lock.cs, ms); + } else { + res = SleepConditionVariableSRW(cond, &mutex->lock.srw, ms, 0); + } + return res ? 0 : ETIMEDOUT; } int pthread_cond_timedwait(pthread_cond_t *restrict cond,