Commit 9a33184d authored by Henrik Gramner's avatar Henrik Gramner Committed by Henrik Gramner

Windows: Improve pthread wrapper

 * Remove the use of malloc() in pthread_create()
 * Make function return values match regular pthread
 * Fix code style issues
 * Simplify some code
parent f2f89a3b
......@@ -34,62 +34,72 @@
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
typedef struct {
HANDLE h;
void *(*func)(void*);
void *arg;
} pthread_t;
typedef SRWLOCK pthread_mutex_t;
typedef CONDITION_VARIABLE pthread_cond_t;
typedef INIT_ONCE pthread_once_t;
typedef void *pthread_t;
typedef void *pthread_mutexattr_t;
typedef void *pthread_condattr_t;
typedef void *pthread_attr_t;
int dav1d_pthread_create(pthread_t* thread, const pthread_attr_t* attr,
void*(*proc)(void*), void* param);
void dav1d_pthread_join(pthread_t thread, void** res);
int dav1d_pthread_create(pthread_t *thread, const void *attr,
void *(*func)(void*), void *arg);
int dav1d_pthread_join(pthread_t *thread, void **res);
int dav1d_pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
#define pthread_create dav1d_pthread_create
#define pthread_join dav1d_pthread_join
#define pthread_join(thread, res) dav1d_pthread_join(&(thread), res)
#define pthread_once dav1d_pthread_once
static inline void pthread_mutex_init(pthread_mutex_t* mutex,
const pthread_mutexattr_t* attr)
static inline int pthread_mutex_init(pthread_mutex_t *const mutex,
const void *const attr)
{
(void)attr;
InitializeSRWLock(mutex);
return 0;
}
static inline void pthread_mutex_destroy(pthread_mutex_t* mutex) {
(void)mutex;
static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) {
return 0;
}
static inline void pthread_mutex_lock(pthread_mutex_t* mutex) {
static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) {
AcquireSRWLockExclusive(mutex);
return 0;
}
static inline void pthread_mutex_unlock(pthread_mutex_t* mutex) {
static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
ReleaseSRWLockExclusive(mutex);
return 0;
}
static inline void pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr) {
(void)attr;
static inline int pthread_cond_init(pthread_cond_t *const cond,
const void *const attr)
{
InitializeConditionVariable(cond);
return 0;
}
static inline void pthread_cond_destroy(pthread_cond_t* cond) {
(void)cond;
static inline int pthread_cond_destroy(pthread_cond_t *const cond) {
return 0;
}
static inline void pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) {
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
static inline int pthread_cond_wait(pthread_cond_t *const cond,
pthread_mutex_t *const mutex)
{
return !SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
}
static inline void pthread_cond_signal(pthread_cond_t* cond) {
static inline int pthread_cond_signal(pthread_cond_t *const cond) {
WakeConditionVariable(cond);
return 0;
}
static inline void pthread_cond_broadcast(pthread_cond_t* cond) {
static inline int pthread_cond_broadcast(pthread_cond_t *const cond) {
WakeAllConditionVariable(cond);
return 0;
}
#else
......
......@@ -29,75 +29,50 @@
#if defined(_WIN32)
#include <errno.h>
#include <process.h>
#include <stdlib.h>
#include <windows.h>
#include "config.h"
#include "src/thread.h"
typedef struct dav1d_win32_thread_t {
HANDLE h;
void* param;
void*(*proc)(void*);
void* res;
} dav1d_win32_thread_t;
static unsigned __stdcall dav1d_thread_entrypoint(void* data) {
dav1d_win32_thread_t* t = data;
t->res = t->proc(t->param);
static unsigned __stdcall thread_entrypoint(void *const data) {
pthread_t *const t = data;
t->arg = t->func(t->arg);
return 0;
}
int dav1d_pthread_create(pthread_t* thread, const pthread_attr_t* attr,
void*(*proc)(void*), void* param)
int dav1d_pthread_create(pthread_t *const thread, const void *const attr,
void *(*const func)(void*), void *const arg)
{
dav1d_win32_thread_t* th = *thread = malloc(sizeof(*th));
(void)attr;
if (th == NULL)
return ENOMEM;
th->proc = proc;
th->param = param;
uintptr_t h = _beginthreadex(NULL, 0, dav1d_thread_entrypoint, th, 0, NULL);
if ( h == 0 ) {
int err = errno;
free(th);
*thread = NULL;
return err;
}
th->h = (HANDLE)h;
return 0;
thread->func = func;
thread->arg = arg;
thread->h = (HANDLE)_beginthreadex(NULL, 0, thread_entrypoint,
thread, 0, NULL);
return !thread->h;
}
void dav1d_pthread_join(pthread_t thread, void** res) {
dav1d_win32_thread_t* th = thread;
WaitForSingleObject(th->h, INFINITE);
int dav1d_pthread_join(pthread_t *const thread, void **const res) {
if (WaitForSingleObject(thread->h, INFINITE))
return 1;
if (res != NULL)
*res = th->res;
CloseHandle(th->h);
free(th);
if (res)
*res = thread->arg;
return !CloseHandle(thread->h);
}
int dav1d_pthread_once(pthread_once_t *once_control,
void (*init_routine)(void))
int dav1d_pthread_once(pthread_once_t *const once_control,
void (*const init_routine)(void))
{
BOOL fPending = FALSE;
BOOL fStatus;
BOOL pending = FALSE;
fStatus = InitOnceBeginInitialize(once_control, 0, &fPending, NULL);
if (fStatus != TRUE)
return EINVAL;
if (InitOnceBeginInitialize(once_control, 0, &pending, NULL) != TRUE)
return 1;
if (fPending == TRUE)
if (pending == TRUE)
init_routine();
fStatus = InitOnceComplete(once_control, 0, NULL);
if (!fStatus)
return EINVAL;
return 0;
return !InitOnceComplete(once_control, 0, NULL);
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment