blob: 36f1701f178cf6077b15e55d221d3a97685a6357 [file] [log] [blame]
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +00001// -*- 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
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +000022#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
Asiri Rathnayakef6600b72016-09-13 09:32:32 +000028#endif
29
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +000030#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && \
31 __libcpp_has_include(<__external_threading>)
32#include <__external_threading>
33#else
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000034#include <pthread.h>
35#include <sched.h>
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000036
Asiri Rathnayake040945b2016-09-11 21:46:40 +000037#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
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000043_LIBCPP_BEGIN_NAMESPACE_STD
44
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000045// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000046typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000047#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000048
Asiri Rathnayake040945b2016-09-11 21:46:40 +000049_LIBCPP_THREAD_ABI_VISIBILITY
50int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
51_LIBCPP_THREAD_ABI_VISIBILITY
52int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
53_LIBCPP_THREAD_ABI_VISIBILITY
54int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
55_LIBCPP_THREAD_ABI_VISIBILITY
56int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
57_LIBCPP_THREAD_ABI_VISIBILITY
58int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
59
60// Condition variable
61typedef pthread_cond_t __libcpp_condvar_t;
62#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
63_LIBCPP_THREAD_ABI_VISIBILITY
64int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
65_LIBCPP_THREAD_ABI_VISIBILITY
66int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
67_LIBCPP_THREAD_ABI_VISIBILITY
68int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
69_LIBCPP_THREAD_ABI_VISIBILITY
70int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
71_LIBCPP_THREAD_ABI_VISIBILITY
72int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
73
74// Thread id
75typedef pthread_t __libcpp_thread_id;
76_LIBCPP_THREAD_ABI_VISIBILITY
77bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
78_LIBCPP_THREAD_ABI_VISIBILITY
79bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
80
81// Thread
82typedef pthread_t __libcpp_thread_t;
83_LIBCPP_THREAD_ABI_VISIBILITY
84int __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
90int __libcpp_thread_join(__libcpp_thread_t* __t);
91_LIBCPP_THREAD_ABI_VISIBILITY
92int __libcpp_thread_detach(__libcpp_thread_t* __t);
93_LIBCPP_THREAD_ABI_VISIBILITY
94void __libcpp_thread_yield();
95
96// Thread local storage
97typedef pthread_key_t __libcpp_tls_key;
98_LIBCPP_THREAD_ABI_VISIBILITY
99int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
100_LIBCPP_THREAD_ABI_VISIBILITY
101void* __libcpp_tls_get(__libcpp_tls_key __key);
102_LIBCPP_THREAD_ABI_VISIBILITY
103void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
104
105#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
106
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000107int __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
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000133int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
134{
135 return pthread_mutex_lock(__m);
136}
137
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000138int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
139{
140 return pthread_mutex_trylock(__m);
141}
142
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000143int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
144{
145 return pthread_mutex_unlock(__m);
146}
147
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000148int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
149{
150 return pthread_mutex_destroy(__m);
151}
152
153// Condition variable
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000154int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
155{
156 return pthread_cond_signal(__cv);
157}
158
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000159int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
160{
161 return pthread_cond_broadcast(__cv);
162}
163
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000164int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
165{
166 return pthread_cond_wait(__cv, __m);
167}
168
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000169int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
170{
171 return pthread_cond_timedwait(__cv, __m, __ts);
172}
173
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000174int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
175{
176 return pthread_cond_destroy(__cv);
177}
178
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000179// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000180bool __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
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000186bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
187{
188 return t1 < t2;
189}
190
191// Thread
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000192int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
193{
194 return pthread_create(__t, 0, __func, __arg);
195}
196
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000197__libcpp_thread_id __libcpp_thread_get_current_id()
198{
199 return pthread_self();
200}
201
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000202__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
203{
204 return *__t;
205}
206
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000207int __libcpp_thread_join(__libcpp_thread_t* __t)
208{
209 return pthread_join(*__t, 0);
210}
211
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000212int __libcpp_thread_detach(__libcpp_thread_t* __t)
213{
214 return pthread_detach(*__t);
215}
216
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000217void __libcpp_thread_yield()
218{
219 sched_yield();
220}
221
222// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000223int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000224{
225 return pthread_key_create(__key, __at_exit);
226}
227
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000228void* __libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000229{
230 return pthread_getspecific(__key);
231}
232
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000233void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000234{
235 pthread_setspecific(__key, __p);
236}
237
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000238#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000239
240_LIBCPP_END_NAMESPACE_STD
241
Asiri Rathnayake4f2c83f2016-10-14 13:56:58 +0000242#endif // !_LIBCPP_HAS_THREAD_API_EXTERNAL || !__libcpp_has_include(<__external_threading>)
Asiri Rathnayake7250d332016-10-14 13:00:07 +0000243
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000244#endif // _LIBCPP_HAS_NO_THREADS
245
246#endif // _LIBCPP_THREADING_SUPPORT