Index: libcxx/include/__config =================================================================== --- libcxx/include/__config +++ libcxx/include/__config @@ -1126,6 +1126,7 @@ defined(__APPLE__) || \ defined(__CloudABI__) || \ defined(__sun__) || \ + defined(__MVS__) || \ (defined(__MINGW32__) && __has_include()) # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) Index: libcxx/include/__threading_support =================================================================== --- libcxx/include/__threading_support +++ libcxx/include/__threading_support @@ -26,7 +26,7 @@ #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) # include # include -# ifdef __APPLE__ +# if defined(__APPLE__) || defined(__MVS__) # define _LIBCPP_NO_NATIVE_SEMAPHORES # endif # ifndef _LIBCPP_NO_NATIVE_SEMAPHORES @@ -82,10 +82,18 @@ #define _LIBCPP_EXEC_ONCE_INITIALIZER PTHREAD_ONCE_INIT // Thread id -typedef pthread_t __libcpp_thread_id; +#if defined(__MVS__) + typedef unsigned long long __libcpp_thread_id; +#else + typedef pthread_t __libcpp_thread_id; +#endif // Thread -#define _LIBCPP_NULL_THREAD 0U +#if defined(__MVS__) + #define _LIBCPP_NULL_THREAD ((__libcpp_thread_t())) +#else + #define _LIBCPP_NULL_THREAD 0U +#endif typedef pthread_t __libcpp_thread_t; @@ -231,9 +239,9 @@ int __libcpp_execute_once(__libcpp_exec_once_flag *flag, void (*init_routine)()); -// Thread id +// Thread _LIBCPP_THREAD_ABI_VISIBILITY -bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2); +bool __libcpp_thread_equal(const __libcpp_thread_t &t1, const __libcpp_thread_t &t2); _LIBCPP_THREAD_ABI_VISIBILITY bool __libcpp_thread_id_less(__libcpp_thread_id t1, __libcpp_thread_id t2); @@ -250,6 +258,9 @@ __libcpp_thread_id __libcpp_thread_get_current_id(); _LIBCPP_THREAD_ABI_VISIBILITY +__libcpp_thread_t __libcpp_thread_get_current_thread(); + +_LIBCPP_THREAD_ABI_VISIBILITY __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t); _LIBCPP_THREAD_ABI_VISIBILITY @@ -477,9 +488,9 @@ return pthread_once(flag, init_routine); } -// Thread id -// Returns non-zero if the thread ids are equal, otherwise 0 -bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) +// Thread +// Returns non-zero if the threads are equal, otherwise 0 +bool __libcpp_thread_equal(const __libcpp_thread_t &t1, const __libcpp_thread_t &t2) { return pthread_equal(t1, t2) != 0; } @@ -492,7 +503,7 @@ // Thread bool __libcpp_thread_isnull(const __libcpp_thread_t *__t) { - return *__t == 0; + return __libcpp_thread_get_id(__t) == 0; } int __libcpp_thread_create(__libcpp_thread_t *__t, void *(*__func)(void *), @@ -503,12 +514,22 @@ __libcpp_thread_id __libcpp_thread_get_current_id() { + const __libcpp_thread_t thread = __libcpp_thread_get_current_thread(); + return __libcpp_thread_get_id(&thread); +} + +__libcpp_thread_t __libcpp_thread_get_current_thread() +{ return pthread_self(); } __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) { +#if defined(__MVS__) + return __t->__; +#else return *__t; +#endif } int __libcpp_thread_join(__libcpp_thread_t *__t) @@ -634,8 +655,8 @@ } // Thread id -// Returns non-zero if the thread ids are equal, otherwise 0 -bool __libcpp_thread_id_equal(__libcpp_thread_id t1, __libcpp_thread_id t2) +// Returns non-zero if the threads are equal, otherwise 0 +bool __libcpp_thread_equal(const __libcpp_thread_t &t1, const __libcpp_thread_t &t2) { return thrd_equal(t1, t2) != 0; } @@ -663,6 +684,11 @@ return thrd_current(); } +__libcpp_thread_t __libcpp_thread_get_current_thread() +{ + return thrd_current(); +} + __libcpp_thread_id __libcpp_thread_get_id(const __libcpp_thread_t *__t) { return *__t; @@ -710,82 +736,54 @@ #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL -class _LIBCPP_TYPE_VIS thread; -class _LIBCPP_TYPE_VIS __thread_id; +class _LIBCPP_TYPE_VIS __thread_t; namespace this_thread { -_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; +_LIBCPP_INLINE_VISIBILITY __thread_t get_thread() _NOEXCEPT; } // this_thread -template<> struct hash<__thread_id>; +template<> struct hash<__thread_t>; -class _LIBCPP_TEMPLATE_VIS __thread_id +class _LIBCPP_TEMPLATE_VIS __thread_t { - // 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. - __libcpp_thread_id __id_; + __libcpp_thread_t __t_; public: _LIBCPP_INLINE_VISIBILITY - __thread_id() _NOEXCEPT : __id_(0) {} + __thread_t() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {} friend _LIBCPP_INLINE_VISIBILITY - bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT - { // don't pass id==0 to underlying routines - if (__x.__id_ == 0) return __y.__id_ == 0; - if (__y.__id_ == 0) return false; - 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 - { // id==0 is always less than any other thread_id - if (__x.__id_ == 0) return __y.__id_ != 0; - if (__y.__id_ == 0) return false; - return __libcpp_thread_id_less(__x.__id_, __y.__id_); + bool operator==(__thread_t __x, __thread_t __y) _NOEXCEPT + { // don't pass thread with id==0 to underlying routines + __libcpp_thread_id __xid = __libcpp_thread_get_id(&__x.__t_); + __libcpp_thread_id __yid = __libcpp_thread_get_id(&__y.__t_); + if (__xid == 0) return __yid == 0; + if (__yid == 0) return false; + return __libcpp_thread_equal(__x.__t_, __y.__t_); } - friend _LIBCPP_INLINE_VISIBILITY - bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT - {return !(__y < __x);} - friend _LIBCPP_INLINE_VISIBILITY - bool operator> (__thread_id __x, __thread_id __y) _NOEXCEPT - {return __y < __x ;} - friend _LIBCPP_INLINE_VISIBILITY - bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT - {return !(__x < __y);} _LIBCPP_INLINE_VISIBILITY - void __reset() { __id_ = 0; } - - template - friend + void __reset() { __t_ = _LIBCPP_NULL_THREAD; } _LIBCPP_INLINE_VISIBILITY - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); + __libcpp_thread_id __get_id() { return __libcpp_thread_get_id(&__t_); } private: _LIBCPP_INLINE_VISIBILITY - __thread_id(__libcpp_thread_id __id) : __id_(__id) {} + __thread_t(const __libcpp_thread_t& __t) : __t_(__t) {} - friend __thread_id this_thread::get_id() _NOEXCEPT; - friend class _LIBCPP_TYPE_VIS thread; - friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; + friend __thread_t this_thread::get_thread() _NOEXCEPT; }; namespace this_thread { - inline _LIBCPP_INLINE_VISIBILITY -__thread_id -get_id() _NOEXCEPT +__thread_t +get_thread() _NOEXCEPT { - return __libcpp_thread_get_current_id(); + return __libcpp_thread_get_current_thread(); } } // this_thread Index: libcxx/include/mutex =================================================================== --- libcxx/include/mutex +++ libcxx/include/mutex @@ -280,7 +280,7 @@ mutex __m_; condition_variable __cv_; size_t __count_; - __thread_id __id_; + __thread_t __t_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -307,9 +307,9 @@ recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - __thread_id __id = this_thread::get_id(); + __thread_t __th = this_thread::get_thread(); unique_lock lk(__m_); - if (__id == __id_) + if (__t_ == __th) { if (__count_ == numeric_limits::max()) return false; @@ -322,7 +322,7 @@ if (__count_ == 0) { __count_ = 1; - __id_ = __id; + __t_ = __th; return true; } return false; Index: libcxx/include/thread =================================================================== --- libcxx/include/thread +++ libcxx/include/thread @@ -197,21 +197,21 @@ } template<> -struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> - : public unary_function<__thread_id, size_t> +struct _LIBCPP_TEMPLATE_VIS hash<__thread_t> + : public unary_function<__thread_t, size_t> { _LIBCPP_INLINE_VISIBILITY - size_t operator()(__thread_id __v) const _NOEXCEPT + size_t operator()(__thread_t __v) const _NOEXCEPT { - return hash<__libcpp_thread_id>()(__v.__id_); + return hash<__libcpp_thread_id>()(__v.__get_id()); } }; template _LIBCPP_INLINE_VISIBILITY basic_ostream<_CharT, _Traits>& -operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) -{return __os << __id.__id_;} +operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_t __t) +{return __os << __t.__get_id();} class _LIBCPP_TYPE_VIS thread { @@ -220,7 +220,8 @@ thread(const thread&); thread& operator=(const thread&); public: - typedef __thread_id id; + typedef __libcpp_thread_id id; + typedef __thread_t t; typedef __libcpp_thread_t native_handle_type; _LIBCPP_INLINE_VISIBILITY Index: libcxx/src/barrier.cpp =================================================================== --- libcxx/src/barrier.cpp +++ libcxx/src/barrier.cpp @@ -42,7 +42,8 @@ __barrier_phase_t const __half_step = __old_phase + 1, __full_step = __old_phase + 2; size_t __current_expected = __expected, - __current = hash()(this_thread::get_id()) % ((__expected + 1) >> 1); + __current = hash()(this_thread::get_thread()) % + ((__expected + 1) >> 1); for(int __round = 0;; ++__round) { if(__current_expected <= 1) return true; Index: libcxx/src/mutex.cpp =================================================================== --- libcxx/src/mutex.cpp +++ libcxx/src/mutex.cpp @@ -130,11 +130,7 @@ // recursive_timed_mutex -recursive_timed_mutex::recursive_timed_mutex() - : __count_(0), - __id_{} -{ -} +recursive_timed_mutex::recursive_timed_mutex() : __count_(0), __t_{} {} recursive_timed_mutex::~recursive_timed_mutex() { @@ -144,9 +140,9 @@ void recursive_timed_mutex::lock() { - __thread_id id = this_thread::get_id(); + __thread_t __th = this_thread::get_thread(); unique_lock lk(__m_); - if (id ==__id_) + if (__t_ == __th) { if (__count_ == numeric_limits::max()) __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); @@ -156,20 +152,20 @@ while (__count_ != 0) __cv_.wait(lk); __count_ = 1; - __id_ = id; + __t_ = __th; } bool recursive_timed_mutex::try_lock() _NOEXCEPT { - __thread_id id = this_thread::get_id(); + __thread_t __th = this_thread::get_thread(); unique_lock lk(__m_, try_to_lock); - if (lk.owns_lock() && (__count_ == 0 || id == __id_)) + if (lk.owns_lock() && (__count_ == 0 || (__t_ == __th))) { if (__count_ == numeric_limits::max()) return false; ++__count_; - __id_ = id; + __t_ = __th; return true; } return false; @@ -181,7 +177,7 @@ unique_lock lk(__m_); if (--__count_ == 0) { - __id_.__reset(); + __t_ .__reset(); lk.unlock(); __cv_.notify_one(); }