thread.c (3387B)
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 #include "config.h" 29 30 #if defined(_WIN32) 31 32 #include <process.h> 33 #include <stdlib.h> 34 #include <windows.h> 35 36 #include "common/attributes.h" 37 38 #include "src/thread.h" 39 40 static HRESULT (WINAPI *set_thread_description)(HANDLE, PCWSTR); 41 42 COLD void dav1d_init_thread(void) { 43 #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) 44 HANDLE kernel32 = GetModuleHandleW(L"kernel32.dll"); 45 if (kernel32) 46 set_thread_description = 47 (void*)GetProcAddress(kernel32, "SetThreadDescription"); 48 #endif 49 } 50 51 #undef dav1d_set_thread_name 52 COLD void dav1d_set_thread_name(const wchar_t *const name) { 53 if (set_thread_description) /* Only available since Windows 10 1607 */ 54 set_thread_description(GetCurrentThread(), name); 55 } 56 57 static COLD unsigned __stdcall thread_entrypoint(void *const data) { 58 pthread_t *const t = data; 59 t->arg = t->func(t->arg); 60 return 0; 61 } 62 63 COLD int dav1d_pthread_create(pthread_t *const thread, 64 const pthread_attr_t *const attr, 65 void *(*const func)(void*), void *const arg) 66 { 67 const unsigned stack_size = attr ? attr->stack_size : 0; 68 thread->func = func; 69 thread->arg = arg; 70 thread->h = (HANDLE)_beginthreadex(NULL, stack_size, thread_entrypoint, thread, 71 STACK_SIZE_PARAM_IS_A_RESERVATION, NULL); 72 return !thread->h; 73 } 74 75 COLD int dav1d_pthread_join(pthread_t *const thread, void **const res) { 76 if (WaitForSingleObject(thread->h, INFINITE)) 77 return 1; 78 79 if (res) 80 *res = thread->arg; 81 82 return !CloseHandle(thread->h); 83 } 84 85 COLD int dav1d_pthread_once(pthread_once_t *const once_control, 86 void (*const init_routine)(void)) 87 { 88 BOOL pending = FALSE; 89 90 if (InitOnceBeginInitialize(once_control, 0, &pending, NULL) != TRUE) 91 return 1; 92 93 if (pending == TRUE) 94 init_routine(); 95 96 return !InitOnceComplete(once_control, 0, NULL); 97 } 98 99 #endif