aom_pthread.h (5134B)
1 /* 2 * Copyright (c) 2024, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 // 12 // pthread.h wrapper 13 14 #ifndef AOM_AOM_UTIL_AOM_PTHREAD_H_ 15 #define AOM_AOM_UTIL_AOM_PTHREAD_H_ 16 17 #include "config/aom_config.h" 18 19 #if CONFIG_MULTITHREAD 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 #if defined(_WIN32) && !HAVE_PTHREAD_H 26 // Prevent leaking max/min macros. 27 #undef NOMINMAX 28 #define NOMINMAX 29 #undef WIN32_LEAN_AND_MEAN 30 #define WIN32_LEAN_AND_MEAN 31 #include <errno.h> // NOLINT 32 #include <process.h> // NOLINT 33 #include <stddef.h> // NOLINT 34 #include <windows.h> // NOLINT 35 typedef HANDLE pthread_t; 36 typedef int pthread_attr_t; 37 typedef SRWLOCK pthread_mutex_t; 38 39 #if _WIN32_WINNT < 0x0600 40 #error _WIN32_WINNT must target Windows Vista / Server 2008 or newer. 41 #endif 42 typedef CONDITION_VARIABLE pthread_cond_t; 43 44 #ifndef WINAPI_FAMILY_PARTITION 45 #define WINAPI_PARTITION_DESKTOP 1 46 #define WINAPI_FAMILY_PARTITION(x) x 47 #endif 48 49 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 50 #define USE_CREATE_THREAD 51 #endif 52 53 //------------------------------------------------------------------------------ 54 // simplistic pthread emulation layer 55 56 // _beginthreadex requires __stdcall 57 #if defined(__GNUC__) && \ 58 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) 59 #define THREADFN __attribute__((force_align_arg_pointer)) unsigned int __stdcall 60 #else 61 #define THREADFN unsigned int __stdcall 62 #endif 63 #define THREAD_EXIT_SUCCESS 0 64 65 static inline int pthread_attr_init(pthread_attr_t *attr) { 66 (void)attr; 67 return 0; 68 } 69 70 static inline int pthread_attr_destroy(pthread_attr_t *attr) { 71 (void)attr; 72 return 0; 73 } 74 75 static inline int pthread_attr_getstacksize(const pthread_attr_t *attr, 76 size_t *stacksize) { 77 (void)attr; 78 (void)stacksize; 79 return EINVAL; 80 } 81 82 static inline int pthread_attr_setstacksize(pthread_attr_t *attr, 83 size_t stacksize) { 84 (void)attr; 85 (void)stacksize; 86 return EINVAL; 87 } 88 89 static inline int pthread_create(pthread_t *const thread, 90 const pthread_attr_t *attr, 91 unsigned int(__stdcall *start)(void *), 92 void *arg) { 93 (void)attr; 94 #ifdef USE_CREATE_THREAD 95 *thread = CreateThread(NULL, /* lpThreadAttributes */ 96 0, /* dwStackSize */ 97 start, arg, 0, /* dwStackSize */ 98 NULL); /* lpThreadId */ 99 #else 100 *thread = (pthread_t)_beginthreadex(NULL, /* void *security */ 101 0, /* unsigned stack_size */ 102 start, arg, 0, /* unsigned initflag */ 103 NULL); /* unsigned *thrdaddr */ 104 #endif 105 if (*thread == NULL) return 1; 106 SetThreadPriority(*thread, THREAD_PRIORITY_ABOVE_NORMAL); 107 return 0; 108 } 109 110 static inline int pthread_join(pthread_t thread, void **value_ptr) { 111 (void)value_ptr; 112 return (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0 || 113 CloseHandle(thread) == 0); 114 } 115 116 // Mutex 117 static inline int pthread_mutex_init(pthread_mutex_t *const mutex, 118 void *mutexattr) { 119 (void)mutexattr; 120 InitializeSRWLock(mutex); 121 return 0; 122 } 123 124 static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) { 125 AcquireSRWLockExclusive(mutex); 126 return 0; 127 } 128 129 static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) { 130 ReleaseSRWLockExclusive(mutex); 131 return 0; 132 } 133 134 static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) { 135 (void)mutex; 136 return 0; 137 } 138 139 // Condition 140 static inline int pthread_cond_destroy(pthread_cond_t *const condition) { 141 (void)condition; 142 return 0; 143 } 144 145 static inline int pthread_cond_init(pthread_cond_t *const condition, 146 void *cond_attr) { 147 (void)cond_attr; 148 InitializeConditionVariable(condition); 149 return 0; 150 } 151 152 static inline int pthread_cond_signal(pthread_cond_t *const condition) { 153 WakeConditionVariable(condition); 154 return 0; 155 } 156 157 static inline int pthread_cond_broadcast(pthread_cond_t *const condition) { 158 WakeAllConditionVariable(condition); 159 return 0; 160 } 161 162 static inline int pthread_cond_wait(pthread_cond_t *const condition, 163 pthread_mutex_t *const mutex) { 164 const int ok = SleepConditionVariableSRW(condition, mutex, INFINITE, 0); 165 return !ok; 166 } 167 #else // _WIN32 168 #include <pthread.h> // NOLINT 169 #define THREADFN void * 170 #define THREAD_EXIT_SUCCESS NULL 171 #endif 172 173 #ifdef __cplusplus 174 } // extern "C" 175 #endif 176 177 #endif // CONFIG_MULTITHREAD 178 179 #endif // AOM_AOM_UTIL_AOM_PTHREAD_H_