1 // Copyright © Tavian Barnes <tavianator@tavianator.com>
2 // SPDX-License-Identifier: 0BSD
5 * Wrappers for POSIX threading APIs.
18 #if __STDC_VERSION__ < 202311L && !defined(thread_local)
19 # if BFS_USE_THREADS_H
22 # define thread_local _Thread_local
26 #define thread_verify(expr, cond) \
27 bfs_verify((errno = (expr), (cond)), "%s: %s", #expr, xstrerror(errno))
30 * Wrapper for pthread_create().
33 * 0 on success, -1 on error.
35 #define thread_create(thread, attr, fn, arg) \
36 ((errno = pthread_create(thread, attr, fn, arg)) ? -1 : 0)
39 * Wrapper for pthread_join().
41 #define thread_join(thread, ret) \
42 thread_verify(pthread_join(thread, ret), errno == 0)
45 * Wrapper for pthread_mutex_init().
47 #define mutex_init(mutex, attr) \
48 ((errno = pthread_mutex_init(mutex, attr)) ? -1 : 0)
51 * Wrapper for pthread_mutex_lock().
53 #define mutex_lock(mutex) \
54 thread_verify(pthread_mutex_lock(mutex), errno == 0)
57 * Wrapper for pthread_mutex_trylock().
60 * Whether the mutex was locked.
62 #define mutex_trylock(mutex) \
63 (thread_verify(pthread_mutex_trylock(mutex), errno == 0 || errno == EBUSY), errno == 0)
66 * Wrapper for pthread_mutex_unlock().
68 #define mutex_unlock(mutex) \
69 thread_verify(pthread_mutex_unlock(mutex), errno == 0)
72 * Wrapper for pthread_mutex_destroy().
74 #define mutex_destroy(mutex) \
75 thread_verify(pthread_mutex_destroy(mutex), errno == 0)
78 * Wrapper for pthread_cond_init().
80 #define cond_init(cond, attr) \
81 ((errno = pthread_cond_init(cond, attr)) ? -1 : 0)
84 * Wrapper for pthread_cond_wait().
86 #define cond_wait(cond, mutex) \
87 thread_verify(pthread_cond_wait(cond, mutex), errno == 0)
90 * Wrapper for pthread_cond_signal().
92 #define cond_signal(cond) \
93 thread_verify(pthread_cond_signal(cond), errno == 0)
96 * Wrapper for pthread_cond_broadcast().
98 #define cond_broadcast(cond) \
99 thread_verify(pthread_cond_broadcast(cond), errno == 0)
102 * Wrapper for pthread_cond_destroy().
104 #define cond_destroy(cond) \
105 thread_verify(pthread_cond_destroy(cond), errno == 0)
108 * Wrapper for pthread_once().
110 #define invoke_once(once, fn) \
111 thread_verify(pthread_once(once, fn), errno == 0)
113 #endif // BFS_THREAD_H