xref: /aosp_15_r20/external/libdav1d/src/thread.h (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
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 
pthread_attr_init(pthread_attr_t * const attr)67 static inline int pthread_attr_init(pthread_attr_t *const attr) {
68     attr->stack_size = 0;
69     return 0;
70 }
71 
pthread_attr_destroy(pthread_attr_t * const attr)72 static inline int pthread_attr_destroy(pthread_attr_t *const attr) {
73     return 0;
74 }
75 
pthread_attr_setstacksize(pthread_attr_t * const attr,const size_t stack_size)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 
pthread_mutex_init(pthread_mutex_t * const mutex,const void * const attr)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 
pthread_mutex_destroy(pthread_mutex_t * const mutex)91 static inline int pthread_mutex_destroy(pthread_mutex_t *const mutex) {
92     return 0;
93 }
94 
pthread_mutex_lock(pthread_mutex_t * const mutex)95 static inline int pthread_mutex_lock(pthread_mutex_t *const mutex) {
96     AcquireSRWLockExclusive(mutex);
97     return 0;
98 }
99 
pthread_mutex_unlock(pthread_mutex_t * const mutex)100 static inline int pthread_mutex_unlock(pthread_mutex_t *const mutex) {
101     ReleaseSRWLockExclusive(mutex);
102     return 0;
103 }
104 
pthread_cond_init(pthread_cond_t * const cond,const void * const attr)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 
pthread_cond_destroy(pthread_cond_t * const cond)112 static inline int pthread_cond_destroy(pthread_cond_t *const cond) {
113     return 0;
114 }
115 
pthread_cond_wait(pthread_cond_t * const cond,pthread_mutex_t * const mutex)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 
pthread_cond_signal(pthread_cond_t * const cond)122 static inline int pthread_cond_signal(pthread_cond_t *const cond) {
123     WakeConditionVariable(cond);
124     return 0;
125 }
126 
pthread_cond_broadcast(pthread_cond_t * const cond)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 
dav1d_set_thread_name(const char * const name)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 
dav1d_set_thread_name(const char * const name)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 
dav1d_set_thread_name(const char * const name)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 
dav1d_set_thread_name(const char * const name)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 
dav1d_set_thread_name(const char * const name)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 
dav1d_set_thread_name(const char * const name)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 */
197