106c3fb27SDimitry Andric // -*- C++ -*- 206c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 306c3fb27SDimitry Andric // 406c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 506c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 606c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 706c3fb27SDimitry Andric // 806c3fb27SDimitry Andric //===----------------------------------------------------------------------===// 906c3fb27SDimitry Andric 1006c3fb27SDimitry Andric #ifndef _LIBCPP___THREAD_ID_H 1106c3fb27SDimitry Andric #define _LIBCPP___THREAD_ID_H 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric #include <__compare/ordering.h> 1406c3fb27SDimitry Andric #include <__config> 15*0fca6ea1SDimitry Andric #include <__fwd/functional.h> 165f757f3fSDimitry Andric #include <__fwd/ostream.h> 17*0fca6ea1SDimitry Andric #include <__thread/support.h> 1806c3fb27SDimitry Andric 1906c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2006c3fb27SDimitry Andric # pragma GCC system_header 2106c3fb27SDimitry Andric #endif 2206c3fb27SDimitry Andric 2306c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 2406c3fb27SDimitry Andric 2506c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS 2606c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI __thread_id; 2706c3fb27SDimitry Andric 2806c3fb27SDimitry Andric namespace this_thread { 2906c3fb27SDimitry Andric 3006c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT; 3106c3fb27SDimitry Andric 3206c3fb27SDimitry Andric } // namespace this_thread 3306c3fb27SDimitry Andric 3406c3fb27SDimitry Andric template <> 3506c3fb27SDimitry Andric struct hash<__thread_id>; 3606c3fb27SDimitry Andric 3706c3fb27SDimitry Andric class _LIBCPP_TEMPLATE_VIS __thread_id { 3806c3fb27SDimitry Andric // FIXME: pthread_t is a pointer on Darwin but a long on Linux. 3906c3fb27SDimitry Andric // NULL is the no-thread value on Darwin. Someone needs to check 4006c3fb27SDimitry Andric // on other platforms. We assume 0 works everywhere for now. 4106c3fb27SDimitry Andric __libcpp_thread_id __id_; 4206c3fb27SDimitry Andric 4306c3fb27SDimitry Andric static _LIBCPP_HIDE_FROM_ABI bool 4406c3fb27SDimitry Andric __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id 4506c3fb27SDimitry Andric if (__x.__id_ == 0) 4606c3fb27SDimitry Andric return __y.__id_ != 0; 4706c3fb27SDimitry Andric if (__y.__id_ == 0) 4806c3fb27SDimitry Andric return false; 4906c3fb27SDimitry Andric return __libcpp_thread_id_less(__x.__id_, __y.__id_); 5006c3fb27SDimitry Andric } 5106c3fb27SDimitry Andric 5206c3fb27SDimitry Andric public: 5306c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {} 5406c3fb27SDimitry Andric 5506c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI void __reset() { __id_ = 0; } 5606c3fb27SDimitry Andric 5706c3fb27SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT; 5806c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 5906c3fb27SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT; 6006c3fb27SDimitry Andric # else // _LIBCPP_STD_VER <= 17 6106c3fb27SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept; 6206c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER <= 17 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric template <class _CharT, class _Traits> 6506c3fb27SDimitry Andric friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>& 6606c3fb27SDimitry Andric operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id); 6706c3fb27SDimitry Andric 6806c3fb27SDimitry Andric private: 6906c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __thread_id(__libcpp_thread_id __id) : __id_(__id) {} 7006c3fb27SDimitry Andric 7106c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; } 7206c3fb27SDimitry Andric 7306c3fb27SDimitry Andric friend __thread_id this_thread::get_id() _NOEXCEPT; 7406c3fb27SDimitry Andric friend class _LIBCPP_EXPORTED_FROM_ABI thread; 7506c3fb27SDimitry Andric friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>; 7606c3fb27SDimitry Andric }; 7706c3fb27SDimitry Andric 7806c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT { 7906c3fb27SDimitry Andric // Don't pass id==0 to underlying routines 8006c3fb27SDimitry Andric if (__x.__id_ == 0) 8106c3fb27SDimitry Andric return __y.__id_ == 0; 8206c3fb27SDimitry Andric if (__y.__id_ == 0) 8306c3fb27SDimitry Andric return false; 8406c3fb27SDimitry Andric return __libcpp_thread_id_equal(__x.__id_, __y.__id_); 8506c3fb27SDimitry Andric } 8606c3fb27SDimitry Andric 8706c3fb27SDimitry Andric # if _LIBCPP_STD_VER <= 17 8806c3fb27SDimitry Andric 8906c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); } 9006c3fb27SDimitry Andric 9106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT { 9206c3fb27SDimitry Andric return __thread_id::__lt_impl(__x.__id_, __y.__id_); 9306c3fb27SDimitry Andric } 9406c3fb27SDimitry Andric 9506c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); } 9606c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; } 9706c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); } 9806c3fb27SDimitry Andric 9906c3fb27SDimitry Andric # else // _LIBCPP_STD_VER <= 17 10006c3fb27SDimitry Andric 10106c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept { 10206c3fb27SDimitry Andric if (__x == __y) 10306c3fb27SDimitry Andric return strong_ordering::equal; 10406c3fb27SDimitry Andric if (__thread_id::__lt_impl(__x, __y)) 10506c3fb27SDimitry Andric return strong_ordering::less; 10606c3fb27SDimitry Andric return strong_ordering::greater; 10706c3fb27SDimitry Andric } 10806c3fb27SDimitry Andric 10906c3fb27SDimitry Andric # endif // _LIBCPP_STD_VER <= 17 11006c3fb27SDimitry Andric 11106c3fb27SDimitry Andric namespace this_thread { 11206c3fb27SDimitry Andric 11306c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); } 11406c3fb27SDimitry Andric 11506c3fb27SDimitry Andric } // namespace this_thread 11606c3fb27SDimitry Andric 11706c3fb27SDimitry Andric #endif // !_LIBCPP_HAS_NO_THREADS 11806c3fb27SDimitry Andric 11906c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD 12006c3fb27SDimitry Andric 12106c3fb27SDimitry Andric #endif // _LIBCPP___THREAD_ID_H 122