mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 18:26:37 +00:00
Refactor pthread usage of libcxx.
This patch extracts out all the pthread dependencies of libcxx into the new header __threading_support. The motivation is to make it easy to re-target libcxx into platforms that do not support pthread. Original patch from Fulvio Esposito (fulvio.esposito@outlook.com) - D11781 Applied with tweaks - D19412 Change-Id: I301111f0075de93dd8129416e06babc195aa936b llvm-svn: 268734
This commit is contained in:
parent
a463d31a64
commit
c7e4239fab
@ -812,6 +812,20 @@ extern "C" void __sanitizer_annotate_contiguous_container(
|
||||
# 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_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.
|
||||
|
@ -14,9 +14,7 @@
|
||||
#include <__config>
|
||||
#include <chrono>
|
||||
#include <system_error>
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <__threading_support>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
@ -36,14 +34,14 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
class _LIBCPP_TYPE_VIS _LIBCPP_THREAD_SAFETY_ANNOTATION(capability("mutex")) mutex
|
||||
{
|
||||
pthread_mutex_t __m_;
|
||||
__libcpp_mutex_t __m_;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
|
||||
constexpr mutex() _NOEXCEPT : __m_(PTHREAD_MUTEX_INITIALIZER) {}
|
||||
constexpr mutex() _NOEXCEPT : __m_(_LIBCPP_MUTEX_INITIALIZER) {}
|
||||
#else
|
||||
mutex() _NOEXCEPT {__m_ = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;}
|
||||
mutex() _NOEXCEPT {__m_ = (__libcpp_mutex_t)_LIBCPP_MUTEX_INITIALIZER;}
|
||||
#endif
|
||||
~mutex();
|
||||
|
||||
@ -56,7 +54,7 @@ public:
|
||||
bool try_lock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true));
|
||||
void unlock() _NOEXCEPT _LIBCPP_THREAD_SAFETY_ANNOTATION(release_capability());
|
||||
|
||||
typedef pthread_mutex_t* native_handle_type;
|
||||
typedef __libcpp_mutex_t* native_handle_type;
|
||||
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__m_;}
|
||||
};
|
||||
|
||||
@ -276,13 +274,13 @@ _LIBCPP_DECLARE_STRONG_ENUM_EPILOG(cv_status)
|
||||
|
||||
class _LIBCPP_TYPE_VIS condition_variable
|
||||
{
|
||||
pthread_cond_t __cv_;
|
||||
__libcpp_condvar_t __cv_;
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
#ifndef _LIBCPP_HAS_NO_CONSTEXPR
|
||||
constexpr condition_variable() : __cv_(PTHREAD_COND_INITIALIZER) {}
|
||||
constexpr condition_variable() : __cv_(_LIBCPP_CONDVAR_INITIALIZER) {}
|
||||
#else
|
||||
condition_variable() {__cv_ = (pthread_cond_t)PTHREAD_COND_INITIALIZER;}
|
||||
condition_variable() {__cv_ = (__libcpp_condvar_t)_LIBCPP_CONDVAR_INITIALIZER;}
|
||||
#endif
|
||||
~condition_variable();
|
||||
|
||||
@ -321,7 +319,7 @@ public:
|
||||
const chrono::duration<_Rep, _Period>& __d,
|
||||
_Predicate __pred);
|
||||
|
||||
typedef pthread_cond_t* native_handle_type;
|
||||
typedef __libcpp_condvar_t* native_handle_type;
|
||||
_LIBCPP_INLINE_VISIBILITY native_handle_type native_handle() {return &__cv_;}
|
||||
|
||||
private:
|
||||
|
205
libcxx/include/__threading_support
Normal file
205
libcxx/include/__threading_support
Normal file
@ -0,0 +1,205 @@
|
||||
// -*- 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_THREADING_SUPPORT
|
||||
#define _LIBCPP_THREADING_SUPPORT
|
||||
|
||||
#include <__config>
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#if defined(_LIBCPP_THREAD_API_PTHREAD)
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if defined(_LIBCPP_THREAD_API_PTHREAD)
|
||||
|
||||
// Mutex
|
||||
#define _LIBCPP_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t __libcpp_mutex_t;
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_recursive_mutex_init(__libcpp_mutex_t* __m)
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
int __ec = pthread_mutexattr_init(&attr);
|
||||
if (__ec) return __ec;
|
||||
__ec = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
if (__ec)
|
||||
{
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return __ec;
|
||||
}
|
||||
__ec = pthread_mutex_init(__m, &attr);
|
||||
if (__ec)
|
||||
{
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
return __ec;
|
||||
}
|
||||
__ec = pthread_mutexattr_destroy(&attr);
|
||||
if (__ec)
|
||||
{
|
||||
pthread_mutex_destroy(__m);
|
||||
return __ec;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_mutex_lock(__libcpp_mutex_t* __m)
|
||||
{
|
||||
return pthread_mutex_lock(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_mutex_trylock(__libcpp_mutex_t* __m)
|
||||
{
|
||||
return pthread_mutex_trylock(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_mutex_unlock(__libcpp_mutex_t* __m)
|
||||
{
|
||||
return pthread_mutex_unlock(__m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_mutex_destroy(__libcpp_mutex_t* __m)
|
||||
{
|
||||
return pthread_mutex_destroy(__m);
|
||||
}
|
||||
|
||||
// Condition variable
|
||||
#define _LIBCPP_CONDVAR_INITIALIZER PTHREAD_COND_INITIALIZER
|
||||
typedef pthread_cond_t __libcpp_condvar_t;
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_condvar_signal(__libcpp_condvar_t* __cv)
|
||||
{
|
||||
return pthread_cond_signal(__cv);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_condvar_broadcast(__libcpp_condvar_t* __cv)
|
||||
{
|
||||
return pthread_cond_broadcast(__cv);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_condvar_wait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m)
|
||||
{
|
||||
return pthread_cond_wait(__cv, __m);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_condvar_timedwait(__libcpp_condvar_t* __cv, __libcpp_mutex_t* __m, timespec* __ts)
|
||||
{
|
||||
return pthread_cond_timedwait(__cv, __m, __ts);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_condvar_destroy(__libcpp_condvar_t* __cv)
|
||||
{
|
||||
return pthread_cond_destroy(__cv);
|
||||
}
|
||||
|
||||
// Thread id
|
||||
typedef pthread_t __libcpp_thread_id;
|
||||
|
||||
// Returns non-zero if the thread ids are equal, otherwise 0
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return pthread_equal(t1, t2) != 0;
|
||||
}
|
||||
|
||||
// Returns non-zero if t1 < t2, otherwise 0
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2)
|
||||
{
|
||||
return t1 < t2;
|
||||
}
|
||||
|
||||
// Thread
|
||||
typedef pthread_t __libcpp_thread_t;
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_thread_create(__libcpp_thread_t* __t, void* (*__func)(void*), void* __arg)
|
||||
{
|
||||
return pthread_create(__t, 0, __func, __arg);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
__libcpp_thread_id __libcpp_thread_get_current_id()
|
||||
{
|
||||
return pthread_self();
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
__libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t* __t)
|
||||
{
|
||||
return *__t;
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_thread_join(__libcpp_thread_t* __t)
|
||||
{
|
||||
return pthread_join(*__t, 0);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_thread_detach(__libcpp_thread_t* __t)
|
||||
{
|
||||
return pthread_detach(*__t);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
void __libcpp_thread_yield()
|
||||
{
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
// Thread local storage
|
||||
typedef pthread_key_t __libcpp_tl_key;
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
int __libcpp_tl_create(__libcpp_tl_key* __key, void (*__at_exit)(void*))
|
||||
{
|
||||
return pthread_key_create(__key, __at_exit);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
void* __libcpp_tl_get(__libcpp_tl_key __key)
|
||||
{
|
||||
return pthread_getspecific(__key);
|
||||
}
|
||||
|
||||
inline _LIBCPP_ALWAYS_INLINE
|
||||
void __libcpp_tl_set(__libcpp_tl_key __key, void* __p)
|
||||
{
|
||||
pthread_setspecific(__key, __p);
|
||||
}
|
||||
|
||||
#else // !_LIBCPP_THREAD_API_PTHREAD
|
||||
#error "No thread API selected."
|
||||
#endif
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_THREADS
|
||||
|
||||
#endif // _LIBCPP_THREADING_SUPPORT
|
@ -179,9 +179,7 @@ template<class Callable, class ...Args>
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
#include <tuple>
|
||||
#endif
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
#include <sched.h>
|
||||
#endif
|
||||
#include <__threading_support>
|
||||
|
||||
#include <__undef_min_max>
|
||||
|
||||
@ -195,7 +193,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
class _LIBCPP_TYPE_VIS recursive_mutex
|
||||
{
|
||||
pthread_mutex_t __m_;
|
||||
__libcpp_mutex_t __m_;
|
||||
|
||||
public:
|
||||
recursive_mutex();
|
||||
@ -210,7 +208,7 @@ public:
|
||||
bool try_lock() _NOEXCEPT;
|
||||
void unlock() _NOEXCEPT;
|
||||
|
||||
typedef pthread_mutex_t* native_handle_type;
|
||||
typedef __libcpp_mutex_t* native_handle_type;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
native_handle_type native_handle() {return &__m_;}
|
||||
};
|
||||
@ -262,7 +260,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex
|
||||
mutex __m_;
|
||||
condition_variable __cv_;
|
||||
size_t __count_;
|
||||
pthread_t __id_;
|
||||
__libcpp_thread_id __id_;
|
||||
public:
|
||||
recursive_timed_mutex();
|
||||
~recursive_timed_mutex();
|
||||
@ -288,9 +286,9 @@ bool
|
||||
recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t)
|
||||
{
|
||||
using namespace chrono;
|
||||
pthread_t __id = pthread_self();
|
||||
__libcpp_thread_id __id = __libcpp_thread_get_current_id();
|
||||
unique_lock<mutex> lk(__m_);
|
||||
if (pthread_equal(__id, __id_))
|
||||
if (__libcpp_thread_id_equal(__id, __id_))
|
||||
{
|
||||
if (__count_ == numeric_limits<size_t>::max())
|
||||
return false;
|
||||
@ -362,7 +360,7 @@ lock(_L0& __l0, _L1& __l1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sched_yield();
|
||||
__libcpp_thread_yield();
|
||||
{
|
||||
unique_lock<_L1> __u1(__l1);
|
||||
if (__l0.try_lock())
|
||||
@ -371,7 +369,7 @@ lock(_L0& __l0, _L1& __l1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sched_yield();
|
||||
__libcpp_thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
@ -396,7 +394,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
|
||||
}
|
||||
}
|
||||
++__i;
|
||||
sched_yield();
|
||||
__libcpp_thread_yield();
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
@ -412,7 +410,7 @@ __lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3)
|
||||
__i = 0;
|
||||
else
|
||||
__i += 2;
|
||||
sched_yield();
|
||||
__libcpp_thread_yield();
|
||||
break;
|
||||
default:
|
||||
__lock_first(__i - 2, __l2, __l3..., __l0, __l1);
|
||||
|
@ -98,8 +98,7 @@ void sleep_for(const chrono::duration<Rep, Period>& rel_time);
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
#include <tuple>
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <__threading_support>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
@ -137,7 +136,7 @@ public:
|
||||
template <class _Tp>
|
||||
class __thread_specific_ptr
|
||||
{
|
||||
pthread_key_t __key_;
|
||||
__libcpp_tl_key __key_;
|
||||
|
||||
// Only __thread_local_data() may construct a __thread_specific_ptr
|
||||
// and only with _Tp == __thread_struct.
|
||||
@ -155,7 +154,7 @@ public:
|
||||
~__thread_specific_ptr();
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer get() const {return static_cast<_Tp*>(pthread_getspecific(__key_));}
|
||||
pointer get() const {return static_cast<_Tp*>(__libcpp_tl_get(__key_));}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer operator*() const {return *get();}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -174,7 +173,9 @@ __thread_specific_ptr<_Tp>::__at_thread_exit(void* __p)
|
||||
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_tl_create(
|
||||
&__key_,
|
||||
&__thread_specific_ptr::__at_thread_exit);
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
if (__ec)
|
||||
throw system_error(error_code(__ec, system_category()),
|
||||
@ -196,7 +197,7 @@ typename __thread_specific_ptr<_Tp>::pointer
|
||||
__thread_specific_ptr<_Tp>::release()
|
||||
{
|
||||
pointer __p = get();
|
||||
pthread_setspecific(__key_, 0);
|
||||
__libcpp_tl_set(__key_, nullptr);
|
||||
return __p;
|
||||
}
|
||||
|
||||
@ -205,7 +206,7 @@ void
|
||||
__thread_specific_ptr<_Tp>::reset(pointer __p)
|
||||
{
|
||||
pointer __p_old = get();
|
||||
pthread_setspecific(__key_, __p);
|
||||
__libcpp_tl_set(__key_, __p);
|
||||
delete __p_old;
|
||||
}
|
||||
|
||||
@ -226,7 +227,7 @@ class _LIBCPP_TYPE_VIS_ONLY __thread_id
|
||||
// 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_thread_id __id_;
|
||||
|
||||
public:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
@ -234,13 +235,13 @@ public:
|
||||
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return __x.__id_ == __y.__id_;}
|
||||
{return __libcpp_thread_id_equal(__x.__id_, __y.__id_);}
|
||||
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_thread_id_less(__x.__id_, __y.__id_);}
|
||||
friend _LIBCPP_INLINE_VISIBILITY
|
||||
bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT
|
||||
{return !(__y < __x);}
|
||||
@ -260,7 +261,7 @@ public:
|
||||
|
||||
private:
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__thread_id(pthread_t __id) : __id_(__id) {}
|
||||
__thread_id(__libcpp_thread_id __id) : __id_(__id) {}
|
||||
|
||||
friend __thread_id this_thread::get_id() _NOEXCEPT;
|
||||
friend class _LIBCPP_TYPE_VIS thread;
|
||||
@ -274,7 +275,7 @@ struct _LIBCPP_TYPE_VIS_ONLY hash<__thread_id>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
size_t operator()(__thread_id __v) const
|
||||
{
|
||||
return hash<pthread_t>()(__v.__id_);
|
||||
return hash<__libcpp_thread_id>()(__v.__id_);
|
||||
}
|
||||
};
|
||||
|
||||
@ -285,20 +286,20 @@ inline _LIBCPP_INLINE_VISIBILITY
|
||||
__thread_id
|
||||
get_id() _NOEXCEPT
|
||||
{
|
||||
return pthread_self();
|
||||
return __libcpp_thread_get_current_id();
|
||||
}
|
||||
|
||||
} // this_thread
|
||||
|
||||
class _LIBCPP_TYPE_VIS thread
|
||||
{
|
||||
pthread_t __t_;
|
||||
__libcpp_thread_t __t_;
|
||||
|
||||
thread(const thread&);
|
||||
thread& operator=(const thread&);
|
||||
public:
|
||||
typedef __thread_id id;
|
||||
typedef pthread_t native_handle_type;
|
||||
typedef __libcpp_thread_t native_handle_type;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
thread() _NOEXCEPT : __t_(0) {}
|
||||
@ -330,7 +331,7 @@ public:
|
||||
void join();
|
||||
void detach();
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
id get_id() const _NOEXCEPT {return __t_;}
|
||||
id get_id() const _NOEXCEPT {return __libcpp_thread_get_id(&__t_);}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
native_handle_type native_handle() _NOEXCEPT {return __t_;}
|
||||
|
||||
@ -370,7 +371,7 @@ thread::thread(_Fp&& __f, _Args&&... __args)
|
||||
new _Gp(std::move(__tsp),
|
||||
__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_thread_create(&__t_, &__thread_proxy<_Gp>, __p.get());
|
||||
if (__ec == 0)
|
||||
__p.release();
|
||||
else
|
||||
@ -405,7 +406,7 @@ thread::thread(_Fp __f)
|
||||
typedef __thread_invoke_pair<_Fp> _InvokePair;
|
||||
typedef std::unique_ptr<_InvokePair> _PairPtr;
|
||||
_PairPtr __pp(new _InvokePair(__f));
|
||||
int __ec = pthread_create(&__t_, 0, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
|
||||
int __ec = __libcpp_thread_create(&__t_, &__thread_proxy_cxx03<_InvokePair>, __pp.get());
|
||||
if (__ec == 0)
|
||||
__pp.release();
|
||||
else
|
||||
@ -480,7 +481,7 @@ sleep_until(const chrono::time_point<chrono::steady_clock, _Duration>& __t)
|
||||
}
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
void yield() _NOEXCEPT {sched_yield();}
|
||||
void yield() _NOEXCEPT {__libcpp_thread_yield();}
|
||||
|
||||
} // this_thread
|
||||
|
||||
|
@ -48,14 +48,14 @@ template bool __insertion_sort_incomplete<__less<long double>&, long double*>(lo
|
||||
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 __libcpp_mutex_t __rs_mut = _LIBCPP_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
unsigned __rs_default::__c_ = 0;
|
||||
|
||||
__rs_default::__rs_default()
|
||||
{
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
pthread_mutex_lock(&__rs_mut);
|
||||
__libcpp_mutex_lock(&__rs_mut);
|
||||
#endif
|
||||
__c_ = 1;
|
||||
}
|
||||
@ -69,7 +69,7 @@ __rs_default::~__rs_default()
|
||||
{
|
||||
#ifndef _LIBCPP_HAS_NO_THREADS
|
||||
if (--__c_ == 0)
|
||||
pthread_mutex_unlock(&__rs_mut);
|
||||
__libcpp_mutex_unlock(&__rs_mut);
|
||||
#else
|
||||
--__c_;
|
||||
#endif
|
||||
|
@ -20,19 +20,19 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
condition_variable::~condition_variable()
|
||||
{
|
||||
pthread_cond_destroy(&__cv_);
|
||||
__libcpp_condvar_destroy(&__cv_);
|
||||
}
|
||||
|
||||
void
|
||||
condition_variable::notify_one() _NOEXCEPT
|
||||
{
|
||||
pthread_cond_signal(&__cv_);
|
||||
__libcpp_condvar_signal(&__cv_);
|
||||
}
|
||||
|
||||
void
|
||||
condition_variable::notify_all() _NOEXCEPT
|
||||
{
|
||||
pthread_cond_broadcast(&__cv_);
|
||||
__libcpp_condvar_broadcast(&__cv_);
|
||||
}
|
||||
|
||||
void
|
||||
@ -41,7 +41,7 @@ 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 = __libcpp_condvar_wait(&__cv_, lk.mutex()->native_handle());
|
||||
if (ec)
|
||||
__throw_system_error(ec, "condition_variable wait failed");
|
||||
}
|
||||
@ -71,7 +71,7 @@ condition_variable::__do_timed_wait(unique_lock<mutex>& lk,
|
||||
ts.tv_sec = ts_sec_max;
|
||||
ts.tv_nsec = giga::num - 1;
|
||||
}
|
||||
int ec = pthread_cond_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);
|
||||
int ec = __libcpp_condvar_timedwait(&__cv_, lk.mutex()->native_handle(), &ts);
|
||||
if (ec != 0 && ec != ETIMEDOUT)
|
||||
__throw_system_error(ec, "condition_variable timed_wait failed");
|
||||
}
|
||||
|
@ -127,12 +127,12 @@ __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT
|
||||
#if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
|
||||
static const std::size_t __sp_mut_count = 16;
|
||||
static pthread_mutex_t mut_back_imp[__sp_mut_count] =
|
||||
static __libcpp_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
|
||||
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
|
||||
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
|
||||
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER,
|
||||
_LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER, _LIBCPP_MUTEX_INITIALIZER
|
||||
};
|
||||
|
||||
static mutex* mut_back = reinterpret_cast<std::mutex*>(mut_back_imp);
|
||||
|
@ -23,13 +23,13 @@ const adopt_lock_t adopt_lock = {};
|
||||
|
||||
mutex::~mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&__m_);
|
||||
__libcpp_mutex_destroy(&__m_);
|
||||
}
|
||||
|
||||
void
|
||||
mutex::lock()
|
||||
{
|
||||
int ec = pthread_mutex_lock(&__m_);
|
||||
int ec = __libcpp_mutex_lock(&__m_);
|
||||
if (ec)
|
||||
__throw_system_error(ec, "mutex lock failed");
|
||||
}
|
||||
@ -37,13 +37,13 @@ mutex::lock()
|
||||
bool
|
||||
mutex::try_lock() _NOEXCEPT
|
||||
{
|
||||
return pthread_mutex_trylock(&__m_) == 0;
|
||||
return __libcpp_mutex_trylock(&__m_) == 0;
|
||||
}
|
||||
|
||||
void
|
||||
mutex::unlock() _NOEXCEPT
|
||||
{
|
||||
int ec = pthread_mutex_unlock(&__m_);
|
||||
int ec = __libcpp_mutex_unlock(&__m_);
|
||||
(void)ec;
|
||||
assert(ec == 0);
|
||||
}
|
||||
@ -52,36 +52,14 @@ mutex::unlock() _NOEXCEPT
|
||||
|
||||
recursive_mutex::recursive_mutex()
|
||||
{
|
||||
pthread_mutexattr_t attr;
|
||||
int ec = pthread_mutexattr_init(&attr);
|
||||
int ec = __libcpp_recursive_mutex_init(&__m_);
|
||||
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");
|
||||
__throw_system_error(ec, "recursive_mutex constructor failed");
|
||||
}
|
||||
|
||||
recursive_mutex::~recursive_mutex()
|
||||
{
|
||||
int e = pthread_mutex_destroy(&__m_);
|
||||
int e = __libcpp_mutex_destroy(&__m_);
|
||||
(void)e;
|
||||
assert(e == 0);
|
||||
}
|
||||
@ -89,7 +67,7 @@ recursive_mutex::~recursive_mutex()
|
||||
void
|
||||
recursive_mutex::lock()
|
||||
{
|
||||
int ec = pthread_mutex_lock(&__m_);
|
||||
int ec = __libcpp_mutex_lock(&__m_);
|
||||
if (ec)
|
||||
__throw_system_error(ec, "recursive_mutex lock failed");
|
||||
}
|
||||
@ -97,7 +75,7 @@ recursive_mutex::lock()
|
||||
void
|
||||
recursive_mutex::unlock() _NOEXCEPT
|
||||
{
|
||||
int e = pthread_mutex_unlock(&__m_);
|
||||
int e = __libcpp_mutex_unlock(&__m_);
|
||||
(void)e;
|
||||
assert(e == 0);
|
||||
}
|
||||
@ -105,7 +83,7 @@ recursive_mutex::unlock() _NOEXCEPT
|
||||
bool
|
||||
recursive_mutex::try_lock() _NOEXCEPT
|
||||
{
|
||||
return pthread_mutex_trylock(&__m_) == 0;
|
||||
return __libcpp_mutex_trylock(&__m_) == 0;
|
||||
}
|
||||
|
||||
// timed_mutex
|
||||
@ -165,9 +143,9 @@ recursive_timed_mutex::~recursive_timed_mutex()
|
||||
void
|
||||
recursive_timed_mutex::lock()
|
||||
{
|
||||
pthread_t id = pthread_self();
|
||||
__libcpp_thread_id id = __libcpp_thread_get_current_id();
|
||||
unique_lock<mutex> lk(__m_);
|
||||
if (pthread_equal(id, __id_))
|
||||
if (__libcpp_thread_id_equal(id, __id_))
|
||||
{
|
||||
if (__count_ == numeric_limits<size_t>::max())
|
||||
__throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached");
|
||||
@ -183,9 +161,9 @@ recursive_timed_mutex::lock()
|
||||
bool
|
||||
recursive_timed_mutex::try_lock() _NOEXCEPT
|
||||
{
|
||||
pthread_t id = pthread_self();
|
||||
__libcpp_thread_id id = __libcpp_thread_get_current_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 || __libcpp_thread_id_equal(id, __id_)))
|
||||
{
|
||||
if (__count_ == numeric_limits<size_t>::max())
|
||||
return false;
|
||||
@ -217,8 +195,8 @@ recursive_timed_mutex::unlock() _NOEXCEPT
|
||||
// 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;
|
||||
static __libcpp_mutex_t mut = _LIBCPP_MUTEX_INITIALIZER;
|
||||
static __libcpp_condvar_t cv = _LIBCPP_CONDVAR_INITIALIZER;
|
||||
#endif
|
||||
|
||||
/// NOTE: Changes to flag are done via relaxed atomic stores
|
||||
@ -247,9 +225,9 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
#else // !_LIBCPP_HAS_NO_THREADS
|
||||
pthread_mutex_lock(&mut);
|
||||
__libcpp_mutex_lock(&mut);
|
||||
while (flag == 1)
|
||||
pthread_cond_wait(&cv, &mut);
|
||||
__libcpp_condvar_wait(&cv, &mut);
|
||||
if (flag == 0)
|
||||
{
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
@ -257,26 +235,26 @@ __call_once(volatile unsigned long& flag, void* arg, void(*func)(void*))
|
||||
{
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
__libcpp_relaxed_store(&flag, 1ul);
|
||||
pthread_mutex_unlock(&mut);
|
||||
__libcpp_mutex_unlock(&mut);
|
||||
func(arg);
|
||||
pthread_mutex_lock(&mut);
|
||||
__libcpp_mutex_lock(&mut);
|
||||
__libcpp_relaxed_store(&flag, ~0ul);
|
||||
pthread_mutex_unlock(&mut);
|
||||
pthread_cond_broadcast(&cv);
|
||||
__libcpp_mutex_unlock(&mut);
|
||||
__libcpp_condvar_broadcast(&cv);
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pthread_mutex_lock(&mut);
|
||||
__libcpp_mutex_lock(&mut);
|
||||
__libcpp_relaxed_store(&flag, 0ul);
|
||||
pthread_mutex_unlock(&mut);
|
||||
pthread_cond_broadcast(&cv);
|
||||
__libcpp_mutex_unlock(&mut);
|
||||
__libcpp_condvar_broadcast(&cv);
|
||||
throw;
|
||||
}
|
||||
#endif // _LIBCPP_NO_EXCEPTIONS
|
||||
}
|
||||
else
|
||||
pthread_mutex_unlock(&mut);
|
||||
__libcpp_mutex_unlock(&mut);
|
||||
#endif // !_LIBCPP_HAS_NO_THREADS
|
||||
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ thread::~thread()
|
||||
void
|
||||
thread::join()
|
||||
{
|
||||
int ec = pthread_join(__t_, 0);
|
||||
int ec = __libcpp_thread_join(&__t_);
|
||||
#ifndef _LIBCPP_NO_EXCEPTIONS
|
||||
if (ec)
|
||||
throw system_error(error_code(ec, system_category()), "thread::join failed");
|
||||
@ -62,7 +62,7 @@ thread::detach()
|
||||
int ec = EINVAL;
|
||||
if (__t_ != 0)
|
||||
{
|
||||
ec = pthread_detach(__t_);
|
||||
ec = __libcpp_thread_detach(&__t_);
|
||||
if (ec == 0)
|
||||
__t_ = 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user