Monado OpenXR Runtime
os_threading.h
Go to the documentation of this file.
1 // Copyright 2019, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Wrapper around OS threading native functions.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  *
8  * @ingroup aux_os
9  */
10 
11 #include "xrt/xrt_config_os.h"
12 #include "util/u_misc.h"
13 
14 #ifdef XRT_OS_LINUX
15 #include <pthread.h>
16 #else
17 #error "OS not supported"
18 #endif
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23 
24 
25 /*!
26  * @ingroup aux_os
27  * @{
28  */
29 
30 /*
31  *
32  * Mutex
33  *
34  */
35 
36 /*!
37  * A wrapper around a native mutex.
38  */
39 struct os_mutex
40 {
41  pthread_mutex_t mutex;
42 };
43 
44 /*!
45  * Init.
46  */
47 static inline int
48 os_mutex_init(struct os_mutex *om)
49 {
50  return pthread_mutex_init(&om->mutex, NULL);
51 }
52 
53 /*!
54  * Lock.
55  */
56 static inline void
57 os_mutex_lock(struct os_mutex *om)
58 {
59  pthread_mutex_lock(&om->mutex);
60 }
61 
62 /*!
63  * Unlock.
64  */
65 static inline void
66 os_mutex_unlock(struct os_mutex *om)
67 {
68  pthread_mutex_unlock(&om->mutex);
69 }
70 
71 /*!
72  * Clean up.
73  */
74 static inline void
75 os_mutex_destroy(struct os_mutex *om)
76 {
77  pthread_mutex_destroy(&om->mutex);
78 }
79 
80 
81 /*
82  *
83  * Thread.
84  *
85  */
86 
87 
88 /*!
89  * A wrapper around a native mutex.
90  */
91 struct os_thread
92 {
93  pthread_t thread;
94 };
95 
96 /*!
97  * Run function.
98  */
99 typedef void *(*os_run_func)(void *);
100 
101 /*!
102  * Init.
103  */
104 static inline int
105 os_thread_init(struct os_thread *ost)
106 {
107  return 0;
108 }
109 
110 /*!
111  * Start thread.
112  */
113 static inline int
114 os_thread_start(struct os_thread *ost, os_run_func func, void *ptr)
115 {
116  return pthread_create(&ost->thread, NULL, func, ptr);
117 }
118 
119 /*!
120  * Join.
121  */
122 static inline void
123 os_thread_join(struct os_thread *ost)
124 {
125  void *retval;
126 
127  pthread_join(ost->thread, &retval);
128  U_ZERO(&ost->thread);
129 }
130 
131 /*!
132  * Destruction.
133  */
134 static inline void
135 os_thread_destroy(struct os_thread *ost)
136 {}
137 
138 
139 /*
140  *
141  * Fancy helper.
142  *
143  */
144 
145 /*!
146  * All in one helper that handles locking, waiting for change and starting a
147  * thread.
148  */
150 {
151  pthread_t thread;
152  pthread_mutex_t mutex;
153  pthread_cond_t cond;
154 
155  bool running;
156 };
157 
158 /*!
159  * Initialize the thread helper.
160  */
161 static inline int
162 os_thread_helper_init(struct os_thread_helper *oth)
163 {
164  int ret = pthread_mutex_init(&oth->mutex, NULL);
165  if (ret != 0) {
166  return ret;
167  }
168 
169  ret = pthread_cond_init(&oth->cond, NULL);
170  if (ret) {
171  pthread_mutex_destroy(&oth->mutex);
172  return ret;
173  }
174 
175  return 0;
176 }
177 
178 /*!
179  * Start the internal thread.
180  */
181 static inline int
182 os_thread_helper_start(struct os_thread_helper *oth,
183  os_run_func func,
184  void *ptr)
185 {
186  pthread_mutex_lock(&oth->mutex);
187 
188  if (oth->running) {
189  pthread_mutex_unlock(&oth->mutex);
190  return -1;
191  }
192 
193  int ret = pthread_create(&oth->thread, NULL, func, ptr);
194  if (ret != 0) {
195  pthread_mutex_unlock(&oth->mutex);
196  return ret;
197  }
198 
199  oth->running = true;
200 
201  pthread_mutex_unlock(&oth->mutex);
202 
203  return 0;
204 }
205 
206 /*!
207  * Stop the thread.
208  */
209 static inline int
210 os_thread_helper_stop(struct os_thread_helper *oth)
211 {
212  void *retval = NULL;
213 
214  // The fields are protected.
215  pthread_mutex_lock(&oth->mutex);
216 
217  if (!oth->running) {
218  pthread_mutex_unlock(&oth->mutex);
219  return 0;
220  }
221 
222  // Stop the thread.
223  oth->running = false;
224 
225  // Wake up the thread if it is waiting.
226  pthread_cond_signal(&oth->cond);
227 
228  // No longer need to protect fields.
229  pthread_mutex_unlock(&oth->mutex);
230 
231  // Wait for thread to finish.
232  pthread_join(oth->thread, &retval);
233 
234  return 0;
235 }
236 
237 /*!
238  * Destroy the thread helper, externally syncronizable.
239  */
240 static inline void
241 os_thread_helper_destroy(struct os_thread_helper *oth)
242 {
243  // Stop the thread.
244  os_thread_helper_stop(oth);
245 
246  // Destroy resources.
247  pthread_mutex_destroy(&oth->mutex);
248  pthread_cond_destroy(&oth->cond);
249 }
250 
251 /*!
252  * Lock the helper.
253  */
254 static inline void
255 os_thread_helper_lock(struct os_thread_helper *oth)
256 {
257  pthread_mutex_lock(&oth->mutex);
258 }
259 
260 /*!
261  * Unlock the helper.
262  */
263 static inline void
264 os_thread_helper_unlock(struct os_thread_helper *oth)
265 {
266  pthread_mutex_unlock(&oth->mutex);
267 }
268 
269 /*!
270  * Is the thread running, or suppised to be running.
271  *
272  * Must be called with the helper locked.
273  */
274 static inline bool
275 os_thread_helper_is_running_locked(struct os_thread_helper *oth)
276 {
277  return oth->running;
278 }
279 
280 /*!
281  * Wait for a signal.
282  *
283  * Must be called with the helper locked.
284  */
285 static inline void
286 os_thread_helper_wait_locked(struct os_thread_helper *oth)
287 {
288  pthread_cond_wait(&oth->cond, &oth->mutex);
289 }
290 
291 /*!
292  * Signal a waiting thread to wake up.
293  *
294  * Must be called with the helper locked.
295  */
296 static inline void
297 os_thread_helper_signal_locked(struct os_thread_helper *oth)
298 {
299  pthread_cond_signal(&oth->cond);
300 }
301 
302 
303 /*!
304  * @}
305  */
306 
307 
308 #ifdef __cplusplus
309 } // extern "C"
310 #endif
Auto detect OS and certain features.
All in one helper that handles locking, waiting for change and starting a thread. ...
Definition: os_threading.h:149
#define U_ZERO(PTR)
Zeroes the correct amount of memory based on the type pointed-to by the argument. ...
Definition: u_misc.h:61
A wrapper around a native mutex.
Definition: os_threading.h:39
A wrapper around a native mutex.
Definition: os_threading.h:91
Very small misc utils.
void *(* os_run_func)(void *)
Run function.
Definition: os_threading.h:99