blob: 86dc8c7be825b3d5e5dd17ee822646d18378c881 [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 Rathnayakef6600b72016-09-13 09:32:32 +000022// These checks are carefully arranged so as not to trigger a gcc pre-processor
23// defect which causes it to fail to parse the __has_include check below, the
24// redundancy is intentional.
25#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
26#if !defined(__clang__) && (_GNUC_VER < 500)
Asiri Rathnayake040945b2016-09-11 21:46:40 +000027#include <__external_threading>
Asiri Rathnayakef6600b72016-09-13 09:32:32 +000028#define _LIBCPP_EXTERNAL_THREADING
29#elif !defined(__has_include) || __has_include(<__external_threading>)
30#include <__external_threading>
31#define _LIBCPP_EXTERNAL_THREADING
32#endif
33#endif
34
35#if !defined(_LIBCPP_EXTERNAL_THREADING)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000036#include <pthread.h>
37#include <sched.h>
38#endif
39
Asiri Rathnayake040945b2016-09-11 21:46:40 +000040#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
41#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
42#else
43#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
44#endif
45
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000046_LIBCPP_BEGIN_NAMESPACE_STD
47
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000048// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000049typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000050#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000051
Asiri Rathnayake040945b2016-09-11 21:46:40 +000052_LIBCPP_THREAD_ABI_VISIBILITY
53int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
54_LIBCPP_THREAD_ABI_VISIBILITY
55int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
56_LIBCPP_THREAD_ABI_VISIBILITY
57int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
58_LIBCPP_THREAD_ABI_VISIBILITY
59int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
60_LIBCPP_THREAD_ABI_VISIBILITY
61int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
62
63// Condition variable
64typedef pthread_cond_t __libcpp_condvar_t;
65#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
66_LIBCPP_THREAD_ABI_VISIBILITY
67int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
68_LIBCPP_THREAD_ABI_VISIBILITY
69int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
70_LIBCPP_THREAD_ABI_VISIBILITY
71int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
72_LIBCPP_THREAD_ABI_VISIBILITY
73int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
74_LIBCPP_THREAD_ABI_VISIBILITY
75int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
76
77// Thread id
78typedef pthread_t __libcpp_thread_id;
79_LIBCPP_THREAD_ABI_VISIBILITY
80bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
81_LIBCPP_THREAD_ABI_VISIBILITY
82bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
83
84// Thread
85typedef pthread_t __libcpp_thread_t;
86_LIBCPP_THREAD_ABI_VISIBILITY
87int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
88_LIBCPP_THREAD_ABI_VISIBILITY
89__libcpp_thread_id __libcpp_thread_get_current_id();
90_LIBCPP_THREAD_ABI_VISIBILITY
91__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
92_LIBCPP_THREAD_ABI_VISIBILITY
93int __libcpp_thread_join(__libcpp_thread_t* __t);
94_LIBCPP_THREAD_ABI_VISIBILITY
95int __libcpp_thread_detach(__libcpp_thread_t* __t);
96_LIBCPP_THREAD_ABI_VISIBILITY
97void __libcpp_thread_yield();
98
99// Thread local storage
100typedef pthread_key_t __libcpp_tls_key;
101_LIBCPP_THREAD_ABI_VISIBILITY
102int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
103_LIBCPP_THREAD_ABI_VISIBILITY
104void* __libcpp_tls_get(__libcpp_tls_key __key);
105_LIBCPP_THREAD_ABI_VISIBILITY
106void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
107
108#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
109
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000110int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
111{
112 pthread_mutexattr_t attr;
113 int __ec = pthread_mutexattr_init(&attr);
114 if (__ec) return __ec;
115 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
116 if (__ec)
117 {
118 pthread_mutexattr_destroy(&attr);
119 return __ec;
120 }
121 __ec = pthread_mutex_init(__m, &attr);
122 if (__ec)
123 {
124 pthread_mutexattr_destroy(&attr);
125 return __ec;
126 }
127 __ec = pthread_mutexattr_destroy(&attr);
128 if (__ec)
129 {
130 pthread_mutex_destroy(__m);
131 return __ec;
132 }
133 return 0;
134}
135
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000136int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
137{
138 return pthread_mutex_lock(__m);
139}
140
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000141int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
142{
143 return pthread_mutex_trylock(__m);
144}
145
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000146int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
147{
148 return pthread_mutex_unlock(__m);
149}
150
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000151int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
152{
153 return pthread_mutex_destroy(__m);
154}
155
156// Condition variable
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000157int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
158{
159 return pthread_cond_signal(__cv);
160}
161
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000162int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
163{
164 return pthread_cond_broadcast(__cv);
165}
166
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000167int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
168{
169 return pthread_cond_wait(__cv, __m);
170}
171
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000172int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
173{
174 return pthread_cond_timedwait(__cv, __m, __ts);
175}
176
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000177int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
178{
179 return pthread_cond_destroy(__cv);
180}
181
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000182// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000183bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
184{
185 return pthread_equal(t1, t2) != 0;
186}
187
188// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000189bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
190{
191 return t1 < t2;
192}
193
194// Thread
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000195int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
196{
197 return pthread_create(__t, 0, __func, __arg);
198}
199
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000200__libcpp_thread_id __libcpp_thread_get_current_id()
201{
202 return pthread_self();
203}
204
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000205__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
206{
207 return *__t;
208}
209
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000210int __libcpp_thread_join(__libcpp_thread_t* __t)
211{
212 return pthread_join(*__t, 0);
213}
214
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000215int __libcpp_thread_detach(__libcpp_thread_t* __t)
216{
217 return pthread_detach(*__t);
218}
219
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000220void __libcpp_thread_yield()
221{
222 sched_yield();
223}
224
225// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000226int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000227{
228 return pthread_key_create(__key, __at_exit);
229}
230
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000231void* __libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000232{
233 return pthread_getspecific(__key);
234}
235
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000236void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000237{
238 pthread_setspecific(__key, __p);
239}
240
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000241#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000242
243_LIBCPP_END_NAMESPACE_STD
244
245#endif // _LIBCPP_HAS_NO_THREADS
246
247#endif // _LIBCPP_THREADING_SUPPORT