]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libc++/include/__threading_support
Update clang to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / libc++ / 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 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
23 #include <pthread.h>
24 #include <sched.h>
25 #endif
26
27 _LIBCPP_BEGIN_NAMESPACE_STD
28
29 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
30
31 // Mutex
32 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
33 typedef pthread_mutex_t __libcpp_mutex_t;
34
35 inline _LIBCPP_ALWAYS_INLINE
36 int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
37 {
38     pthread_mutexattr_t attr;
39     int __ec = pthread_mutexattr_init(&attr);
40     if (__ec) return __ec;
41     __ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
42     if (__ec)
43     {
44         pthread_mutexattr_destroy(&attr);
45         return __ec;
46     }
47     __ec = pthread_mutex_init(__m, &attr);
48     if (__ec)
49     {
50         pthread_mutexattr_destroy(&attr);
51         return __ec;
52     }
53     __ec = pthread_mutexattr_destroy(&attr);
54     if (__ec)
55     {
56         pthread_mutex_destroy(__m);
57         return __ec;
58     }
59     return 0;
60 }
61
62 inline _LIBCPP_ALWAYS_INLINE
63 int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
64 {
65     return pthread_mutex_lock(__m);
66 }
67
68 inline _LIBCPP_ALWAYS_INLINE
69 int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
70 {
71     return pthread_mutex_trylock(__m);
72 }
73
74 inline _LIBCPP_ALWAYS_INLINE
75 int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
76 {
77     return pthread_mutex_unlock(__m);
78 }
79
80 inline _LIBCPP_ALWAYS_INLINE
81 int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
82 {
83     return pthread_mutex_destroy(__m);
84 }
85
86 // Condition variable
87 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
88 typedef pthread_cond_t __libcpp_condvar_t;
89
90 inline _LIBCPP_ALWAYS_INLINE
91 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
92 {
93     return pthread_cond_signal(__cv);
94 }
95
96 inline _LIBCPP_ALWAYS_INLINE
97 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
98 {
99     return pthread_cond_broadcast(__cv);
100 }
101
102 inline _LIBCPP_ALWAYS_INLINE
103 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
104 {
105     return pthread_cond_wait(__cv, __m);
106 }
107
108 inline _LIBCPP_ALWAYS_INLINE
109 int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
110 {
111     return pthread_cond_timedwait(__cv, __m, __ts);
112 }
113
114 inline _LIBCPP_ALWAYS_INLINE
115 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
116 {
117     return pthread_cond_destroy(__cv);
118 }
119
120 // Thread id
121 typedef pthread_t __libcpp_thread_id;
122
123 // Returns non-zero if the thread ids are equal, otherwise 0
124 inline _LIBCPP_ALWAYS_INLINE
125 bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
126 {
127     return pthread_equal(t1, t2) != 0;
128 }
129
130 // Returns non-zero if t1 < t2, otherwise 0
131 inline _LIBCPP_ALWAYS_INLINE
132 bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
133 {
134     return t1 < t2;
135 }
136
137 // Thread
138 typedef pthread_t __libcpp_thread_t;
139
140 inline _LIBCPP_ALWAYS_INLINE
141 int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
142 {
143     return pthread_create(__t, 0, __func, __arg);
144 }
145
146 inline _LIBCPP_ALWAYS_INLINE
147 __libcpp_thread_id __libcpp_thread_get_current_id()
148 {
149     return pthread_self();
150 }
151
152 inline _LIBCPP_ALWAYS_INLINE
153 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
154 {
155     return *__t;
156 }
157
158 inline _LIBCPP_ALWAYS_INLINE
159 int __libcpp_thread_join(__libcpp_thread_t* __t)
160 {
161     return pthread_join(*__t, 0);
162 }
163
164 inline _LIBCPP_ALWAYS_INLINE
165 int __libcpp_thread_detach(__libcpp_thread_t* __t)
166 {
167     return pthread_detach(*__t);
168 }
169
170 inline _LIBCPP_ALWAYS_INLINE
171 void __libcpp_thread_yield()
172 {
173     sched_yield();
174 }
175
176 // Thread local storage
177 typedef pthread_key_t __libcpp_tl_key;
178
179 inline _LIBCPP_ALWAYS_INLINE
180 int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*))
181 {
182     return pthread_key_create(__key, __at_exit);
183 }
184
185 inline _LIBCPP_ALWAYS_INLINE
186 void* __libcpp_tl_get(__libcpp_tl_key __key)
187 {
188     return pthread_getspecific(__key);
189 }
190
191 inline _LIBCPP_ALWAYS_INLINE
192 void __libcpp_tl_set(__libcpp_tl_key __key, void* __p)
193 {
194     pthread_setspecific(__key, __p);
195 }
196
197 #else // !_LIBCPP_HAS_THREAD_API_PTHREAD
198   #error "No thread API selected."
199 #endif
200
201 _LIBCPP_END_NAMESPACE_STD
202
203 #endif // _LIBCPP_HAS_NO_THREADS
204
205 #endif // _LIBCPP_THREADING_SUPPORT