2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_THREADING_SUPPORT
12 #define _LIBCPP_THREADING_SUPPORT
16 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17 #pragma GCC system_header
20 #ifndef _LIBCPP_HAS_NO_THREADS
22 #ifndef __libcpp_has_include
24 #define __libcpp_has_include(x) 0
26 #define __libcpp_has_include(x) __has_include(x)
30 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
31 __libcpp_has_include(<__external_threading>)
32 #include <__external_threading>
37 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
38 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
40 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
43 _LIBCPP_BEGIN_NAMESPACE_STD
46 typedef pthread_mutex_t __libcpp_mutex_t;
47 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
49 _LIBCPP_THREAD_ABI_VISIBILITY
50 int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
51 _LIBCPP_THREAD_ABI_VISIBILITY
52 int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
53 _LIBCPP_THREAD_ABI_VISIBILITY
54 int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
55 _LIBCPP_THREAD_ABI_VISIBILITY
56 int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
57 _LIBCPP_THREAD_ABI_VISIBILITY
58 int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
61 typedef pthread_cond_t __libcpp_condvar_t;
62 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
63 _LIBCPP_THREAD_ABI_VISIBILITY
64 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
65 _LIBCPP_THREAD_ABI_VISIBILITY
66 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
67 _LIBCPP_THREAD_ABI_VISIBILITY
68 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
69 _LIBCPP_THREAD_ABI_VISIBILITY
70 int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
71 _LIBCPP_THREAD_ABI_VISIBILITY
72 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
75 typedef pthread_t __libcpp_thread_id;
76 _LIBCPP_THREAD_ABI_VISIBILITY
77 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
78 _LIBCPP_THREAD_ABI_VISIBILITY
79 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
82 typedef pthread_t __libcpp_thread_t;
83 _LIBCPP_THREAD_ABI_VISIBILITY
84 int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
85 _LIBCPP_THREAD_ABI_VISIBILITY
86 __libcpp_thread_id __libcpp_thread_get_current_id();
87 _LIBCPP_THREAD_ABI_VISIBILITY
88 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
89 _LIBCPP_THREAD_ABI_VISIBILITY
90 int __libcpp_thread_join(__libcpp_thread_t* __t);
91 _LIBCPP_THREAD_ABI_VISIBILITY
92 int __libcpp_thread_detach(__libcpp_thread_t* __t);
93 _LIBCPP_THREAD_ABI_VISIBILITY
94 void __libcpp_thread_yield();
96 // Thread local storage
97 typedef pthread_key_t __libcpp_tls_key;
98 _LIBCPP_THREAD_ABI_VISIBILITY
99 int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
100 _LIBCPP_THREAD_ABI_VISIBILITY
101 void* __libcpp_tls_get(__libcpp_tls_key __key);
102 _LIBCPP_THREAD_ABI_VISIBILITY
103 void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
105 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
107 int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
109 pthread_mutexattr_t attr;
110 int __ec = pthread_mutexattr_init(&attr);
111 if (__ec) return __ec;
112 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
115 pthread_mutexattr_destroy(&attr);
118 __ec = pthread_mutex_init(__m, &attr);
121 pthread_mutexattr_destroy(&attr);
124 __ec = pthread_mutexattr_destroy(&attr);
127 pthread_mutex_destroy(__m);
133 int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
135 return pthread_mutex_lock(__m);
138 int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
140 return pthread_mutex_trylock(__m);
143 int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
145 return pthread_mutex_unlock(__m);
148 int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
150 return pthread_mutex_destroy(__m);
153 // Condition variable
154 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
156 return pthread_cond_signal(__cv);
159 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
161 return pthread_cond_broadcast(__cv);
164 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
166 return pthread_cond_wait(__cv, __m);
169 int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
171 return pthread_cond_timedwait(__cv, __m, __ts);
174 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
176 return pthread_cond_destroy(__cv);
179 // Returns non-zero if the thread ids are equal, otherwise 0
180 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
182 return pthread_equal(t1, t2) != 0;
185 // Returns non-zero if t1 < t2, otherwise 0
186 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
192 int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
194 return pthread_create(__t, 0, __func, __arg);
197 __libcpp_thread_id __libcpp_thread_get_current_id()
199 return pthread_self();
202 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
207 int __libcpp_thread_join(__libcpp_thread_t* __t)
209 return pthread_join(*__t, 0);
212 int __libcpp_thread_detach(__libcpp_thread_t* __t)
214 return pthread_detach(*__t);
217 void __libcpp_thread_yield()
222 // Thread local storage
223 int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
225 return pthread_key_create(__key, __at_exit);
228 void* __libcpp_tls_get(__libcpp_tls_key __key)
230 return pthread_getspecific(__key);
233 void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
235 pthread_setspecific(__key, __p);
238 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
240 _LIBCPP_END_NAMESPACE_STD
242 #endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
244 #endif // _LIBCPP_HAS_NO_THREADS
246 #endif // _LIBCPP_THREADING_SUPPORT