shithub: dav1d

Download patch

ref: 9a33184db45f00f4b929a2696229015258e66f3c
parent: f2f89a3ba4acbf824c40b5b33171d0f4c406ec59
author: Henrik Gramner <gramner@twoorioles.com>
date: Fri Feb 8 09:56:53 EST 2019

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

--- a/src/thread.h
+++ b/src/thread.h
@@ -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
--- a/src/win32/thread.c
+++ b/src/win32/thread.c
@@ -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