aboutsummaryrefslogtreecommitdiffstats
path: root/include/__threading_support
diff options
context:
space:
mode:
Diffstat (limited to 'include/__threading_support')
-rw-r--r--include/__threading_support105
1 files changed, 96 insertions, 9 deletions
diff --git a/include/__threading_support b/include/__threading_support
index 589fe2096fd4..0d1f1e681f50 100644
--- a/include/__threading_support
+++ b/include/__threading_support
@@ -12,6 +12,7 @@
#include <__config>
#include <chrono>
+#include <iosfwd>
#include <errno.h>
#ifndef _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
@@ -22,16 +23,11 @@
# include <__external_threading>
#elif !defined(_LIBCPP_HAS_NO_THREADS)
-typedef ::timespec __libcpp_timespec_t;
-
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
# include <pthread.h>
# include <sched.h>
#endif
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
#if defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL) || \
defined(_LIBCPP_HAS_THREAD_API_WIN32)
@@ -46,8 +42,16 @@ _LIBCPP_PUSH_MACROS
#define _LIBCPP_NO_THREAD_SAFETY_ANALYSIS
#endif
+typedef ::timespec __libcpp_timespec_t;
+#endif // !defined(_LIBCPP_HAS_NO_THREADS)
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
_LIBCPP_BEGIN_NAMESPACE_STD
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+
#if defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
// Mutex
typedef pthread_mutex_t __libcpp_mutex_t;
@@ -75,7 +79,7 @@ typedef pthread_t __libcpp_thread_t;
typedef pthread_key_t __libcpp_tls_key;
#define _LIBCPP_TLS_DESTRUCTOR_CC
-#else
+#elif !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
// Mutex
typedef void* __libcpp_mutex_t;
#define _LIBCPP_MUTEX_INITIALIZER 0
@@ -108,8 +112,9 @@ typedef void* __libcpp_thread_t;
typedef long __libcpp_tls_key;
#define _LIBCPP_TLS_DESTRUCTOR_CC __stdcall
-#endif
+#endif // !defined(_LIBCPP_HAS_THREAD_API_PTHREAD) && !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+#if !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
// Mutex
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_recursive_mutex_init(__libcpp_recursive_mutex_t *__m);
@@ -204,6 +209,8 @@ void *__libcpp_tls_get(__libcpp_tls_key __key);
_LIBCPP_THREAD_ABI_VISIBILITY
int __libcpp_tls_set(__libcpp_tls_key __key, void *__p);
+#endif // !defined(_LIBCPP_HAS_THREAD_API_EXTERNAL)
+
#if (!defined(_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL) || \
defined(_LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL)) && \
defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
@@ -394,10 +401,90 @@ int __libcpp_tls_set(__libcpp_tls_key __key, void *__p)
#endif // !_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL || _LIBCPP_BUILDING_THREAD_LIBRARY_EXTERNAL
-_LIBCPP_END_NAMESPACE_STD
+class _LIBCPP_TYPE_VIS thread;
+class _LIBCPP_TYPE_VIS __thread_id;
-_LIBCPP_POP_MACROS
+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
#endif // !_LIBCPP_HAS_NO_THREADS
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
#endif // _LIBCPP_THREADING_SUPPORT