mirror of https://github.com/mpv-player/mpv
win32: pthread: use SRW locks by default
SRW locks are available since Windows Vista. They work essentially like Linux futexes. In particular, they can be statically initialized, and do not require deinitialization. This makes them ideal for implementing PTHREAD_MUTEX_INITIALIZER. We still need CRITICAL_SECTION for recursive mutexes.
This commit is contained in:
parent
8ff96f0216
commit
b9cc33de58
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue