espositofulvio updated this revision to Diff 31716.
espositofulvio added a comment.

Added __CloudABI__ to the list of platform using pthread


Repository:
  rL LLVM

http://reviews.llvm.org/D11781

Files:
  include/__config
  include/__mutex_base
  include/mutex
  include/support/condition_variable.h
  include/support/mutex.h
  include/support/pthread/condition_variable.h
  include/support/pthread/mutex.h
  include/support/pthread/thread.h
  include/support/thread.h
  include/thread
  include/type_traits
  lib/CMakeLists.txt
  src/algorithm.cpp
  src/condition_variable.cpp
  src/memory.cpp
  src/mutex.cpp
  src/support/pthread/condition_variable.cpp
  src/support/pthread/mutex.cpp
  src/support/pthread/thread.cpp
  src/thread.cpp

Index: src/thread.cpp
===================================================================
--- src/thread.cpp
+++ src/thread.cpp
@@ -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()
 {
Index: src/support/pthread/thread.cpp
===================================================================
--- /dev/null
+++ src/support/pthread/thread.cpp
@@ -0,0 +1,54 @@
+// -*- C++ -*-
+//===---------------------- support/pthread/thread.cpp --------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "__config"
+
+#include <ostream>
+#include <chrono>
+#define _LIBCPP_INCLUDE_THREAD_API
+#include <support/pthread/thread.h>
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+namespace __libcpp_support
+{
+
+void
+__os_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)
+            ;
+    }
+}
+
+} //namespace __libcpp_support
+
+#endif // _LIBCPP_HAS_NO_THREADS
+_LIBCPP_END_NAMESPACE_STD
Index: src/support/pthread/mutex.cpp
===================================================================
--- /dev/null
+++ src/support/pthread/mutex.cpp
@@ -0,0 +1,131 @@
+// -*- C++ -*-
+//===---------------------- support/pthread/thread.cpp --------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "__config"
+
+#include <chrono>
+#include <system_error>
+#include "../atomic_support.h"
+
+#define _LIBCPP_INCLUDE_THREAD_API
+#include <support/pthread/mutex.h>
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+namespace __libcpp_support
+{
+
+void __os_recursive_mutex_init(__os_mutex* __m)
+{
+    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");
+}
+
+#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
+__os_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
+
+}
+
+} //namespace __libcpp_support
+
+_LIBCPP_END_NAMESPACE_STD
Index: src/support/pthread/condition_variable.cpp
===================================================================
--- /dev/null
+++ src/support/pthread/condition_variable.cpp
@@ -0,0 +1,55 @@
+// -*- C++ -*-
+//===---------------------- support/pthread/thread.cpp --------------------===//
+//
+//                     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.
+//
+//===----------------------------------------------------------------------===//
+
+#include "__config"
+
+#include <chrono>
+#include "system_error"
+#define _LIBCPP_INCLUDE_THREAD_API
+#include <support/pthread/condition_variable.h>
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+namespace __libcpp_support
+{
+
+void __os_cond_var_timed_wait(__os_cond_var* cv,
+     __os_mutex* m,
+     chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp)
+{
+    using namespace chrono;
+    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, m, &ts);
+    if (ec != 0 && ec != ETIMEDOUT)
+        __throw_system_error(ec, "condition_variable timed_wait failed");    
+}
+
+} //namespace __libcpp_support
+
+#endif // _LIBCPP_HAS_NO_THREADS
+_LIBCPP_END_NAMESPACE_STD
Index: src/mutex.cpp
===================================================================
--- src/mutex.cpp
+++ src/mutex.cpp
@@ -12,100 +12,78 @@
 #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
 
 const defer_lock_t  defer_lock = {};
 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");
 }
 
 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);
 }
 
 // recursive_mutex
 
 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);
 }
 
 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");
 }
 
 void
 recursive_mutex::unlock() _NOEXCEPT
 {
-    int e = pthread_mutex_unlock(&__m_);
+    int e = __os_recursive_mutex_unlock(&__m_);
     (void)e;
     assert(e == 0);
 }
 
 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/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -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/condition_variable.cpp
===================================================================
--- src/condition_variable.cpp
+++ src/condition_variable.cpp
@@ -18,62 +18,44 @@
 
 _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
 condition_variable::wait(unique_lock<mutex>& lk) _NOEXCEPT
 {
     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");
 }
 
 void
 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/algorithm.cpp
===================================================================
--- src/algorithm.cpp
+++ src/algorithm.cpp
@@ -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: lib/CMakeLists.txt
===================================================================
--- lib/CMakeLists.txt
+++ lib/CMakeLists.txt
@@ -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: include/type_traits
===================================================================
--- include/type_traits
+++ include/type_traits
@@ -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: include/thread
===================================================================
--- include/thread
+++ include/thread
@@ -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,24 +160,24 @@
 template <class _Tp>
 __thread_specific_ptr<_Tp>::~__thread_specific_ptr()
 {
-    pthread_key_delete(__key_);
+    __libcpp_support::__os_tl_destroy(__key_);
 }
 
 template <class _Tp>
 typename __thread_specific_ptr<_Tp>::pointer
 __thread_specific_ptr<_Tp>::release()
 {
     pointer __p = get();
-    pthread_setspecific(__key_, 0);
+    __libcpp_support::__os_tl_set(__key_, 0);
     return __p;
 }
 
 template <class _Tp>
 void
 __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,21 +198,21 @@
     // 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
     __thread_id() _NOEXCEPT : __id_(0) {}
 
     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/support/thread.h
===================================================================
--- /dev/null
+++ include/support/thread.h
@@ -0,0 +1,27 @@
+// -*- 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_SUPPORT_THREAD_H
+#define _LIBCPP_SUPPORT_THREAD_H
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+#define _LIBCPP_INCLUDE_THREAD_API
+
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+# include <support/pthread/thread.h>
+#else
+# error "No thread API found"
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP_SUPPORT_THREAD_H
Index: include/support/pthread/thread.h
===================================================================
--- /dev/null
+++ include/support/pthread/thread.h
@@ -0,0 +1,121 @@
+// -*- 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_SUPPORT_PTHREAD_THREAD_H
+#define _LIBCPP_SUPPORT_PTHREAD_THREAD_H
+
+#ifndef _LIBCPP_INCLUDE_THREAD_API
+# error "This header can't be included directly"
+#endif // _LIBCPP_INCLUDE_THREAD_API
+
+#include <pthread.h>
+#include <sched.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __libcpp_support
+{
+
+// thread local
+typedef pthread_key_t __os_tl_key;
+
+template<class _Func>
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_tl_create(__os_tl_key* __key, _Func&& __at_exit)
+{
+    return pthread_key_create(__key, __at_exit);
+}
+    
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_tl_destroy(__os_tl_key __key)
+{
+    pthread_key_delete(__key);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void* __os_tl_get(__os_tl_key __key)
+{
+    return pthread_getspecific(__key);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_tl_set(__os_tl_key __key, void* __p)
+{
+    pthread_setspecific(__key, __p);
+}
+
+// thread id
+typedef pthread_t __os_thread_id;
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_thread_id_compare( __os_thread_id t1, __os_thread_id t2)
+{
+    bool res = pthread_equal(t1, t2);
+    return res != 0 ? 0 : (t1 < t2 ? -1 : 1);
+}
+
+template<class _CharT, class _Traits>
+inline _LIBCPP_INLINE_VISIBILITY
+basic_ostream<_CharT, _Traits>&
+__os_write_to_ostream(basic_ostream<_CharT, _Traits>& __os, __os_thread_id __id)
+{
+    return __os << __id;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+__os_thread_id __os_get_current_thread_id()
+{
+    return pthread_self();
+}
+
+
+// thread
+typedef pthread_t __os_thread;
+_LIBCPP_CONSTEXPR pthread_t __os_thread_init = 0;
+
+template<class _Func, class _Arg>
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_create_thread(__os_thread* __t, _Func&& __f, _Arg&& __arg)
+{
+    return pthread_create(__t, 0, __f, __arg);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+__os_thread_id __os_get_thread_id(__os_thread __t)
+{
+    return __t;
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_thread_join(__os_thread t)
+{
+    return pthread_join(t, 0);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_thread_detach(__os_thread t)
+{
+    return pthread_detach(t);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_yield()
+{
+    sched_yield();
+}
+
+_LIBCPP_FUNC_VIS void __os_sleep_for(const chrono::nanoseconds& ns);
+
+} // namespace __libcpp_support
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SUPPORT_PTHREAD_THREAD_H
+
Index: include/support/pthread/mutex.h
===================================================================
--- /dev/null
+++ include/support/pthread/mutex.h
@@ -0,0 +1,93 @@
+// -*- 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_SUPPORT_PTHREAD_MUTEX_H
+#define _LIBCPP_SUPPORT_PTHREAD_MUTEX_H
+
+#ifndef _LIBCPP_INCLUDE_THREAD_API
+# error "This header can't be included directly"
+#endif // _LIBCPP_INCLUDE_THREAD_API
+
+#include <pthread.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __libcpp_support
+{
+
+// mutex
+typedef pthread_mutex_t __os_mutex;
+_LIBCPP_CONSTEXPR pthread_mutex_t __os_mutex_init = PTHREAD_MUTEX_INITIALIZER;
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_mutex_lock(__os_mutex* __m)
+{
+    return pthread_mutex_lock(__m);
+}
+    
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_mutex_trylock(__os_mutex* __m)
+{
+    return pthread_mutex_trylock(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_mutex_unlock(__os_mutex* __m)
+{
+    return pthread_mutex_unlock(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_mutex_destroy(__os_mutex* __m)
+{
+    return pthread_mutex_destroy(__m);
+}
+
+// pthread hides differences between recursive and non-recursive mutexes
+// internally, other platform (e.g. Windows) might not, thus the following
+// is like the above except for init
+typedef pthread_mutex_t __os_recursive_mutex;
+
+_LIBCPP_FUNC_VIS
+void __os_recursive_mutex_init(__os_mutex* __m);
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_recursive_mutex_lock(__os_mutex* __m)
+{
+    return pthread_mutex_lock(__m);
+}
+    
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_recursive_mutex_trylock(__os_mutex* __m)
+{
+    return pthread_mutex_trylock(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_recursive_mutex_unlock(__os_mutex* __m)
+{
+    return pthread_mutex_unlock(__m);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_recursive_mutex_destroy(__os_mutex* __m)
+{
+    return pthread_mutex_destroy(__m);
+}
+
+_LIBCPP_FUNC_VIS void __os_call_once(volatile unsigned long&, void*, void(*)(void*));
+
+
+} // namespace __libcpp_support
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SUPPORT_PTHREAD_MUTEX_H
+
Index: include/support/pthread/condition_variable.h
===================================================================
--- /dev/null
+++ include/support/pthread/condition_variable.h
@@ -0,0 +1,62 @@
+// -*- 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_SUPPORT_PTHREAD_CONDITION_VARIABLE_H
+#define _LIBCPP_SUPPORT_PTHREAD_CONDITION_VARIABLE_H
+
+#ifndef _LIBCPP_INCLUDE_THREAD_API
+# error "This header can't be included directly"
+#endif // _LIBCPP_INCLUDE_THREAD_API
+
+#include <pthread.h>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __libcpp_support
+{
+
+typedef pthread_cond_t __os_cond_var;
+typedef pthread_mutex_t __os_mutex;
+_LIBCPP_CONSTEXPR pthread_cond_t __os_cond_var_init = PTHREAD_COND_INITIALIZER;
+
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_cond_var_destroy(__os_cond_var* __cv)
+{
+    pthread_cond_destroy(__cv);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_cond_var_notify_one(__os_cond_var* __cv)
+{
+    pthread_cond_signal(__cv);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+void __os_cond_var_notify_all(__os_cond_var* __cv)
+{
+    pthread_cond_broadcast(__cv);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
+int __os_cond_var_wait(__os_cond_var* __cv, __os_mutex* __m)
+{
+    return pthread_cond_wait(__cv, __m);
+}
+
+_LIBCPP_FUNC_VIS
+void __os_cond_var_timed_wait(__os_cond_var* __cv,
+     __os_mutex* __m,
+     chrono::time_point<chrono::system_clock, chrono::nanoseconds> tp);
+
+} // namespace __libcpp_support
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_SUPPORT_PTHREAD_CONDITION_VARIABLE_H
Index: include/support/mutex.h
===================================================================
--- /dev/null
+++ include/support/mutex.h
@@ -0,0 +1,28 @@
+// -*- 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_SUPPORT_MUTEX_H
+#define _LIBCPP_SUPPORT_MUTEX_H
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+#define _LIBCPP_INCLUDE_THREAD_API
+
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+# include <support/pthread/mutex.h>
+#else
+# error "No thread API found"
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP_SUPPORT_MUTEX_H
Index: include/support/condition_variable.h
===================================================================
--- /dev/null
+++ include/support/condition_variable.h
@@ -0,0 +1,28 @@
+// -*- 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_SUPPORT_CONDITION_VARIABLE_H
+#define _LIBCPP_SUPPORT_CONDITION_VARIABLE_H
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
+#define _LIBCPP_INCLUDE_THREAD_API
+
+#if _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+# include <support/pthread/condition_variable.h>
+#else
+# error "No thread API found"
+#endif // _LIBCPP_THREAD_API == _LIBCPP_PTHREAD
+
+#undef _LIBCPP_INCLUDE_THREAD_API
+
+#endif // _LIBCPP_HAS_NO_THREADS
+
+#endif // _LIBCPP_SUPPORT_CONDITION_VARIABLE_H
Index: include/mutex
===================================================================
--- include/mutex
+++ include/mutex
@@ -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,16 +362,16 @@
                 break;
             }
         }
-        sched_yield();
+        __libcpp_support::__os_yield();
         {
             unique_lock<_L1> __u1(__l1);
             if (__l0.try_lock())
             {
                 __u1.release();
                 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/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -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/__config
===================================================================
--- include/__config
+++ include/__config
@@ -737,6 +737,19 @@
 #  define _LIBCPP_WEAK __attribute__((__weak__))
 #endif
 
+// Thread API
+#ifndef _LIBCPP_HAS_NO_THREADS
+# if defined(__FreeBSD__) || \
+    defined(__NetBSD__) || \
+    defined(__linux__) || \
+    defined(__APPLE__) || \
+    defined(__CloudABI__)
+#  define _LIBCPP_THREAD_API _LIBCPP_PTHREAD
+# else
+#  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.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to