thread.h (5522B)
1 /* 2 * Copyright © 2018-2021, VideoLAN and dav1d authors 3 * Copyright © 2018, Two Orioles, LLC 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this 10 * list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef DAV1D_SRC_THREAD_H 29 #define DAV1D_SRC_THREAD_H 30 31 #if defined(_WIN32) 32 33 #include <limits.h> 34 #include <windows.h> 35 36 #define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT 37 #define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT 38 39 typedef struct { 40 HANDLE h; 41 void *(*func)(void*); 42 void *arg; 43 } pthread_t; 44 45 typedef struct { 46 unsigned stack_size; 47 } pthread_attr_t; 48 49 typedef SRWLOCK pthread_mutex_t; 50 typedef CONDITION_VARIABLE pthread_cond_t; 51 typedef INIT_ONCE pthread_once_t; 52 53 void dav1d_init_thread(void); 54 void dav1d_set_thread_name(const wchar_t *name); 55 #define dav1d_set_thread_name(name) dav1d_set_thread_name(L##name) 56 57 int dav1d_pthread_create(pthread_t *thread, const pthread_attr_t *attr, 58 void *(*func)(void*), void *arg); 59 int dav1d_pthread_join(pthread_t *thread, void **res); 60 int dav1d_pthread_once(pthread_once_t *once_control, 61 void (*init_routine)(void)); 62 63 #define pthread_create dav1d_pthread_create 64 #define pthread_join(thread, res) dav1d_pthread_join(&(thread), res) 65 #define pthread_once dav1d_pthread_once 66 67 static inline int pthread_attr_init(pthread_attr_t *const attr) { 68 attr->stack_size = 0; 69 return 0; 70 } 71 72 static inline int pthread_attr_destroy(pthread_attr_t *const attr) { 73 return 0; 74 } 75 76 static inline int pthread_attr_setstacksize(pthread_attr_t *const attr, 77 const size_t stack_size) 78 { 79 if (stack_size > UINT_MAX) return 1; 80 attr->stack_size = (unsigned) stack_size; 81 return 0; 82 } 83 84 static inline int pthread_mutex_init(pthread_mutex_t *const mutex, 85 const void *const attr) 86 { 87 InitializeSRWLock(mutex); 88 return 0; 89 } 90 91 static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) { 92 return 0; 93 } 94 95 static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) { 96 AcquireSRWLockExclusive(mutex); 97 return 0; 98 } 99 100 static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) { 101 ReleaseSRWLockExclusive(mutex); 102 return 0; 103 } 104 105 static inline int pthread_cond_init(pthread_cond_t *const cond, 106 const void *const attr) 107 { 108 InitializeConditionVariable(cond); 109 return 0; 110 } 111 112 static inline int pthread_cond_destroy(pthread_cond_t *const cond) { 113 return 0; 114 } 115 116 static inline int pthread_cond_wait(pthread_cond_t *const cond, 117 pthread_mutex_t *const mutex) 118 { 119 return !SleepConditionVariableSRW(cond, mutex, INFINITE, 0); 120 } 121 122 static inline int pthread_cond_signal(pthread_cond_t *const cond) { 123 WakeConditionVariable(cond); 124 return 0; 125 } 126 127 static inline int pthread_cond_broadcast(pthread_cond_t *const cond) { 128 WakeAllConditionVariable(cond); 129 return 0; 130 } 131 132 #else 133 134 #include <pthread.h> 135 #if defined(__FreeBSD__) 136 /* ALIGN from <sys/param.h> conflicts with ALIGN from "common/attributes.h" */ 137 #define _SYS_PARAM_H_ 138 #include <sys/types.h> 139 #endif 140 #if HAVE_PTHREAD_NP_H 141 #include <pthread_np.h> 142 #endif 143 144 #define dav1d_init_thread() do {} while (0) 145 146 /* Thread naming support */ 147 148 #ifdef __linux__ 149 150 #include <sys/prctl.h> 151 152 static inline void dav1d_set_thread_name(const char *const name) { 153 prctl(PR_SET_NAME, name); 154 } 155 156 #elif HAVE_PTHREAD_SETNAME_NP && defined(__APPLE__) 157 158 static inline void dav1d_set_thread_name(const char *const name) { 159 pthread_setname_np(name); 160 } 161 162 #elif HAVE_PTHREAD_SETNAME_NP && defined(__NetBSD__) 163 164 static inline void dav1d_set_thread_name(const char *const name) { 165 pthread_setname_np(pthread_self(), "%s", (void*)name); 166 } 167 168 #elif HAVE_PTHREAD_SETNAME_NP 169 170 static inline void dav1d_set_thread_name(const char *const name) { 171 pthread_setname_np(pthread_self(), name); 172 } 173 174 #elif HAVE_PTHREAD_SET_NAME_NP 175 176 static inline void dav1d_set_thread_name(const char *const name) { 177 pthread_set_name_np(pthread_self(), name); 178 } 179 180 #elif defined(__HAIKU__) 181 182 #include <os/kernel/OS.h> 183 184 static inline void dav1d_set_thread_name(const char *const name) { 185 rename_thread(find_thread(NULL), name); 186 } 187 188 #else 189 190 #define dav1d_set_thread_name(name) do {} while (0) 191 192 #endif 193 194 #endif 195 196 #endif /* DAV1D_SRC_THREAD_H */