blob: af3109efd4601a3b68c2689aa99485517ab88282 [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 Rathnayake7250d332016-10-14 13:00:07 +000028#define _LIBCPP_HAS_EXTERNAL_THREADING_HEADER
Asiri Rathnayakef6600b72016-09-13 09:32:32 +000029#elif !defined(__has_include) || __has_include(<__external_threading>)
30#include <__external_threading>
Asiri Rathnayake7250d332016-10-14 13:00:07 +000031#define _LIBCPP_HAS_EXTERNAL_THREADING_HEADER
Asiri Rathnayakef6600b72016-09-13 09:32:32 +000032#endif
33#endif
34
Asiri Rathnayake7250d332016-10-14 13:00:07 +000035#if !defined(_LIBCPP_HAS_EXTERNAL_THREADING_HEADER)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000036#include <pthread.h>
37#include <sched.h>
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000038
Asiri Rathnayake040945b2016-09-11 21:46:40 +000039#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
40#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
41#else
42#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
43#endif
44
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000045_LIBCPP_BEGIN_NAMESPACE_STD
46
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000047// Mutex
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000048typedef pthread_mutex_t __libcpp_mutex_t;
Asiri Rathnayake040945b2016-09-11 21:46:40 +000049#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +000050
Asiri Rathnayake040945b2016-09-11 21:46:40 +000051_LIBCPP_THREAD_ABI_VISIBILITY
52int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
53_LIBCPP_THREAD_ABI_VISIBILITY
54int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
55_LIBCPP_THREAD_ABI_VISIBILITY
56int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
57_LIBCPP_THREAD_ABI_VISIBILITY
58int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
59_LIBCPP_THREAD_ABI_VISIBILITY
60int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
61
62// Condition variable
63typedef pthread_cond_t __libcpp_condvar_t;
64#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
65_LIBCPP_THREAD_ABI_VISIBILITY
66int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
67_LIBCPP_THREAD_ABI_VISIBILITY
68int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
69_LIBCPP_THREAD_ABI_VISIBILITY
70int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
71_LIBCPP_THREAD_ABI_VISIBILITY
72int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
73_LIBCPP_THREAD_ABI_VISIBILITY
74int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
75
76// Thread id
77typedef pthread_t __libcpp_thread_id;
78_LIBCPP_THREAD_ABI_VISIBILITY
79bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
80_LIBCPP_THREAD_ABI_VISIBILITY
81bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
82
83// Thread
84typedef pthread_t __libcpp_thread_t;
85_LIBCPP_THREAD_ABI_VISIBILITY
86int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
87_LIBCPP_THREAD_ABI_VISIBILITY
88__libcpp_thread_id __libcpp_thread_get_current_id();
89_LIBCPP_THREAD_ABI_VISIBILITY
90__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
91_LIBCPP_THREAD_ABI_VISIBILITY
92int __libcpp_thread_join(__libcpp_thread_t* __t);
93_LIBCPP_THREAD_ABI_VISIBILITY
94int __libcpp_thread_detach(__libcpp_thread_t* __t);
95_LIBCPP_THREAD_ABI_VISIBILITY
96void __libcpp_thread_yield();
97
98// Thread local storage
99typedef pthread_key_t __libcpp_tls_key;
100_LIBCPP_THREAD_ABI_VISIBILITY
101int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
102_LIBCPP_THREAD_ABI_VISIBILITY
103void* __libcpp_tls_get(__libcpp_tls_key __key);
104_LIBCPP_THREAD_ABI_VISIBILITY
105void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
106
107#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
108
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000109int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
110{
111 pthread_mutexattr_t attr;
112 int __ec = pthread_mutexattr_init(&attr);
113 if (__ec) return __ec;
114 __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
115 if (__ec)
116 {
117 pthread_mutexattr_destroy(&attr);
118 return __ec;
119 }
120 __ec = pthread_mutex_init(__m, &attr);
121 if (__ec)
122 {
123 pthread_mutexattr_destroy(&attr);
124 return __ec;
125 }
126 __ec = pthread_mutexattr_destroy(&attr);
127 if (__ec)
128 {
129 pthread_mutex_destroy(__m);
130 return __ec;
131 }
132 return 0;
133}
134
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000135int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
136{
137 return pthread_mutex_lock(__m);
138}
139
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000140int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
141{
142 return pthread_mutex_trylock(__m);
143}
144
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000145int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
146{
147 return pthread_mutex_unlock(__m);
148}
149
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000150int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
151{
152 return pthread_mutex_destroy(__m);
153}
154
155// Condition variable
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000156int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
157{
158 return pthread_cond_signal(__cv);
159}
160
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000161int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
162{
163 return pthread_cond_broadcast(__cv);
164}
165
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000166int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
167{
168 return pthread_cond_wait(__cv, __m);
169}
170
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000171int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
172{
173 return pthread_cond_timedwait(__cv, __m, __ts);
174}
175
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000176int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
177{
178 return pthread_cond_destroy(__cv);
179}
180
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000181// Returns non-zero if the thread ids are equal, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000182bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
183{
184 return pthread_equal(t1, t2) != 0;
185}
186
187// Returns non-zero if t1 < t2, otherwise 0
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000188bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
189{
190 return t1 < t2;
191}
192
193// Thread
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000194int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
195{
196 return pthread_create(__t, 0, __func, __arg);
197}
198
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000199__libcpp_thread_id __libcpp_thread_get_current_id()
200{
201 return pthread_self();
202}
203
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000204__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
205{
206 return *__t;
207}
208
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000209int __libcpp_thread_join(__libcpp_thread_t* __t)
210{
211 return pthread_join(*__t, 0);
212}
213
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000214int __libcpp_thread_detach(__libcpp_thread_t* __t)
215{
216 return pthread_detach(*__t);
217}
218
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000219void __libcpp_thread_yield()
220{
221 sched_yield();
222}
223
224// Thread local storage
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000225int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000226{
227 return pthread_key_create(__key, __at_exit);
228}
229
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000230void* __libcpp_tls_get(__libcpp_tls_key __key)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000231{
232 return pthread_getspecific(__key);
233}
234
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000235void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000236{
237 pthread_setspecific(__key, __p);
238}
239
Asiri Rathnayake040945b2016-09-11 21:46:40 +0000240#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000241
242_LIBCPP_END_NAMESPACE_STD
243
Asiri Rathnayake7250d332016-10-14 13:00:07 +0000244#endif // !_LIBCPP_HAS_EXTERNAL_THREADING_HEADER
245
Asiri Rathnayake35ff03b2016-05-06 14:06:29 +0000246#endif // _LIBCPP_HAS_NO_THREADS
247
248#endif // _LIBCPP_THREADING_SUPPORT