Index: include/__mutex_base =================================================================== --- include/__mutex_base +++ include/__mutex_base @@ -39,7 +39,9 @@ public: _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_CONSTEXPR +#if defined(_LIBCPP_THREAD_API_EXTERNAL) + mutex() _NOEXCEPT {__libcpp_os_support::__os_mutex_init(&__m_);} +#elif !defined(_LIBCPP_HAS_NO_CONSTEXPR) constexpr mutex() _NOEXCEPT : __m_(__OS_MUTEX_INITIALIZER) {} #else mutex() _NOEXCEPT {__m_ = (__mutex_type)__OS_MUTEX_INITIALIZER;} @@ -279,7 +281,9 @@ __cond_var_type __cv_; public: _LIBCPP_INLINE_VISIBILITY -#ifndef _LIBCPP_HAS_NO_CONSTEXPR +#if defined(_LIBCPP_THREAD_API_EXTERNAL) + condition_variable() {__libcpp_os_support::__os_condvar_init(&__cv_);} +#elif !defined(_LIBCPP_HAS_NO_CONSTEXPR) constexpr condition_variable() : __cv_(__OS_COND_INITIALIZER) {} #else condition_variable() {__cv_ = (__os_cond_var)__OS_COND_INITIALIZER;} Index: include/__os_support =================================================================== --- include/__os_support +++ include/__os_support @@ -13,7 +13,81 @@ #ifndef _LIBCPP_HAS_NO_THREADS -#if defined(_LIBCPP_THREAD_API_PTHREAD) +#if defined(_LIBCPP_THREAD_API_EXTERNAL) + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace __libcpp_os_support +{ +// Mutexes +struct __mutex_t; +typedef struct __mutex_t* __os_mutex; + +int __os_mutex_init(__os_mutex*, bool recursive = false); + +int __os_mutex_destroy(__os_mutex); + +int __os_mutex_lock(__os_mutex); + +int __os_mutex_trylock(__os_mutex); + +int __os_mutex_unlock(__os_mutex); + +void __os_call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)); + +// Condition variables +struct __condvar_t; +typedef struct __condvar_t* __os_cond_var; + +int __os_condvar_init(__os_cond_var*); + +int __os_condvar_destroy(__os_cond_var); + +int __os_condvar_signal(__os_cond_var); + +int __os_condvar_broadcast(__os_cond_var); + +int __os_condvar_wait(__os_cond_var, __os_mutex*); + +int __os_condvar_timedwait(__os_cond_var, __os_mutex*, timespec*); + +// Thread id +typedef unsigned long __os_thread_id; + +int __os_thread_id_compare(__os_thread_id, __os_thread_id); + +// Thread +struct __thread_t; +typedef struct __thread_t* __os_thread; + +template +int __os_thread_create(__os_thread* __t, _Func&& __f, _Arg&& __arg); + +__os_thread_id __os_thread_get_current_id(); + +__os_thread_id __os_thread_get_id(__os_thread); + +int __os_thread_join(__os_thread); + +int __os_thread_detach(__os_thread); + +void __os_thread_yield(); + +// Thread local storage +typedef unsigned long __os_tl_key; + +template +int __os_tl_create(__os_tl_key* __key, _Func&& __at_exit); + +void* __os_tl_get(__os_tl_key); + +void __os_tl_set(__os_tl_key __key, void* __p); + +} // __libcpp_os_support + +_LIBCPP_END_NAMESPACE_STD + +#elif defined(_LIBCPP_THREAD_API_PTHREAD) #include #include Index: include/thread =================================================================== --- include/thread +++ include/thread @@ -303,7 +303,11 @@ typedef __thread_type native_handle_type; _LIBCPP_INLINE_VISIBILITY +#if defined(_LIBCPP_THREAD_API_EXTERNAL) + thread() _NOEXCEPT : __t_(NULL) {} +#else thread() _NOEXCEPT : __t_(__libcpp_os_support::__os_thread_init) {} +#endif #ifndef _LIBCPP_HAS_NO_VARIADICS template &, long double*>(long double*, long double*, long double*, long double*, long double*, __less&); #ifndef _LIBCPP_HAS_NO_THREADS +# if defined(_LIBCPP_THREAD_API_PTHREAD) static __libcpp_os_support::__os_mutex __rs_mut = __OS_MUTEX_INITIALIZER; +# else +static mutex __rs_mut; +# endif #endif unsigned __rs_default::__c_ = 0; __rs_default::__rs_default() { #ifndef _LIBCPP_HAS_NO_THREADS -#if defined(_LIBCPP_THREAD_API_PTHREAD) +# if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_mutex_lock(&__rs_mut); -#else +# elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __rs_mut.lock(); +# else #error "Not implemented for the selected thread API." -#endif +# endif #endif __c_ = 1; } @@ -73,11 +79,13 @@ { #ifndef _LIBCPP_HAS_NO_THREADS if (--__c_ == 0) -#if defined(_LIBCPP_THREAD_API_PTHREAD) +# if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_mutex_unlock(&__rs_mut); -#else +# elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __rs_mut.unlock(); +# else #error "Not implemented for the selected thread API." -#endif +# endif #else --__c_; #endif Index: src/condition_variable.cpp =================================================================== --- src/condition_variable.cpp +++ src/condition_variable.cpp @@ -24,6 +24,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_cond_destroy(&__cv_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __os_condvar_destroy(__cv_); #else #error "Not implemented for the selected thread API." #endif @@ -34,6 +36,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_cond_signal(&__cv_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __os_condvar_signal(__cv_); #else #error "Not implemented for the selected thread API." #endif @@ -44,6 +48,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_cond_broadcast(&__cv_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __os_condvar_broadcast(__cv_); #else #error "Not implemented for the selected thread API." #endif @@ -57,6 +63,8 @@ "condition_variable::wait: mutex not locked"); #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_condvar_wait(__cv_, lk.mutex()->native_handle()); #else #error "Not implemented for the selected thread API." #endif @@ -91,6 +99,8 @@ } #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_condvar_timedwait(__cv_, lk.mutex()->native_handle(), &ts); #else #error "Not implemented for the selected thread API." #endif Index: src/memory.cpp =================================================================== --- src/memory.cpp +++ src/memory.cpp @@ -127,6 +127,8 @@ #if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS) static const std::size_t __sp_mut_count = 16; + +#if !defined(_LIBCPP_THREAD_API_EXTERNAL) static __libcpp_os_support::__os_mutex mut_back_imp[__sp_mut_count] = { __OS_MUTEX_INITIALIZER, __OS_MUTEX_INITIALIZER, __OS_MUTEX_INITIALIZER, __OS_MUTEX_INITIALIZER, @@ -136,6 +138,9 @@ }; static mutex* mut_back = reinterpret_cast(mut_back_imp); +#else +static mutex mut_back[__sp_mut_count]; +#endif _LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT : __lx(p) Index: src/mutex.cpp =================================================================== --- src/mutex.cpp +++ src/mutex.cpp @@ -27,6 +27,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) pthread_mutex_destroy(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __os_mutex_destroy(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -37,6 +39,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_mutex_lock(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_mutex_lock(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -49,6 +53,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) return pthread_mutex_trylock(&__m_) == 0; +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + return __os_mutex_trylock(__m_) == 0; #else #error "Not implemented for the selected thread API." #endif @@ -59,6 +65,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_mutex_unlock(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_mutex_unlock(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -93,18 +101,24 @@ pthread_mutex_destroy(&__m_); goto fail; } - return; -fail: - __throw_system_error(ec, "recursive_mutex constructor failed"); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_mutex_init(&__m_, true); + if (ec) + goto fail; #else #error "Not implemented for the selected thread API." #endif + return; +fail: + __throw_system_error(ec, "recursive_mutex constructor failed"); } recursive_mutex::~recursive_mutex() { #if defined(_LIBCPP_THREAD_API_PTHREAD) int e = pthread_mutex_destroy(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int e = __os_mutex_destroy(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -117,6 +131,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_mutex_lock(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_mutex_lock(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -129,6 +145,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) int e = pthread_mutex_unlock(&__m_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int e = __os_mutex_unlock(__m_); #else #error "Not implemented for the selected thread API." #endif @@ -141,6 +159,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) return pthread_mutex_trylock(&__m_) == 0; +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + return __os_mutex_trylock(__m_) == 0; #else #error "Not implemented for the selected thread API." #endif @@ -311,7 +331,9 @@ } else pthread_mutex_unlock(&mut); -#else // !_LIBCPP_THREAD_API_PTHREAD +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + __os_call_once(flag, arg, func); +#else #error "Not implemented for the selected thread API." #endif // _LIBCPP_THREAD_API_PTHREAD #endif // _LIBCPP_HAS_NO_THREADS Index: src/thread.cpp =================================================================== --- src/thread.cpp +++ src/thread.cpp @@ -50,6 +50,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) int ec = pthread_join(__t_, 0); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + int ec = __os_thread_join(__t_); #else #error "Not implemented for the selected thread API." #endif @@ -70,6 +72,8 @@ { #if defined(_LIBCPP_THREAD_API_PTHREAD) ec = pthread_detach(__t_); +#elif defined(_LIBCPP_THREAD_API_EXTERNAL) + ec = __os_thread_detach(__t_); #else #error "Not implemented for the selected thread API." #endif