1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP_THREADING_SUPPORT
#define _LIBCPP_THREADING_SUPPORT
#include <__config>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
#pragma GCC system_header
#endif
#ifndef _LIBCPP_HAS_NO_THREADS
#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) && (!defined(__has_include) || __has_include(<__external_threading>))
#include <__external_threading>
#else
#include <pthread.h>
#include <sched.h>
#endif
#if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
#define _LIBCPP_THREAD_ABI_VISIBILITY _LIBCPP_FUNC_VIS
#else
#define _LIBCPP_THREAD_ABI_VISIBILITY inline _LIBCPP_INLINE_VISIBILITY
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
// Mutex
typedef pthread_mutex_t __libcpp_mutex_t;
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_lock(__libcpp_mutex_t* __m);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_trylock(__libcpp_mutex_t* __m);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_unlock(__libcpp_mutex_t* __m);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_mutex_destroy(__libcpp_mutex_t* __m);
// Condition variable
typedef pthread_cond_t __libcpp_condvar_t;
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv);
// Thread id
typedef pthread_t __libcpp_thread_id;
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2);
_LIBCPP_THREAD_ABI_VISIBILITY
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2);
// Thread
typedef pthread_t __libcpp_thread_t;
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg);
_LIBCPP_THREAD_ABI_VISIBILITY
__libcpp_thread_id __libcpp_thread_get_current_id();
_LIBCPP_THREAD_ABI_VISIBILITY
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_thread_join(__libcpp_thread_t* __t);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_thread_detach(__libcpp_thread_t* __t);
_LIBCPP_THREAD_ABI_VISIBILITY
void __libcpp_thread_yield();
// Thread local storage
typedef pthread_key_t __libcpp_tls_key;
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*));
_LIBCPP_THREAD_ABI_VISIBILITY
void* __libcpp_tls_get(__libcpp_tls_key __key);
_LIBCPP_THREAD_ABI_VISIBILITY
void __libcpp_tls_set(__libcpp_tls_key __key, void* __p);
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) || defined(_LIBCPP_BUILDING_EXTERNAL_THREADS)
int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
{
pthread_mutexattr_t attr;
int __ec = pthread_mutexattr_init(&attr);
if (__ec) return __ec;
__ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
if (__ec)
{
pthread_mutexattr_destroy(&attr);
return __ec;
}
__ec = pthread_mutex_init(__m, &attr);
if (__ec)
{
pthread_mutexattr_destroy(&attr);
return __ec;
}
__ec = pthread_mutexattr_destroy(&attr);
if (__ec)
{
pthread_mutex_destroy(__m);
return __ec;
}
return 0;
}
int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
{
return pthread_mutex_lock(__m);
}
int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
{
return pthread_mutex_trylock(__m);
}
int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
{
return pthread_mutex_unlock(__m);
}
int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
{
return pthread_mutex_destroy(__m);
}
// Condition variable
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
{
return pthread_cond_signal(__cv);
}
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
{
return pthread_cond_broadcast(__cv);
}
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
{
return pthread_cond_wait(__cv, __m);
}
int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
{
return pthread_cond_timedwait(__cv, __m, __ts);
}
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
{
return pthread_cond_destroy(__cv);
}
// Returns non-zero if the thread ids are equal, otherwise 0
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return pthread_equal(t1, t2) != 0;
}
// Returns non-zero if t1 < t2, otherwise 0
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
{
return t1 < t2;
}
// Thread
int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
{
return pthread_create(__t, 0, __func, __arg);
}
__libcpp_thread_id __libcpp_thread_get_current_id()
{
return pthread_self();
}
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
{
return *__t;
}
int __libcpp_thread_join(__libcpp_thread_t* __t)
{
return pthread_join(*__t, 0);
}
int __libcpp_thread_detach(__libcpp_thread_t* __t)
{
return pthread_detach(*__t);
}
void __libcpp_thread_yield()
{
sched_yield();
}
// Thread local storage
int __libcpp_tls_create(__libcpp_tls_key* __key, void (*__at_exit)(void*))
{
return pthread_key_create(__key, __at_exit);
}
void* __libcpp_tls_get(__libcpp_tls_key __key)
{
return pthread_getspecific(__key);
}
void __libcpp_tls_set(__libcpp_tls_key __key, void* __p)
{
pthread_setspecific(__key, __p);
}
#endif // _LIBCPP_HAS_THREAD_API_PTHREAD || _LIBCPP_BUILDING_EXTERNAL_THREADS
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_HAS_NO_THREADS
#endif // _LIBCPP_THREADING_SUPPORT
|