Implement a few of mclow's comments.

http://reviews.llvm.org/D3969

Files:
  include/__config
  include/__mutex_base
  include/atomic
  include/condition_variable
  include/future
  include/memory
  include/mutex
  include/shared_mutex
  include/thread
  src/algorithm.cpp
  src/condition_variable.cpp
  src/debug.cpp
  src/future.cpp
  src/memory.cpp
  src/mutex.cpp
  src/shared_mutex.cpp
  src/thread.cpp
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -11,6 +11,10 @@
 #ifndef _LIBCPP_CONFIG
 #define _LIBCPP_CONFIG
 
+#if !_WIN32
+#include <unistd.h>
+#endif
+
 #if !defined(_MSC_VER) || defined(__clang__)
 #pragma GCC system_header
 #endif
@@ -119,6 +123,12 @@
 # endif
 #endif  // !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
 
+#if !defined(_LIBCPP_HAS_NO_THREADS) && (!defined(_POSIX_THREADS) || _POSIX_THREADS <= 0)
+#  error <unistd.h> suggests that your system doesn't have PTHREADS... \
+         If you'd like to build libcxx for a single threaded system,   \
+         please use -D_LIBCPP_SINGLE_THREADED
+#endif
+
 #ifdef _WIN32
 
 // only really useful for a DLL
Index: include/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -22,6 +22,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 class _LIBCPP_TYPE_VIS mutex
 {
     pthread_mutex_t __m_;
@@ -315,6 +317,7 @@
     void __do_timed_wait(unique_lock<mutex>& __lk,
        chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
 };
+#endif // !_LIBCPP_HAS_NO_THREADS
 
 template <class _To, class _Rep, class _Period>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -332,6 +335,7 @@
     return __r;
 }
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 template <class _Predicate>
 void
 condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
@@ -396,6 +400,8 @@
                       _VSTD::move(__pred));
 }
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP___MUTEX_BASE
Index: include/atomic
===================================================================
--- include/atomic
+++ include/atomic
@@ -533,6 +533,10 @@
 #pragma GCC system_header
 #endif
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <atomic> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 #if !__has_feature(cxx_atomic) && _GNUC_VER < 407
@@ -1779,4 +1783,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif  // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_ATOMIC
Index: include/condition_variable
===================================================================
--- include/condition_variable
+++ include/condition_variable
@@ -115,6 +115,8 @@
 #pragma GCC system_header
 #endif
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS condition_variable_any
@@ -253,4 +255,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_CONDITION_VARIABLE
Index: include/future
===================================================================
--- include/future
+++ include/future
@@ -374,6 +374,10 @@
 #pragma GCC system_header
 #endif
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+#error <future> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 //enum class future_errc
@@ -2612,4 +2616,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_FUTURE
Index: include/memory
===================================================================
--- include/memory
+++ include/memory
@@ -610,7 +610,7 @@
     #include <cassert>
 #endif
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !defined(_LIBCPP_HAS_NO_THREADS)
 #  include <atomic>
 #endif
 
Index: include/mutex
===================================================================
--- include/mutex
+++ include/mutex
@@ -187,6 +187,8 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 class _LIBCPP_TYPE_VIS recursive_mutex
 {
     pthread_mutex_t __m_;
@@ -425,6 +427,8 @@
 
 #endif  // _LIBCPP_HAS_NO_VARIADICS
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 struct _LIBCPP_TYPE_VIS_ONLY once_flag;
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
Index: include/shared_mutex
===================================================================
--- include/shared_mutex
+++ include/shared_mutex
@@ -112,6 +112,10 @@
 #pragma GCC system_header
 #endif
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <shared_mutex> is not supported on this single threaded system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 class _LIBCPP_TYPE_VIS shared_timed_mutex
@@ -414,6 +418,8 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif  // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_STD_VER > 11
 
 #endif  // _LIBCPP_SHARED_MUTEX
Index: include/thread
===================================================================
--- include/thread
+++ include/thread
@@ -106,6 +106,10 @@
 
 #define __STDCPP_THREADS__ __cplusplus
 
+#ifdef _LIBCPP_HAS_NO_THREADS
+#error <thread> is not supported on this system
+#else // !_LIBCPP_HAS_NO_THREADS
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Tp>
@@ -455,4 +459,6 @@
 
 _LIBCPP_END_NAMESPACE_STD
 
+#endif // !_LIBCPP_HAS_NO_THREADS
+
 #endif  // _LIBCPP_THREAD
Index: src/algorithm.cpp
===================================================================
--- src/algorithm.cpp
+++ src/algorithm.cpp
@@ -47,12 +47,16 @@
 
 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;
+#endif
 unsigned __rs_default::__c_ = 0;
 
 __rs_default::__rs_default()
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     pthread_mutex_lock(&__rs_mut);
+#endif
     __c_ = 1;
 }
 
@@ -63,8 +67,12 @@
 
 __rs_default::~__rs_default()
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     if (--__c_ == 0)
         pthread_mutex_unlock(&__rs_mut);
+#else
+    --__c_;
+#endif
 }
 
 __rs_default::result_type
Index: src/condition_variable.cpp
===================================================================
--- src/condition_variable.cpp
+++ src/condition_variable.cpp
@@ -7,11 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "condition_variable"
 #include "thread"
 #include "system_error"
 #include "cassert"
 
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 condition_variable::~condition_variable()
@@ -79,3 +84,6 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
Index: src/debug.cpp
===================================================================
--- src/debug.cpp
+++ src/debug.cpp
@@ -35,6 +35,7 @@
 namespace
 {
 
+#ifndef _LIBCPP_HAS_NO_THREADS
 typedef mutex mutex_type;
 typedef lock_guard<mutex_type> WLock;
 typedef lock_guard<mutex_type> RLock;
@@ -45,6 +46,7 @@
     static mutex_type m;
     return m;
 }
+#endif // !_LIBCPP_HAS_NO_THREADS
 
 }  // unnamed namespace
 
@@ -108,7 +110,9 @@
 void*
 __libcpp_db::__find_c_from_i(void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database.");
     return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
@@ -117,7 +121,9 @@
 void
 __libcpp_db::__insert_ic(void* __i, const void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cbeg_ == __cend_)
         return;
     size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -138,7 +144,9 @@
 __c_node*
 __libcpp_db::__insert_c(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
     {
         size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
@@ -184,7 +192,9 @@
 void
 __libcpp_db::__erase_i(void* __i)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__ibeg_ != __iend_)
     {
         size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
@@ -215,7 +225,9 @@
 void
 __libcpp_db::__invalidate_all(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cend_ != __cbeg_)
     {
         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -239,10 +251,14 @@
 __c_node*
 __libcpp_db::__find_c_and_lock(void* __c) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     mut().lock();
+#endif
     if (__cend_ == __cbeg_)
     {
+#ifndef _LIBCPP_HAS_NO_THREADS
         mut().unlock();
+#endif
         return nullptr;
     }
     size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -249,7 +265,9 @@
     __c_node* p = __cbeg_[hc];
     if (p == nullptr)
     {
+#ifndef _LIBCPP_HAS_NO_THREADS
         mut().unlock();
+#endif
         return nullptr;
     }
     while (p->__c_ != __c)
@@ -257,7 +275,9 @@
         p = p->__next_;
         if (p == nullptr)
         {
+#ifndef _LIBCPP_HAS_NO_THREADS
             mut().unlock();
+#endif
             return nullptr;
         }
     }
@@ -281,13 +301,17 @@
 void
 __libcpp_db::unlock() const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     mut().unlock();
+#endif
 }
 
 void
 __libcpp_db::__erase_c(void* __c)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     if (__cend_ != __cbeg_)
     {
         size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -322,7 +346,9 @@
 void
 __libcpp_db::__iterator_copy(void* __i, const void* __i0)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     __i_node* i0 = __find_iterator(__i0);
     __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
@@ -348,7 +374,9 @@
 bool
 __libcpp_db::__dereferenceable(const void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
 }
@@ -356,7 +384,9 @@
 bool
 __libcpp_db::__decrementable(const void* __i) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
 }
@@ -364,7 +394,9 @@
 bool
 __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
 }
@@ -372,7 +404,9 @@
 bool
 __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
 }
@@ -380,7 +414,9 @@
 bool
 __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     RLock _(mut());
+#endif
     __i_node* i = __find_iterator(__i);
     __i_node* j = __find_iterator(__j);
     __c_node* ci = i != nullptr ? i->__c_ : nullptr;
@@ -391,7 +427,9 @@
 void
 __libcpp_db::swap(void* c1, void* c2)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
     __c_node* p1 = __cbeg_[hc];
     _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
@@ -420,7 +458,9 @@
 void
 __libcpp_db::__insert_i(void* __i)
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     WLock _(mut());
+#endif
     __insert_iterator(__i);
 }
 
Index: src/future.cpp
===================================================================
--- src/future.cpp
+++ src/future.cpp
@@ -7,6 +7,10 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "future"
 #include "string"
 
@@ -298,3 +302,7 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+
Index: src/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -9,8 +9,10 @@
 
 #define _LIBCPP_BUILDING_MEMORY
 #include "memory"
+#ifndef _LIBCPP_HAS_NO_THREADS
 #include "mutex"
 #include "thread"
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
@@ -119,7 +121,7 @@
 
 #endif  // _LIBCPP_NO_RTTI
 
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
 
 static const std::size_t __sp_mut_count = 16;
 static pthread_mutex_t mut_back_imp[__sp_mut_count] =
@@ -172,7 +174,7 @@
     return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
 }
 
-#endif // __has_feature(cxx_atomic)
+#endif // __has_feature(cxx_atomic) && !_LIBCPP_HAS_NO_THREADS
 
 void
 declare_reachable(void*)
Index: src/mutex.cpp
===================================================================
--- src/mutex.cpp
+++ src/mutex.cpp
@@ -14,6 +14,7 @@
 #include "cassert"
 
 _LIBCPP_BEGIN_NAMESPACE_STD
+#ifndef _LIBCPP_HAS_NO_THREADS
 
 const defer_lock_t  defer_lock = {};
 const try_to_lock_t try_to_lock = {};
@@ -206,6 +207,8 @@
     }
 }
 
+#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
@@ -212,15 +215,19 @@
 // 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
 
 void
 __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
 {
+#ifndef _LIBCPP_HAS_NO_THREADS
     pthread_mutex_lock(&mut);
     while (flag == 1)
         pthread_cond_wait(&cv, &mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
     if (flag == 0)
     {
 #ifndef _LIBCPP_NO_EXCEPTIONS
@@ -228,26 +235,38 @@
         {
 #endif  // _LIBCPP_NO_EXCEPTIONS
             flag = 1;
+#ifndef _LIBCPP_HAS_NO_THREADS
             pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
             func(arg);
+#ifndef _LIBCPP_HAS_NO_THREADS
             pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
             flag = ~0ul;
+#ifndef _LIBCPP_HAS_NO_THREADS
             pthread_mutex_unlock(&mut);
             pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_HAS_NO_THREADS
 #ifndef _LIBCPP_NO_EXCEPTIONS
         }
         catch (...)
         {
+#ifndef _LIBCPP_HAS_NO_THREADS
             pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
             flag = 0ul;
+#ifndef _LIBCPP_HAS_NO_THREADS
             pthread_mutex_unlock(&mut);
             pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_HAS_NO_THREADS
             throw;
         }
 #endif  // _LIBCPP_NO_EXCEPTIONS
     }
+#ifndef _LIBCPP_HAS_NO_THREADS
     else
         pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_HAS_NO_THREADS
 }
 
 _LIBCPP_END_NAMESPACE_STD
Index: src/shared_mutex.cpp
===================================================================
--- src/shared_mutex.cpp
+++ src/shared_mutex.cpp
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #define _LIBCPP_BUILDING_SHARED_MUTEX
 #include "shared_mutex"
 
@@ -99,3 +102,7 @@
 
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
+
+
Index: src/thread.cpp
===================================================================
--- src/thread.cpp
+++ src/thread.cpp
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "__config"
+#ifndef _LIBCPP_HAS_NO_THREADS
+
 #include "thread"
 #include "exception"
 #include "vector"
@@ -27,6 +30,7 @@
 #include <windows.h>
 #endif
 
+
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 thread::~thread()
@@ -225,3 +229,5 @@
 }
 
 _LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_HAS_NO_THREADS
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to