2 //===----------------------------------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_THREADING_SUPPORT
12 #define _LIBCPP_THREADING_SUPPORT
16 #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
17 #pragma GCC system_header
20 #ifndef _LIBCPP_HAS_NO_THREADS
22 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
27 _LIBCPP_BEGIN_NAMESPACE_STD
29 #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
32 #define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
33 typedef pthread_mutex_t __libcpp_mutex_t;
35 inline _LIBCPP_ALWAYS_INLINE
36 int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
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);
44 pthread_mutexattr_destroy(&attr);
47 __ec = pthread_mutex_init(__m, &attr);
50 pthread_mutexattr_destroy(&attr);
53 __ec = pthread_mutexattr_destroy(&attr);
56 pthread_mutex_destroy(__m);
62 inline _LIBCPP_ALWAYS_INLINE
63 int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
65 return pthread_mutex_lock(__m);
68 inline _LIBCPP_ALWAYS_INLINE
69 int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
71 return pthread_mutex_trylock(__m);
74 inline _LIBCPP_ALWAYS_INLINE
75 int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
77 return pthread_mutex_unlock(__m);
80 inline _LIBCPP_ALWAYS_INLINE
81 int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
83 return pthread_mutex_destroy(__m);
87 #define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
88 typedef pthread_cond_t __libcpp_condvar_t;
90 inline _LIBCPP_ALWAYS_INLINE
91 int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
93 return pthread_cond_signal(__cv);
96 inline _LIBCPP_ALWAYS_INLINE
97 int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
99 return pthread_cond_broadcast(__cv);
102 inline _LIBCPP_ALWAYS_INLINE
103 int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
105 return pthread_cond_wait(__cv, __m);
108 inline _LIBCPP_ALWAYS_INLINE
109 int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
111 return pthread_cond_timedwait(__cv, __m, __ts);
114 inline _LIBCPP_ALWAYS_INLINE
115 int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
117 return pthread_cond_destroy(__cv);
121 typedef pthread_t __libcpp_thread_id;
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)
127 return pthread_equal(t1, t2) != 0;
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)
138 typedef pthread_t __libcpp_thread_t;
140 inline _LIBCPP_ALWAYS_INLINE
141 int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
143 return pthread_create(__t, 0, __func, __arg);
146 inline _LIBCPP_ALWAYS_INLINE
147 __libcpp_thread_id __libcpp_thread_get_current_id()
149 return pthread_self();
152 inline _LIBCPP_ALWAYS_INLINE
153 __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
158 inline _LIBCPP_ALWAYS_INLINE
159 int __libcpp_thread_join(__libcpp_thread_t* __t)
161 return pthread_join(*__t, 0);
164 inline _LIBCPP_ALWAYS_INLINE
165 int __libcpp_thread_detach(__libcpp_thread_t* __t)
167 return pthread_detach(*__t);
170 inline _LIBCPP_ALWAYS_INLINE
171 void __libcpp_thread_yield()
176 // Thread local storage
177 typedef pthread_key_t __libcpp_tl_key;
179 inline _LIBCPP_ALWAYS_INLINE
180 int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*))
182 return pthread_key_create(__key, __at_exit);
185 inline _LIBCPP_ALWAYS_INLINE
186 void* __libcpp_tl_get(__libcpp_tl_key __key)
188 return pthread_getspecific(__key);
191 inline _LIBCPP_ALWAYS_INLINE
192 void __libcpp_tl_set(__libcpp_tl_key __key, void* __p)
194 pthread_setspecific(__key, __p);
197 #else // !_LIBCPP_HAS_THREAD_API_PTHREAD
198 #error "No thread API selected."
201 _LIBCPP_END_NAMESPACE_STD
203 #endif // _LIBCPP_HAS_NO_THREADS
205 #endif // _LIBCPP_THREADING_SUPPORT