-
-
Save jroelofs/279cb2639ad910b953d2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: CMakeLists.txt | |
=================================================================== | |
--- CMakeLists.txt (revision 244611) | |
+++ CMakeLists.txt (working copy) | |
@@ -166,7 +166,7 @@ | |
# Setup Compiler Flags | |
#=============================================================================== | |
-include(HandleLibCXXABI) # Steup the ABI library flags | |
+include(HandleLibCXXABI) # Setup the ABI library flags | |
# Include macros for adding and removing libc++ flags. | |
include(HandleLibcxxFlags) | |
@@ -246,9 +246,8 @@ | |
define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK -D_LIBCPP_HAS_NO_MONOTONIC_CLOCK) | |
define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS -D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) | |
+# Sanitizer flags ============================================================= | |
-# Sanitizer flags | |
- | |
# Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do | |
# the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it. | |
if (LIBCXX_BUILT_STANDALONE) | |
@@ -282,10 +281,29 @@ | |
message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") | |
endif() | |
endif() | |
+ | |
+# Thread API ================================================================== | |
+if(UNIX AND LIBCXX_HAS_PTHREAD_LIB) | |
+ set(LIBCXX_THREAD_API _LIBCPP_PTHREAD) | |
+elseif(WIN32) | |
+ set(LIBCXX_THREAD_API _LIBCPP_WIN32THREAD) | |
+else() | |
+ set(LIBCXX_THREAD_API _LIBCPP_NOTHREADS) | |
+endif() | |
+ | |
#=============================================================================== | |
+# Build the site configuration file | |
+#=============================================================================== | |
+ | |
+configure_file( | |
+ include/__config_site.in | |
+ ${CMAKE_BINARY_DIR}/include/c++/v1/__config_site | |
+ @ONLY) | |
+ | |
+#=============================================================================== | |
# Setup Source Code And Tests | |
#=============================================================================== | |
-include_directories(include) | |
+include_directories(include "${CMAKE_BINARY_DIR}/include/c++/v1") | |
add_subdirectory(include) | |
add_subdirectory(lib) | |
if (LIBCXX_INCLUDE_TESTS) | |
Index: include/CMakeLists.txt | |
=================================================================== | |
--- include/CMakeLists.txt (revision 244611) | |
+++ include/CMakeLists.txt (working copy) | |
@@ -5,6 +5,7 @@ | |
PATTERN "*" | |
PATTERN "CMakeLists.txt" EXCLUDE | |
PATTERN ".svn" EXCLUDE | |
+ PATTERN "__config_site.in" EXCLUDE | |
${LIBCXX_SUPPORT_HEADER_PATTERN} | |
) | |
Index: include/__config | |
=================================================================== | |
--- include/__config (revision 244611) | |
+++ include/__config (working copy) | |
@@ -11,6 +11,8 @@ | |
#ifndef _LIBCPP_CONFIG | |
#define _LIBCPP_CONFIG | |
+#include <__config_site> | |
+ | |
#if !defined(_MSC_VER) || defined(__clang__) | |
#pragma GCC system_header | |
#endif | |
@@ -737,6 +739,13 @@ | |
# define _LIBCPP_WEAK __attribute__((__weak__)) | |
#endif | |
+// Thread API | |
+#ifndef _LIBCPP_HAS_NO_THREADS | |
+# ifndef _LIBCPP_THREAD_API | |
+# error "No thread API" | |
+# endif // _LIBCPP_THREAD_API | |
+#endif // _LIBCPP_HAS_NO_THREADS | |
+ | |
#if defined(_LIBCPP_HAS_NO_MONOTONIC_CLOCK) && !defined(_LIBCPP_HAS_NO_THREADS) | |
# error _LIBCPP_HAS_NO_MONOTONIC_CLOCK may only be defined when \ | |
_LIBCPP_HAS_NO_THREADS is defined. | |
Index: include/__config_site.in | |
=================================================================== | |
--- include/__config_site.in (revision 0) | |
+++ include/__config_site.in (working copy) | |
@@ -0,0 +1,8 @@ | |
+#ifndef _LIBCPP_CONFIG_SITE | |
+#define _LIBCPP_CONFIG_SITE | |
+ | |
+#define _LIBCPP_PTHREAD 1 | |
+ | |
+#define _LIBCPP_THREAD_API @LIBCXX_THREAD_API@ | |
+ | |
+#endif | |
Index: include/__mutex_base | |
=================================================================== | |
--- include/__mutex_base (revision 244611) | |
+++ include/__mutex_base (working copy) | |
@@ -14,7 +14,8 @@ | |
#include <__config> | |
#include <chrono> | |
#include <system_error> | |
-#include <pthread.h> | |
+#include <support/mutex.h> | |
+#include <support/condition_variable.h> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
@@ -26,14 +27,15 @@ | |
class _LIBCPP_TYPE_VIS mutex | |
{ | |
- pthread_mutex_t __m_; | |
+ typedef __libcpp_support::__os_mutex __mutex_type; | |
+ __mutex_type __m_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
#ifndef _LIBCPP_HAS_NO_CONSTEXPR | |
- constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {} | |
+ constexpr mutex() _NOEXCEPT : __m_(__libcpp_support::__os_mutex_init) {} | |
#else | |
- mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;} | |
+ mutex() _NOEXCEPT {__m_ = __libcpp_support::__os_mutex_init;} | |
#endif | |
~mutex(); | |
@@ -46,7 +48,7 @@ | |
bool try_lock() _NOEXCEPT; | |
void unlock() _NOEXCEPT; | |
- typedef pthread_mutex_t* native_handle_type; | |
+ typedef __mutex_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;} | |
}; | |
@@ -266,13 +268,14 @@ | |
class _LIBCPP_TYPE_VIS condition_variable | |
{ | |
- pthread_cond_t __cv_; | |
+ typedef __libcpp_support::__os_cond_var __cond_var_type; | |
+ __cond_var_type __cv_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
#ifndef _LIBCPP_HAS_NO_CONSTEXPR | |
- constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {} | |
+ constexpr condition_variable() : __cv_(__libcpp_support::__os_cond_var_init) {} | |
#else | |
- condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;} | |
+ condition_variable() {__cv_ = __libcpp_support::__os_cond_var_init;} | |
#endif | |
~condition_variable(); | |
@@ -310,7 +313,7 @@ | |
const chrono::duration<_Rep, _Period>& __d, | |
_Predicate __pred); | |
- typedef pthread_cond_t* native_handle_type; | |
+ typedef __cond_var_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;} | |
private: | |
Index: include/mutex | |
=================================================================== | |
--- include/mutex (revision 244611) | |
+++ include/mutex (working copy) | |
@@ -179,7 +179,7 @@ | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#include <tuple> | |
#endif | |
-#include <sched.h> | |
+#include <support/thread.h> | |
#include <__undef_min_max> | |
@@ -193,7 +193,8 @@ | |
class _LIBCPP_TYPE_VIS recursive_mutex | |
{ | |
- pthread_mutex_t __m_; | |
+ typedef __libcpp_support::__os_mutex __mutex_type; | |
+ __mutex_type __m_; | |
public: | |
recursive_mutex(); | |
@@ -206,9 +207,9 @@ | |
public: | |
void lock(); | |
bool try_lock() _NOEXCEPT; | |
- void unlock() _NOEXCEPT; | |
+ void unlock() _NOEXCEPT; | |
- typedef pthread_mutex_t* native_handle_type; | |
+ typedef __mutex_type* native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY | |
native_handle_type native_handle() {return &__m_;} | |
}; | |
@@ -257,10 +258,10 @@ | |
class _LIBCPP_TYPE_VIS recursive_timed_mutex | |
{ | |
- mutex __m_; | |
- condition_variable __cv_; | |
- size_t __count_; | |
- pthread_t __id_; | |
+ mutex __m_; | |
+ condition_variable __cv_; | |
+ size_t __count_; | |
+ __libcpp_support::__os_thread_id __id_; | |
public: | |
recursive_timed_mutex(); | |
~recursive_timed_mutex(); | |
@@ -286,9 +287,10 @@ | |
recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) | |
{ | |
using namespace chrono; | |
- pthread_t __id = pthread_self(); | |
+ using namespace __libcpp_support; | |
+ __os_thread_id __id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_); | |
- if (pthread_equal(__id, __id_)) | |
+ if (__os_thread_id_compare(__id, __id_) == 0) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
return false; | |
@@ -360,7 +362,7 @@ | |
break; | |
} | |
} | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
{ | |
unique_lock<_L1> __u1(__l1); | |
if (__l0.try_lock()) | |
@@ -369,7 +371,7 @@ | |
break; | |
} | |
} | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
} | |
} | |
@@ -394,7 +396,7 @@ | |
} | |
} | |
++__i; | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
break; | |
case 1: | |
{ | |
@@ -410,7 +412,7 @@ | |
__i = 0; | |
else | |
__i += 2; | |
- sched_yield(); | |
+ __libcpp_support::__os_yield(); | |
break; | |
default: | |
__lock_first(__i - 2, __l2, __l3..., __l0, __l1); | |
@@ -531,8 +533,6 @@ | |
(*__p)(); | |
} | |
-_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); | |
- | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template<class _Callable, class... _Args> | |
@@ -545,7 +545,7 @@ | |
typedef tuple<_Callable&&, _Args&&...> _Gp; | |
_Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); | |
__call_once_param<_Gp> __p(__f); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); | |
+ __libcpp_support::__os_call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); | |
} | |
} | |
@@ -559,7 +559,7 @@ | |
if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) | |
{ | |
__call_once_param<_Callable> __p(__func); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); | |
+ __libcpp_support::__call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); | |
} | |
} | |
@@ -571,7 +571,7 @@ | |
if (__flag.__state_ != ~0ul) | |
{ | |
__call_once_param<const _Callable> __p(__func); | |
- __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); | |
+ __libcpp_support::__call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); | |
} | |
} | |
Index: include/thread | |
=================================================================== | |
--- include/thread (revision 244611) | |
+++ include/thread (working copy) | |
@@ -98,8 +98,7 @@ | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
#include <tuple> | |
#endif | |
-#include <pthread.h> | |
-#include <sched.h> | |
+#include <support/thread.h> | |
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | |
#pragma GCC system_header | |
@@ -116,7 +115,7 @@ | |
template <class _Tp> | |
class __thread_specific_ptr | |
{ | |
- pthread_key_t __key_; | |
+ __libcpp_support::__os_tl_key __key_; | |
__thread_specific_ptr(const __thread_specific_ptr&); | |
__thread_specific_ptr& operator=(const __thread_specific_ptr&); | |
@@ -129,7 +128,7 @@ | |
~__thread_specific_ptr(); | |
_LIBCPP_INLINE_VISIBILITY | |
- pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));} | |
+ pointer get() const {return static_cast<_Tp*>(__libcpp_support::__os_tl_get(__key_));} | |
_LIBCPP_INLINE_VISIBILITY | |
pointer operator*() const {return *get();} | |
_LIBCPP_INLINE_VISIBILITY | |
@@ -148,7 +147,9 @@ | |
template <class _Tp> | |
__thread_specific_ptr<_Tp>::__thread_specific_ptr() | |
{ | |
- int __ec = pthread_key_create(&__key_, &__thread_specific_ptr::__at_thread_exit); | |
+ int __ec = __libcpp_support::__os_tl_create( | |
+ &__key_, | |
+ &__thread_specific_ptr::__at_thread_exit); | |
#ifndef _LIBCPP_NO_EXCEPTIONS | |
if (__ec) | |
throw system_error(error_code(__ec, system_category()), | |
@@ -159,7 +160,7 @@ | |
template <class _Tp> | |
__thread_specific_ptr<_Tp>::~__thread_specific_ptr() | |
{ | |
- pthread_key_delete(__key_); | |
+ __libcpp_support::__os_tl_destroy(__key_); | |
} | |
template <class _Tp> | |
@@ -167,7 +168,7 @@ | |
__thread_specific_ptr<_Tp>::release() | |
{ | |
pointer __p = get(); | |
- pthread_setspecific(__key_, 0); | |
+ __libcpp_support::__os_tl_set(__key_, 0); | |
return __p; | |
} | |
@@ -176,7 +177,7 @@ | |
__thread_specific_ptr<_Tp>::reset(pointer __p) | |
{ | |
pointer __p_old = get(); | |
- pthread_setspecific(__key_, __p); | |
+ __libcpp_support::__os_tl_set(__key_, __p); | |
delete __p_old; | |
} | |
@@ -197,7 +198,7 @@ | |
// FIXME: pthread_t is a pointer on Darwin but a long on Linux. | |
// NULL is the no-thread value on Darwin. Someone needs to check | |
// on other platforms. We assume 0 works everywhere for now. | |
- pthread_t __id_; | |
+ __libcpp_support::__os_thread_id __id_; | |
public: | |
_LIBCPP_INLINE_VISIBILITY | |
@@ -205,13 +206,13 @@ | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT | |
- {return __x.__id_ == __y.__id_;} | |
+ {return __libcpp_support::__os_thread_id_compare(__x.__id_, __y.__id_) == 0;} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return !(__x == __y);} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator< (__thread_id __x, __thread_id __y) _NOEXCEPT | |
- {return __x.__id_ < __y.__id_;} | |
+ {return __libcpp_support::__os_thread_id_compare(__x.__id_, __y.__id_) < 0;} | |
friend _LIBCPP_INLINE_VISIBILITY | |
bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT | |
{return !(__y < __x);} | |
@@ -227,11 +228,11 @@ | |
_LIBCPP_INLINE_VISIBILITY | |
basic_ostream<_CharT, _Traits>& | |
operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) | |
- {return __os << __id.__id_;} | |
+ {return __libcpp_support::__os_write_to_ostream(__os, __id.__id_);} | |
private: | |
_LIBCPP_INLINE_VISIBILITY | |
- __thread_id(pthread_t __id) : __id_(__id) {} | |
+ __thread_id(__libcpp_support::__os_thread_id __id) : __id_(__id) {} | |
friend __thread_id this_thread::get_id() _NOEXCEPT; | |
friend class _LIBCPP_TYPE_VIS thread; | |
@@ -245,7 +246,7 @@ | |
_LIBCPP_INLINE_VISIBILITY | |
size_t operator()(__thread_id __v) const | |
{ | |
- return hash<pthread_t>()(__v.__id_); | |
+ return hash<__libcpp_support::__os_thread_id>()(__v.__id_); | |
} | |
}; | |
@@ -256,23 +257,24 @@ | |
__thread_id | |
get_id() _NOEXCEPT | |
{ | |
- return pthread_self(); | |
+ return __libcpp_support::__os_get_current_thread_id(); | |
} | |
} // this_thread | |
class _LIBCPP_TYPE_VIS thread | |
{ | |
- pthread_t __t_; | |
+ typedef __libcpp_support::__os_thread __thread_type; | |
+ __thread_type __t_; | |
thread(const thread&); | |
thread& operator=(const thread&); | |
public: | |
typedef __thread_id id; | |
- typedef pthread_t native_handle_type; | |
+ typedef __thread_type native_handle_type; | |
_LIBCPP_INLINE_VISIBILITY | |
- thread() _NOEXCEPT : __t_(0) {} | |
+ thread() _NOEXCEPT : __t_(__libcpp_support::__os_thread_init) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class _Fp, class ..._Args, | |
class = typename enable_if | |
@@ -300,7 +302,7 @@ | |
void join(); | |
void detach(); | |
_LIBCPP_INLINE_VISIBILITY | |
- id get_id() const _NOEXCEPT {return __t_;} | |
+ id get_id() const _NOEXCEPT {return __libcpp_support::__os_get_thread_id(__t_);} | |
_LIBCPP_INLINE_VISIBILITY | |
native_handle_type native_handle() _NOEXCEPT {return __t_;} | |
@@ -356,7 +358,7 @@ | |
typedef tuple<typename decay<_Fp>::type, typename decay<_Args>::type...> _Gp; | |
_VSTD::unique_ptr<_Gp> __p(new _Gp(__decay_copy(_VSTD::forward<_Fp>(__f)), | |
__decay_copy(_VSTD::forward<_Args>(__args))...)); | |
- int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get()); | |
+ int __ec = __libcpp_support::__os_create_thread(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
if (__ec == 0) | |
__p.release(); | |
else | |
@@ -379,7 +381,7 @@ | |
thread::thread(_Fp __f) | |
{ | |
std::unique_ptr<_Fp> __p(new _Fp(__f)); | |
- int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get()); | |
+ int __ec = __libcpp_support::__os_create_thread(&__t_, &__thread_proxy<_Gp>, __p.get()); | |
if (__ec == 0) | |
__p.release(); | |
else | |
@@ -409,7 +411,10 @@ | |
namespace this_thread | |
{ | |
-_LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns); | |
+inline _LIBCPP_FUNC_VIS void sleep_for(const chrono::nanoseconds& ns) | |
+{ | |
+ __libcpp_support::__os_sleep_for(ns); | |
+} | |
template <class _Rep, class _Period> | |
void | |
@@ -454,7 +459,7 @@ | |
} | |
inline _LIBCPP_INLINE_VISIBILITY | |
-void yield() _NOEXCEPT {sched_yield();} | |
+void yield() _NOEXCEPT {__libcpp_support::__os_yield();} | |
} // this_thread | |
Index: include/type_traits | |
=================================================================== | |
--- include/type_traits (revision 244611) | |
+++ include/type_traits (working copy) | |
@@ -219,8 +219,8 @@ | |
template <class> | |
struct __void_t { typedef void type; }; | |
-template <class _Tp> | |
-struct __identity { typedef _Tp type; }; | |
+template <class T> | |
+struct __identity { typedef T type; }; | |
template <class _Tp, bool> | |
struct _LIBCPP_TYPE_VIS_ONLY __dependent_type : public _Tp {}; | |
Index: lib/CMakeLists.txt | |
=================================================================== | |
--- lib/CMakeLists.txt (revision 244611) | |
+++ lib/CMakeLists.txt (working copy) | |
@@ -8,6 +8,9 @@ | |
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS") | |
file(GLOB LIBCXX_SOLARIS_SOURCES ../src/support/solaris/*.c) | |
list(APPEND LIBCXX_SOURCES ${LIBCXX_SOLARIS_SOURCES}) | |
+elseif(UNIX) | |
+ file(GLOB LIBCXX_PTHREAD_SOURCES ../src/support/pthread/*.cpp) | |
+ list(APPEND LIBCXX_SOURCES ${LIBCXX_PTHREAD_SOURCES}) | |
endif() | |
# Add all the headers to the project for IDEs. | |
@@ -17,6 +20,9 @@ | |
file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/win32/*.h) | |
list(APPEND LIBCXX_HEADERS ${LIBCXX_WIN32_HEADERS}) | |
endif() | |
+if(XCODE) | |
+ file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/support/pthread/*) | |
+ endif() | |
# Force them all into the headers dir on MSVC, otherwise they end up at | |
# project scope because they don't have extensions. | |
if (MSVC_IDE) | |
Index: src/algorithm.cpp | |
=================================================================== | |
--- src/algorithm.cpp (revision 244611) | |
+++ src/algorithm.cpp (working copy) | |
@@ -48,14 +48,14 @@ | |
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&); | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
-static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER; | |
+static mutex __rs_mut; | |
#endif | |
unsigned __rs_default::__c_ = 0; | |
__rs_default::__rs_default() | |
{ | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
- pthread_mutex_lock(&__rs_mut); | |
+ __rs_mut.lock(); | |
#endif | |
__c_ = 1; | |
} | |
@@ -69,7 +69,7 @@ | |
{ | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
if (--__c_ == 0) | |
- pthread_mutex_unlock(&__rs_mut); | |
+ __rs_mut.unlock(); | |
#else | |
--__c_; | |
#endif | |
Index: src/condition_variable.cpp | |
=================================================================== | |
--- src/condition_variable.cpp (revision 244611) | |
+++ src/condition_variable.cpp (working copy) | |
@@ -18,21 +18,23 @@ | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
+using namespace __libcpp_support; | |
+ | |
condition_variable::~condition_variable() | |
{ | |
- pthread_cond_destroy(&__cv_); | |
+ __os_cond_var_destroy(&__cv_); | |
} | |
void | |
condition_variable::notify_one() _NOEXCEPT | |
{ | |
- pthread_cond_signal(&__cv_); | |
+ __os_cond_var_notify_one(&__cv_); | |
} | |
void | |
condition_variable::notify_all() _NOEXCEPT | |
{ | |
- pthread_cond_broadcast(&__cv_); | |
+ __os_cond_var_notify_all(&__cv_); | |
} | |
void | |
@@ -41,7 +43,7 @@ | |
if (!lk.owns_lock()) | |
__throw_system_error(EPERM, | |
"condition_variable::wait: mutex not locked"); | |
- int ec = pthread_cond_wait(&__cv_, lk.mutex()->native_handle()); | |
+ int ec = __os_cond_var_wait(&__cv_, lk.mutex()->native_handle()); | |
if (ec) | |
__throw_system_error(ec, "condition_variable wait failed"); | |
} | |
@@ -50,30 +52,10 @@ | |
condition_variable::__do_timed_wait(unique_lock<mutex>& lk, | |
chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp) _NOEXCEPT | |
{ | |
- using namespace chrono; | |
if (!lk.owns_lock()) | |
__throw_system_error(EPERM, | |
"condition_variable::timed wait: mutex not locked"); | |
- nanoseconds d = tp.time_since_epoch(); | |
- if (d > nanoseconds(0x59682F000000E941)) | |
- d = nanoseconds(0x59682F000000E941); | |
- timespec ts; | |
- seconds s = duration_cast<seconds>(d); | |
- typedef decltype(ts.tv_sec) ts_sec; | |
- _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
- if (s.count() < ts_sec_max) | |
- { | |
- ts.tv_sec = static_cast<ts_sec>(s.count()); | |
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((d - s).count()); | |
- } | |
- else | |
- { | |
- ts.tv_sec = ts_sec_max; | |
- ts.tv_nsec = giga::num - 1; | |
- } | |
- int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts); | |
- if (ec != 0 && ec != ETIMEDOUT) | |
- __throw_system_error(ec, "condition_variable timed_wait failed"); | |
+ __os_cond_var_timed_wait(&__cv_, lk.mutex()->native_handle(), tp); | |
} | |
void | |
Index: src/memory.cpp | |
=================================================================== | |
--- src/memory.cpp (revision 244611) | |
+++ src/memory.cpp (working copy) | |
@@ -127,15 +127,9 @@ | |
#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS) | |
static const std::size_t __sp_mut_count = 16; | |
-static pthread_mutex_t mut_back_imp[__sp_mut_count] = | |
-{ | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, | |
- PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER | |
-}; | |
+static mutex mut_back_imp[__sp_mut_count]; | |
-static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp); | |
+static mutex* mut_back = mut_back_imp; | |
_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT | |
: __lx(p) | |
Index: src/mutex.cpp | |
=================================================================== | |
--- src/mutex.cpp (revision 244611) | |
+++ src/mutex.cpp (working copy) | |
@@ -12,7 +12,7 @@ | |
#include "limits" | |
#include "system_error" | |
#include "cassert" | |
-#include "support/atomic_support.h" | |
+#include "support/thread.h" | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
#ifndef _LIBCPP_HAS_NO_THREADS | |
@@ -21,15 +21,17 @@ | |
const try_to_lock_t try_to_lock = {}; | |
const adopt_lock_t adopt_lock = {}; | |
+using namespace __libcpp_support; | |
+ | |
mutex::~mutex() | |
{ | |
- pthread_mutex_destroy(&__m_); | |
+ __os_mutex_destroy(&__m_); | |
} | |
void | |
mutex::lock() | |
{ | |
- int ec = pthread_mutex_lock(&__m_); | |
+ int ec = __os_mutex_lock(&__m_); | |
if (ec) | |
__throw_system_error(ec, "mutex lock failed"); | |
} | |
@@ -37,13 +39,13 @@ | |
bool | |
mutex::try_lock() _NOEXCEPT | |
{ | |
- return pthread_mutex_trylock(&__m_) == 0; | |
+ return __os_mutex_trylock(&__m_) == 0; | |
} | |
void | |
mutex::unlock() _NOEXCEPT | |
{ | |
- int ec = pthread_mutex_unlock(&__m_); | |
+ int ec = __os_mutex_unlock(&__m_); | |
(void)ec; | |
assert(ec == 0); | |
} | |
@@ -52,36 +54,12 @@ | |
recursive_mutex::recursive_mutex() | |
{ | |
- pthread_mutexattr_t attr; | |
- int ec = pthread_mutexattr_init(&attr); | |
- if (ec) | |
- goto fail; | |
- ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
- if (ec) | |
- { | |
- pthread_mutexattr_destroy(&attr); | |
- goto fail; | |
- } | |
- ec = pthread_mutex_init(&__m_, &attr); | |
- if (ec) | |
- { | |
- pthread_mutexattr_destroy(&attr); | |
- goto fail; | |
- } | |
- ec = pthread_mutexattr_destroy(&attr); | |
- if (ec) | |
- { | |
- pthread_mutex_destroy(&__m_); | |
- goto fail; | |
- } | |
- return; | |
-fail: | |
- __throw_system_error(ec, "recursive_mutex constructor failed"); | |
+ __os_recursive_mutex_init(&__m_); | |
} | |
recursive_mutex::~recursive_mutex() | |
{ | |
- int e = pthread_mutex_destroy(&__m_); | |
+ int e = __os_recursive_mutex_destroy(&__m_); | |
(void)e; | |
assert(e == 0); | |
} | |
@@ -89,7 +67,7 @@ | |
void | |
recursive_mutex::lock() | |
{ | |
- int ec = pthread_mutex_lock(&__m_); | |
+ int ec = __os_recursive_mutex_lock(&__m_); | |
if (ec) | |
__throw_system_error(ec, "recursive_mutex lock failed"); | |
} | |
@@ -97,7 +75,7 @@ | |
void | |
recursive_mutex::unlock() _NOEXCEPT | |
{ | |
- int e = pthread_mutex_unlock(&__m_); | |
+ int e = __os_recursive_mutex_unlock(&__m_); | |
(void)e; | |
assert(e == 0); | |
} | |
@@ -105,7 +83,7 @@ | |
bool | |
recursive_mutex::try_lock() _NOEXCEPT | |
{ | |
- return pthread_mutex_trylock(&__m_) == 0; | |
+ return __os_recursive_mutex_trylock(&__m_) == 0; | |
} | |
// timed_mutex | |
@@ -165,9 +143,9 @@ | |
void | |
recursive_timed_mutex::lock() | |
{ | |
- pthread_t id = pthread_self(); | |
+ __os_thread_id id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_); | |
- if (pthread_equal(id, __id_)) | |
+ if (__os_thread_id_compare(id, __id_) == 0) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
__throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); | |
@@ -183,9 +161,9 @@ | |
bool | |
recursive_timed_mutex::try_lock() _NOEXCEPT | |
{ | |
- pthread_t id = pthread_self(); | |
+ __os_thread_id id = __os_get_current_thread_id(); | |
unique_lock<mutex> lk(__m_, try_to_lock); | |
- if (lk.owns_lock() && (__count_ == 0 || pthread_equal(id, __id_))) | |
+ if (lk.owns_lock() && (__count_ == 0 || __os_thread_id_compare(id, __id_) == 0)) | |
{ | |
if (__count_ == numeric_limits<size_t>::max()) | |
return false; | |
@@ -210,75 +188,4 @@ | |
#endif // !_LIBCPP_HAS_NO_THREADS | |
-// If dispatch_once_f ever handles C++ exceptions, and if one can get to it | |
-// without illegal macros (unexpected macros not beginning with _UpperCase or | |
-// __lowercase), and if it stops spinning waiting threads, then call_once should | |
-// call into dispatch_once_f instead of here. Relevant radar this code needs to | |
-// keep in sync with: 7741191. | |
- | |
-#ifndef _LIBCPP_HAS_NO_THREADS | |
-static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; | |
-static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; | |
-#endif | |
- | |
-/// NOTE: Changes to flag are done via relaxed atomic stores | |
-/// even though the accesses are protected by a mutex because threads | |
-/// just entering 'call_once` concurrently read from flag. | |
-void | |
-__call_once(volatile unsigned long& flag, void* arg, void(*func)(void*)) | |
-{ | |
-#if defined(_LIBCPP_HAS_NO_THREADS) | |
- if (flag == 0) | |
- { | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- try | |
- { | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- flag = 1; | |
- func(arg); | |
- flag = ~0ul; | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- } | |
- catch (...) | |
- { | |
- flag = 0ul; | |
- throw; | |
- } | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- } | |
-#else // !_LIBCPP_HAS_NO_THREADS | |
- pthread_mutex_lock(&mut); | |
- while (flag == 1) | |
- pthread_cond_wait(&cv, &mut); | |
- if (flag == 0) | |
- { | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- try | |
- { | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- __libcpp_relaxed_store(&flag, 1ul); | |
- pthread_mutex_unlock(&mut); | |
- func(arg); | |
- pthread_mutex_lock(&mut); | |
- __libcpp_relaxed_store(&flag, ~0ul); | |
- pthread_mutex_unlock(&mut); | |
- pthread_cond_broadcast(&cv); | |
-#ifndef _LIBCPP_NO_EXCEPTIONS | |
- } | |
- catch (...) | |
- { | |
- pthread_mutex_lock(&mut); | |
- __libcpp_relaxed_store(&flag, 0ul); | |
- pthread_mutex_unlock(&mut); | |
- pthread_cond_broadcast(&cv); | |
- throw; | |
- } | |
-#endif // _LIBCPP_NO_EXCEPTIONS | |
- } | |
- else | |
- pthread_mutex_unlock(&mut); | |
-#endif // !_LIBCPP_HAS_NO_THREADS | |
- | |
-} | |
- | |
_LIBCPP_END_NAMESPACE_STD | |
Index: src/thread.cpp | |
=================================================================== | |
--- src/thread.cpp (revision 244611) | |
+++ src/thread.cpp (working copy) | |
@@ -32,6 +32,8 @@ | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
+using namespace __libcpp_support; | |
+ | |
thread::~thread() | |
{ | |
if (__t_ != 0) | |
@@ -41,7 +43,7 @@ | |
void | |
thread::join() | |
{ | |
- int ec = pthread_join(__t_, 0); | |
+ int ec = __os_thread_join(__t_); | |
#ifndef _LIBCPP_NO_EXCEPTIONS | |
if (ec) | |
throw system_error(error_code(ec, system_category()), "thread::join failed"); | |
@@ -57,7 +59,7 @@ | |
int ec = EINVAL; | |
if (__t_ != 0) | |
{ | |
- ec = pthread_detach(__t_); | |
+ ec = __os_thread_detach(__t_); | |
if (ec == 0) | |
__t_ = 0; | |
} | |
@@ -101,37 +103,6 @@ | |
#endif // defined(CTL_HW) && defined(HW_NCPU) | |
} | |
-namespace this_thread | |
-{ | |
- | |
-void | |
-sleep_for(const chrono::nanoseconds& ns) | |
-{ | |
- using namespace chrono; | |
- if (ns > nanoseconds::zero()) | |
- { | |
- seconds s = duration_cast<seconds>(ns); | |
- timespec ts; | |
- typedef decltype(ts.tv_sec) ts_sec; | |
- _LIBCPP_CONSTEXPR ts_sec ts_sec_max = numeric_limits<ts_sec>::max(); | |
- if (s.count() < ts_sec_max) | |
- { | |
- ts.tv_sec = static_cast<ts_sec>(s.count()); | |
- ts.tv_nsec = static_cast<decltype(ts.tv_nsec)>((ns-s).count()); | |
- } | |
- else | |
- { | |
- ts.tv_sec = ts_sec_max; | |
- ts.tv_nsec = giga::num - 1; | |
- } | |
- | |
- while (nanosleep(&ts, &ts) == -1 && errno == EINTR) | |
- ; | |
- } | |
-} | |
- | |
-} // this_thread | |
- | |
__thread_specific_ptr<__thread_struct>& | |
__thread_local_data() | |
{ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: src/CMakeLists.txt | |
=================================================================== | |
--- src/CMakeLists.txt (revision 244611) | |
+++ src/CMakeLists.txt (working copy) | |
@@ -34,7 +34,8 @@ | |
endif() | |
endif() | |
-include_directories("${LIBCXXABI_LIBCXX_INCLUDES}") | |
+include_directories("${LIBCXXABI_LIBCXX_INCLUDES}" | |
+ "${CMAKE_BINARY_DIR}/include/c++/v1") | |
if (LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) | |
add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment