Date: Tue, 20 Aug 2019 17:39:33 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351253 - in head/contrib/libc++: include src Message-ID: <201908201739.x7KHdXvv054610@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Tue Aug 20 17:39:32 2019 New Revision: 351253 URL: https://svnweb.freebsd.org/changeset/base/351253 Log: Pull in r368867 from upstream libc++ trunk (by Marshall Clow): Rework recursive_timed_mutex so that it uses __thread_id instead of using the lower-level __libcpp_thread_id. This is prep for fixing PR42918. Reviewed as https://reviews.llvm.org/D65895 Pull in r368916 from upstream libc++ trunk (by Marshall Clow): Fix thread comparison by making sure we never pass our special 'not a thread' value to the underlying implementation. Fixes PR#42918. This should fix std::thread::id::operator==() attempting to call pthread_equal(3) with zero values. Reported by: andrew@tao11.riddles.org.uk PR: 239038, 239550 MFC after: 3 days Modified: head/contrib/libc++/include/__threading_support head/contrib/libc++/include/mutex head/contrib/libc++/include/thread head/contrib/libc++/src/mutex.cpp Modified: head/contrib/libc++/include/__threading_support ============================================================================== --- head/contrib/libc++/include/__threading_support Tue Aug 20 17:00:31 2019 (r351252) +++ head/contrib/libc++/include/__threading_support Tue Aug 20 17:39:32 2019 (r351253) @@ -13,6 +13,7 @@ #include <__config> #include <chrono> +#include <iosfwd> #include <errno.h> #ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER @@ -392,6 +393,86 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p } #endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL + +class _LIBCPP_TYPE_VIS thread; +class _LIBCPP_TYPE_VIS __thread_id; + +namespace this_thread +{ + +_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; + +} // this_thread + +template<> struct hash<__thread_id>; + +class _LIBCPP_TEMPLATE_VIS __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. + __libcpp_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 + { // 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_); + } + 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<class _CharT, class _Traits> + friend + _LIBCPP_INLINE_VISIBILITY + basic_ostream<_CharT, _Traits>& + operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); + +private: + _LIBCPP_INLINE_VISIBILITY + __thread_id(__libcpp_thread_id __id) : __id_(__id) {} + + friend __thread_id this_thread::get_id() _NOEXCEPT; + friend class _LIBCPP_TYPE_VIS thread; + friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; +}; + +namespace this_thread +{ + +inline _LIBCPP_INLINE_VISIBILITY +__thread_id +get_id() _NOEXCEPT +{ + return __libcpp_thread_get_current_id(); +} + +} // this_thread _LIBCPP_END_NAMESPACE_STD Modified: head/contrib/libc++/include/mutex ============================================================================== --- head/contrib/libc++/include/mutex Tue Aug 20 17:00:31 2019 (r351252) +++ head/contrib/libc++/include/mutex Tue Aug 20 17:39:32 2019 (r351253) @@ -280,7 +280,7 @@ class _LIBCPP_TYPE_VIS recursive_timed_mutex mutex __m_; condition_variable __cv_; size_t __count_; - __libcpp_thread_id __id_; + __thread_id __id_; public: recursive_timed_mutex(); ~recursive_timed_mutex(); @@ -307,9 +307,9 @@ bool recursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) { using namespace chrono; - __libcpp_thread_id __id = __libcpp_thread_get_current_id(); + __thread_id __id = this_thread::get_id(); unique_lock<mutex> lk(__m_); - if (__libcpp_thread_id_equal(__id, __id_)) + if (__id == __id_) { if (__count_ == numeric_limits<size_t>::max()) return false; Modified: head/contrib/libc++/include/thread ============================================================================== --- head/contrib/libc++/include/thread Tue Aug 20 17:00:31 2019 (r351252) +++ head/contrib/libc++/include/thread Tue Aug 20 17:39:32 2019 (r351253) @@ -201,64 +201,6 @@ __thread_specific_ptr<_Tp>::set_pointer(pointer __p) __libcpp_tls_set(__key_, __p); } -class _LIBCPP_TYPE_VIS thread; -class _LIBCPP_TYPE_VIS __thread_id; - -namespace this_thread -{ - -_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT; - -} // this_thread - -template<> struct hash<__thread_id>; - -class _LIBCPP_TEMPLATE_VIS __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. - __libcpp_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 __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 __libcpp_thread_id_less(__x.__id_, __y.__id_);} - 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);} - - template<class _CharT, class _Traits> - friend - _LIBCPP_INLINE_VISIBILITY - basic_ostream<_CharT, _Traits>& - operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) - {return __os << __id.__id_;} - -private: - _LIBCPP_INLINE_VISIBILITY - __thread_id(__libcpp_thread_id __id) : __id_(__id) {} - - friend __thread_id this_thread::get_id() _NOEXCEPT; - friend class _LIBCPP_TYPE_VIS thread; - friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; -}; - template<> struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> : public unary_function<__thread_id, size_t> @@ -270,17 +212,11 @@ struct _LIBCPP_TEMPLATE_VIS hash<__thread_id> } }; -namespace this_thread -{ - -inline _LIBCPP_INLINE_VISIBILITY -__thread_id -get_id() _NOEXCEPT -{ - return __libcpp_thread_get_current_id(); -} - -} // this_thread +template<class _CharT, class _Traits> +_LIBCPP_INLINE_VISIBILITY +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id) +{return __os << __id.__id_;} class _LIBCPP_TYPE_VIS thread { Modified: head/contrib/libc++/src/mutex.cpp ============================================================================== --- head/contrib/libc++/src/mutex.cpp Tue Aug 20 17:00:31 2019 (r351252) +++ head/contrib/libc++/src/mutex.cpp Tue Aug 20 17:39:32 2019 (r351253) @@ -130,7 +130,7 @@ timed_mutex::unlock() _NOEXCEPT recursive_timed_mutex::recursive_timed_mutex() : __count_(0), - __id_(0) + __id_{} { } @@ -142,9 +142,9 @@ recursive_timed_mutex::~recursive_timed_mutex() void recursive_timed_mutex::lock() { - __libcpp_thread_id id = __libcpp_thread_get_current_id(); + __thread_id id = this_thread::get_id(); unique_lock<mutex> lk(__m_); - if (__libcpp_thread_id_equal(id, __id_)) + if (id ==__id_) { if (__count_ == numeric_limits<size_t>::max()) __throw_system_error(EAGAIN, "recursive_timed_mutex lock limit reached"); @@ -160,9 +160,9 @@ recursive_timed_mutex::lock() bool recursive_timed_mutex::try_lock() _NOEXCEPT { - __libcpp_thread_id id = __libcpp_thread_get_current_id(); + __thread_id id = this_thread::get_id(); unique_lock<mutex> lk(__m_, try_to_lock); - if (lk.owns_lock() && (__count_ == 0 || __libcpp_thread_id_equal(id, __id_))) + if (lk.owns_lock() && (__count_ == 0 || id == __id_)) { if (__count_ == numeric_limits<size_t>::max()) return false; @@ -179,7 +179,7 @@ recursive_timed_mutex::unlock() _NOEXCEPT unique_lock<mutex> lk(__m_); if (--__count_ == 0) { - __id_ = 0; + __id_.__reset(); lk.unlock(); __cv_.notify_one(); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908201739.x7KHdXvv054610>