]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/__threading_support
Vendor import of libc++ trunk r290819:
[FreeBSD/FreeBSD.git] / include / __threading_support
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _LIBCPP_THREADING_SUPPORT
12 #define _LIBCPP_THREADING_SUPPORT
13
14 #include <__config>
15
16 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17 #pragma GCC system_header
18 #endif
19
20 #ifndef _LIBCPP_HAS_NO_THREADS
21
22 #ifndef __libcpp_has_include
23   #ifndef __has_include
24     #define __libcpp_has_include(x) 0
25   #else
26     #define __libcpp_has_include(x) __has_include(x)
27   #endif
28 #endif
29
30 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
31     __libcpp_has_include(<__external_threading>)
32 #include <__external_threading>
33 #else
34 #include <pthread.h>
35 #include <sched.h>
36
37 #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
38 #define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
39 #else
40 #define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
41 #endif
42
43 _LIBCPP_BEGIN_NAMESPACE_STD
44
45 // Mutex
46 typedef pthread_mutex_t __libcpp_mutex_t;
47 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
48
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);
59
60 // Condition variable
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);
73
74 // Thread id
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);
80
81 // Thread
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();
95
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);
104
105 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
106
107 int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
108 {
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);
113     if (__ec)
114     {
115         pthread_mutexattr_destroy(&attr);
116         return __ec;
117     }
118     __ec = pthread_mutex_init(__m, &attr);
119     if (__ec)
120     {
121         pthread_mutexattr_destroy(&attr);
122         return __ec;
123     }
124     __ec = pthread_mutexattr_destroy(&attr);
125     if (__ec)
126     {
127         pthread_mutex_destroy(__m);
128         return __ec;
129     }
130     return 0;
131 }
132
133 int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
134 {
135     return pthread_mutex_lock(__m);
136 }
137
138 int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
139 {
140     return pthread_mutex_trylock(__m);
141 }
142
143 int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
144 {
145     return pthread_mutex_unlock(__m);
146 }
147
148 int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
149 {
150     return pthread_mutex_destroy(__m);
151 }
152
153 // Condition variable
154 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
155 {
156     return pthread_cond_signal(__cv);
157 }
158
159 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
160 {
161     return pthread_cond_broadcast(__cv);
162 }
163
164 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
165 {
166     return pthread_cond_wait(__cv, __m);
167 }
168
169 int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
170 {
171     return pthread_cond_timedwait(__cv, __m, __ts);
172 }
173
174 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
175 {
176     return pthread_cond_destroy(__cv);
177 }
178
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)
181 {
182     return pthread_equal(t1, t2) != 0;
183 }
184
185 // Returns non-zero if t1 < t2, otherwise 0
186 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
187 {
188     return t1 < t2;
189 }
190
191 // Thread
192 int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
193 {
194     return pthread_create(__t, 0, __func, __arg);
195 }
196
197 __libcpp_thread_id __libcpp_thread_get_current_id()
198 {
199     return pthread_self();
200 }
201
202 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
203 {
204     return *__t;
205 }
206
207 int __libcpp_thread_join(__libcpp_thread_t* __t)
208 {
209     return pthread_join(*__t, 0);
210 }
211
212 int __libcpp_thread_detach(__libcpp_thread_t* __t)
213 {
214     return pthread_detach(*__t);
215 }
216
217 void __libcpp_thread_yield()
218 {
219     sched_yield();
220 }
221
222 // Thread local storage
223 int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
224 {
225     return pthread_key_create(__key, __at_exit);
226 }
227
228 void* __libcpp_tls_get(__libcpp_tls_key __key)
229 {
230     return pthread_getspecific(__key);
231 }
232
233 void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
234 {
235     pthread_setspecific(__key, __p);
236 }
237
238 #endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
239
240 _LIBCPP_END_NAMESPACE_STD
241
242 #endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
243
244 #endif // _LIBCPP_HAS_NO_THREADS
245
246 #endif // _LIBCPP_THREADING_SUPPORT