Hi Joerg,
I'm finally resurrecting this...
http://reviews.llvm.org/D3969
Files:
include/__config
include/__mutex_base
include/condition_variable
include/future
include/mutex
include/shared_mutex
include/thread
src/algorithm.cpp
src/chrono.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(_POSIX_THREADS) && _POSIX_THREADS > 0
+# define _LIBCPP_SINGLE_THREADED 0
+#else
+# define _LIBCPP_SINGLE_THREADED 1
+#endif
+
#ifdef _WIN32
// only really useful for a DLL
Index: include/__mutex_base
===================================================================
--- include/__mutex_base
+++ include/__mutex_base
@@ -22,12 +22,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
+
class _LIBCPP_TYPE_VIS mutex
{
pthread_mutex_t __m_;
public:
_LIBCPP_INLINE_VISIBILITY
+
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
#else
@@ -315,6 +318,7 @@
void __do_timed_wait(unique_lock<mutex>& __lk,
chrono::time_point<chrono::system_clock, chrono::nanoseconds>) _NOEXCEPT;
};
+#endif // !_LIBCPP_SINGLE_THREADED
template <class _To, class _Rep, class _Period>
inline _LIBCPP_INLINE_VISIBILITY
@@ -332,6 +336,7 @@
return __r;
}
+#if !_LIBCPP_SINGLE_THREADED
template <class _Predicate>
void
condition_variable::wait(unique_lock<mutex>& __lk, _Predicate __pred)
@@ -396,6 +401,8 @@
_VSTD::move(__pred));
}
+#endif // !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___MUTEX_BASE
Index: include/condition_variable
===================================================================
--- include/condition_variable
+++ include/condition_variable
@@ -115,6 +115,8 @@
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS condition_variable_any
@@ -253,4 +255,6 @@
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_CONDITION_VARIABLE
Index: include/future
===================================================================
--- include/future
+++ include/future
@@ -374,6 +374,8 @@
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
//enum class future_errc
@@ -2612,4 +2614,6 @@
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_FUTURE
Index: include/mutex
===================================================================
--- include/mutex
+++ include/mutex
@@ -187,6 +187,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
+
class _LIBCPP_TYPE_VIS recursive_mutex
{
pthread_mutex_t __m_;
@@ -425,6 +427,8 @@
#endif // _LIBCPP_HAS_NO_VARIADICS
+#endif // !_LIBCPP_SINGLE_THREADED
+
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,8 @@
#pragma GCC system_header
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS shared_timed_mutex
@@ -414,6 +416,8 @@
_LIBCPP_END_NAMESPACE_STD
+#endif // _LIBC_HAS_PTHREADS
+
#endif // _LIBCPP_STD_VER > 11
#endif // _LIBCPP_SHARED_MUTEX
Index: include/thread
===================================================================
--- include/thread
+++ include/thread
@@ -106,6 +106,8 @@
#define __STDCPP_THREADS__ __cplusplus
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
@@ -455,4 +457,6 @@
_LIBCPP_END_NAMESPACE_STD
+#endif // !_LIBCPP_SINGLE_THREADED
+
#endif // _LIBCPP_THREAD
Index: src/algorithm.cpp
===================================================================
--- src/algorithm.cpp
+++ src/algorithm.cpp
@@ -48,12 +48,16 @@
template unsigned __sort5<__less<long double>&, long double*>(long double*, long double*, long double*, long double*, long double*, __less<long double>&);
+#if !_LIBCPP_SINGLE_THREADED
static pthread_mutex_t __rs_mut = PTHREAD_MUTEX_INITIALIZER;
+#endif
unsigned __rs_default::__c_ = 0;
__rs_default::__rs_default()
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&__rs_mut);
+#endif
__c_ = 1;
}
@@ -64,8 +68,12 @@
__rs_default::~__rs_default()
{
+#if !_LIBCPP_SINGLE_THREADED
if (--__c_ == 0)
pthread_mutex_unlock(&__rs_mut);
+#else
+ --__c_;
+#endif
}
__rs_default::result_type
Index: src/chrono.cpp
===================================================================
--- src/chrono.cpp
+++ src/chrono.cpp
@@ -16,6 +16,7 @@
#include <system_error> // __throw_system_error
#include <time.h> // clock_gettime, CLOCK_MONOTONIC
#endif // __APPLE__
+#include <unistd.h>
_LIBCPP_BEGIN_NAMESPACE_STD
Index: src/condition_variable.cpp
===================================================================
--- src/condition_variable.cpp
+++ src/condition_variable.cpp
@@ -12,6 +12,8 @@
#include "system_error"
#include "cassert"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
condition_variable::~condition_variable()
@@ -79,3 +81,6 @@
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
Index: src/debug.cpp
===================================================================
--- src/debug.cpp
+++ src/debug.cpp
@@ -35,6 +35,7 @@
namespace
{
+#if !_LIBCPP_SINGLE_THREADED
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_SINGLE_THREADED
} // unnamed namespace
@@ -108,16 +110,20 @@
void*
__libcpp_db::__find_c_from_i(void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
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;
}
void
__libcpp_db::__insert_ic(void* __i, const void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
if (__cend_ != __cbeg_)
{
size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
@@ -239,25 +251,33 @@
__c_node*
__libcpp_db::__find_c_and_lock(void* __c) const
{
+#if !_LIBCPP_SINGLE_THREADED
mut().lock();
+#endif
if (__cend_ == __cbeg_)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
__c_node* p = __cbeg_[hc];
if (p == nullptr)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
while (p->__c_ != __c)
{
p = p->__next_;
if (p == nullptr)
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
return nullptr;
}
}
@@ -281,13 +301,17 @@
void
__libcpp_db::unlock() const
{
+#if !_LIBCPP_SINGLE_THREADED
mut().unlock();
+#endif
}
void
__libcpp_db::__erase_c(void* __c)
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
__i_node* i0 = __find_iterator(__i0);
__c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
@@ -348,39 +374,49 @@
bool
__libcpp_db::__dereferenceable(const void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
}
bool
__libcpp_db::__decrementable(const void* __i) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
}
bool
__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
}
bool
__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
{
+#if !_LIBCPP_SINGLE_THREADED
RLock _(mut());
+#endif
__i_node* i = __find_iterator(__i);
return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
}
bool
__libcpp_db::__less_than_comparable(const void* __i, const void* __j) const
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
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)
{
+#if !_LIBCPP_SINGLE_THREADED
WLock _(mut());
+#endif
__insert_iterator(__i);
}
Index: src/future.cpp
===================================================================
--- src/future.cpp
+++ src/future.cpp
@@ -10,6 +10,8 @@
#include "future"
#include "string"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_HIDDEN __future_error_category
@@ -298,3 +300,7 @@
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
+
Index: src/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -119,7 +119,7 @@
#endif // _LIBCPP_NO_RTTI
-#if __has_feature(cxx_atomic)
+#if __has_feature(cxx_atomic) && !_LIBCPP_SINGLE_THREADED
static const std::size_t __sp_mut_count = 16;
static pthread_mutex_t mut_back_imp[__sp_mut_count] =
@@ -172,7 +172,7 @@
return muts[hash<const void*>()(p) & (__sp_mut_count-1)];
}
-#endif // __has_feature(cxx_atomic)
+#endif // __has_feature(cxx_atomic) && !_LIBCPP_SINGLE_THREADED
void
declare_reachable(void*)
Index: src/mutex.cpp
===================================================================
--- src/mutex.cpp
+++ src/mutex.cpp
@@ -14,6 +14,7 @@
#include "cassert"
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !_LIBCPP_SINGLE_THREADED
const defer_lock_t defer_lock = {};
const try_to_lock_t try_to_lock = {};
@@ -206,48 +207,66 @@
}
}
+#endif // !_LIBCPP_SINGLE_THREADED
+
// 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.
+#if !_LIBCPP_SINGLE_THREADED
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*))
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
while (flag == 1)
pthread_cond_wait(&cv, &mut);
+#endif // !_LIBCPP_SINGLE_THREADED
if (flag == 0)
{
#ifndef _LIBCPP_NO_EXCEPTIONS
try
{
#endif // _LIBCPP_NO_EXCEPTIONS
flag = 1;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
func(arg);
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
flag = ~0ul;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_SINGLE_THREADED
#ifndef _LIBCPP_NO_EXCEPTIONS
}
catch (...)
{
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_lock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
flag = 0ul;
+#if !_LIBCPP_SINGLE_THREADED
pthread_mutex_unlock(&mut);
pthread_cond_broadcast(&cv);
+#endif // !_LIBCPP_SINGLE_THREADED
throw;
}
#endif // _LIBCPP_NO_EXCEPTIONS
}
+#if !_LIBCPP_SINGLE_THREADED
else
pthread_mutex_unlock(&mut);
+#endif // !_LIBCPP_SINGLE_THREADED
}
_LIBCPP_END_NAMESPACE_STD
Index: src/shared_mutex.cpp
===================================================================
--- src/shared_mutex.cpp
+++ src/shared_mutex.cpp
@@ -10,6 +10,8 @@
#define _LIBCPP_BUILDING_SHARED_MUTEX
#include "shared_mutex"
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
shared_timed_mutex::shared_timed_mutex()
@@ -99,3 +101,7 @@
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
+
+
Index: src/thread.cpp
===================================================================
--- src/thread.cpp
+++ src/thread.cpp
@@ -27,6 +27,8 @@
#include <windows.h>
#endif
+#if !_LIBCPP_SINGLE_THREADED
+
_LIBCPP_BEGIN_NAMESPACE_STD
thread::~thread()
@@ -225,3 +227,5 @@
}
_LIBCPP_END_NAMESPACE_STD
+
+#endif // !_LIBCPP_SINGLE_THREADED
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits