shithub: dav1d

Download patch

ref: 707a32a57df226e3364dcc4373fc32ae7a69af91
parent: e2892ffa2dd1e893d0229c5fcbe0bbbee8e11c20
author: Hugo Beauzée-Luyssen <[email protected]>
date: Thu Sep 20 09:21:08 EDT 2018

Add & use a thread compatibility layer

--- a/meson.build
+++ b/meson.build
@@ -34,8 +34,11 @@
 if not meson.is_cross_build() 
     thread_dependency = dependency('threads')
 else
-    thread_dependency = cc.find_library('pthread')
+    thread_dependency = cc.find_library('pthread', required: false)
 endif
+if thread_dependency.found()
+    cdata.set('HAVE_PTHREAD_H', 1)
+endif
 
 dav1d_inc_dirs = include_directories(['include', 'include/dav1d'])
 
@@ -192,6 +195,10 @@
     'src/wedge.c',
     'src/qm.c',
 )
+
+if host_machine.system() == 'windows'
+    libdav1d_sources += files('src/win32/thread.c')
+endif
 
 libdav1d = library('dav1d',
     libdav1d_sources, rev_target,
--- a/src/cdf.c
+++ b/src/cdf.c
@@ -28,9 +28,9 @@
 #include "config.h"
 
 #include <assert.h>
-#include <pthread.h>
 #include <string.h>
 
+#include "src/thread.h"
 #include "common/intops.h"
 
 #include "src/cdf.h"
--- a/src/internal.h
+++ b/src/internal.h
@@ -28,7 +28,6 @@
 #ifndef __DAV1D_SRC_INTERNAL_H__
 #define __DAV1D_SRC_INTERNAL_H__
 
-#include <pthread.h>
 #include <stdatomic.h>
 
 #include "dav1d/data.h"
@@ -54,6 +53,7 @@
 #include "src/picture.h"
 #include "src/recon.h"
 #include "src/ref_mvs.h"
+#include "src/thread.h"
 
 typedef struct Dav1dDSPContext {
     Dav1dIntraPredDSPContext ipred;
--- a/src/picture.c
+++ b/src/picture.c
@@ -39,6 +39,7 @@
 
 #include "src/picture.h"
 #include "src/ref.h"
+#include "src/thread.h"
 
 static int picture_alloc_with_edges(Dav1dPicture *const p,
                                     const int w, const int h,
--- a/src/picture.h
+++ b/src/picture.h
@@ -28,9 +28,9 @@
 #ifndef __DAV1D_SRC_PICTURE_H__
 #define __DAV1D_SRC_PICTURE_H__
 
-#include <pthread.h>
 #include <stdatomic.h>
 
+#include "src/thread.h"
 #include "dav1d/picture.h"
 
 #include "src/thread_data.h"
--- /dev/null
+++ b/src/thread.h
@@ -1,0 +1,63 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __DAV1D_THREAD_H__
+# define __DAV1D_THREAD_H__
+
+#if defined(_WIN32) && !defined(HAVE_PTHREAD_H)
+
+#include <windows.h>
+
+typedef CRITICAL_SECTION pthread_mutex_t;
+typedef CONDITION_VARIABLE pthread_cond_t;
+typedef void *pthread_t;
+typedef void *pthread_mutexattr_t;
+typedef void *pthread_condattr_t;
+typedef void *pthread_attr_t;
+
+void pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);
+void pthread_mutex_destroy(pthread_mutex_t* mutex);
+void pthread_mutex_lock(pthread_mutex_t* mutex);
+void pthread_mutex_unlock(pthread_mutex_t* mutex);
+
+void pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr);
+void pthread_cond_destroy(pthread_cond_t* cond);
+void pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
+void pthread_cond_signal(pthread_cond_t* cond);
+void pthread_cond_broadcast(pthread_cond_t* cond);
+
+int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
+                   void*(*proc)(void*), void* param);
+void pthread_join(pthread_t thread, void** res);
+
+#else
+
+#include <pthread.h>
+
+#endif
+
+#endif // __DAV1D_THREAD_H__
--- a/src/thread_data.h
+++ b/src/thread_data.h
@@ -28,6 +28,8 @@
 #ifndef __DAV1D_SRC_THREAD_DATA_H__
 #define __DAV1D_SRC_THREAD_DATA_H__
 
+#include "src/thread.h"
+
 struct thread_data {
     pthread_t thread;
     pthread_cond_t cond;
--- a/src/thread_task.c
+++ b/src/thread_task.c
@@ -53,7 +53,6 @@
         decode_frame(f);
     }
 
-    pthread_exit(NULL);
     return NULL;
 }
 
@@ -132,6 +131,5 @@
         }
     }
 
-    pthread_exit(NULL);
     return NULL;
 }
--- /dev/null
+++ b/src/win32/thread.c
@@ -1,0 +1,128 @@
+/*
+ * Copyright © 2018, VideoLAN and dav1d authors
+ * Copyright © 2018, Two Orioles, LLC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if defined(_WIN32) && !defined(HAVE_PTHREAD_H)
+
+#include <windows.h>
+#include <process.h>
+#include <errno.h>
+
+#include "config.h"
+#include "src/thread.h"
+
+void pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr)
+{
+    (void)attr;
+    InitializeCriticalSection(mutex);
+}
+
+void pthread_mutex_destroy(pthread_mutex_t* mutex)
+{
+    DeleteCriticalSection(mutex);
+}
+
+void pthread_mutex_lock(pthread_mutex_t* mutex)
+{
+    EnterCriticalSection(mutex);
+}
+
+void pthread_mutex_unlock(pthread_mutex_t* mutex)
+{
+    LeaveCriticalSection(mutex);
+}
+
+void pthread_cond_init(pthread_cond_t* cond, const pthread_condattr_t* attr)
+{
+    (void)attr;
+    InitializeConditionVariable(cond);
+}
+
+void pthread_cond_destroy(pthread_cond_t* cond)
+{
+    (void)cond;
+}
+
+void pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex)
+{
+    SleepConditionVariableCS(cond, mutex, INFINITE);
+}
+
+void pthread_cond_signal(pthread_cond_t* cond)
+{
+    WakeConditionVariable(cond);
+}
+
+void pthread_cond_broadcast(pthread_cond_t* cond)
+{
+    WakeAllConditionVariable(cond);
+}
+
+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 );
+    return 0;
+}
+
+int pthread_create(pthread_t* thread, const pthread_attr_t* attr, void*(*proc)(void*), void* param)
+{
+    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;
+        free(th);
+        *thread = NULL;
+        return err;
+    }
+    th->h = (HANDLE)h;
+    return 0;
+}
+
+void pthread_join(pthread_t thread, void** res)
+{
+    dav1d_win32_thread_t* th = thread;
+    WaitForSingleObject(th->h, INFINITE);
+
+    if (res != NULL)
+        *res = th->res;
+    free(th);
+}
+
+#endif