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
Pipeline #4460 passed with stages
in 6 minutes and 39 seconds
......@@ -34,62 +34,72 @@
typedef struct {
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)
return 0;
static inline void pthread_mutex_destroy(pthread_mutex_t* 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) {
return 0;
static inline void pthread_mutex_unlock(pthread_mutex_t* mutex) {
static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
return 0;
static inline void pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr) {
static inline int pthread_cond_init(pthread_cond_t *const cond,
const void *const attr)
return 0;
static inline void pthread_cond_destroy(pthread_cond_t* 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) {
return 0;
static inline void pthread_cond_broadcast(pthread_cond_t* cond) {
static inline int pthread_cond_broadcast(pthread_cond_t *const cond) {
return 0;
......@@ -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 {
void* param;
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));
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;
*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;
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)
fStatus = InitOnceComplete(once_control, 0, NULL);
if (!fStatus)
return EINVAL;
return 0;
return !InitOnceComplete(once_control, 0, NULL);
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