xref: /freebsd-src/contrib/llvm-project/libcxx/include/__thread/id.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1*06c3fb27SDimitry Andric // -*- C++ -*-
2*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
3*06c3fb27SDimitry Andric //
4*06c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*06c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*06c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*06c3fb27SDimitry Andric //
8*06c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
9*06c3fb27SDimitry Andric 
10*06c3fb27SDimitry Andric #ifndef _LIBCPP___THREAD_ID_H
11*06c3fb27SDimitry Andric #define _LIBCPP___THREAD_ID_H
12*06c3fb27SDimitry Andric 
13*06c3fb27SDimitry Andric #include <__compare/ordering.h>
14*06c3fb27SDimitry Andric #include <__config>
15*06c3fb27SDimitry Andric #include <__fwd/hash.h>
16*06c3fb27SDimitry Andric #include <__threading_support>
17*06c3fb27SDimitry Andric #include <iosfwd>
18*06c3fb27SDimitry Andric 
19*06c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
20*06c3fb27SDimitry Andric #  pragma GCC system_header
21*06c3fb27SDimitry Andric #endif
22*06c3fb27SDimitry Andric 
23*06c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
24*06c3fb27SDimitry Andric 
25*06c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_THREADS
26*06c3fb27SDimitry Andric class _LIBCPP_EXPORTED_FROM_ABI __thread_id;
27*06c3fb27SDimitry Andric 
28*06c3fb27SDimitry Andric namespace this_thread {
29*06c3fb27SDimitry Andric 
30*06c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT;
31*06c3fb27SDimitry Andric 
32*06c3fb27SDimitry Andric } // namespace this_thread
33*06c3fb27SDimitry Andric 
34*06c3fb27SDimitry Andric template <>
35*06c3fb27SDimitry Andric struct hash<__thread_id>;
36*06c3fb27SDimitry Andric 
37*06c3fb27SDimitry Andric class _LIBCPP_TEMPLATE_VIS __thread_id {
38*06c3fb27SDimitry Andric   // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
39*06c3fb27SDimitry Andric   // NULL is the no-thread value on Darwin.  Someone needs to check
40*06c3fb27SDimitry Andric   // on other platforms.  We assume 0 works everywhere for now.
41*06c3fb27SDimitry Andric   __libcpp_thread_id __id_;
42*06c3fb27SDimitry Andric 
43*06c3fb27SDimitry Andric   static _LIBCPP_HIDE_FROM_ABI bool
44*06c3fb27SDimitry Andric   __lt_impl(__thread_id __x, __thread_id __y) _NOEXCEPT { // id==0 is always less than any other thread_id
45*06c3fb27SDimitry Andric     if (__x.__id_ == 0)
46*06c3fb27SDimitry Andric       return __y.__id_ != 0;
47*06c3fb27SDimitry Andric     if (__y.__id_ == 0)
48*06c3fb27SDimitry Andric       return false;
49*06c3fb27SDimitry Andric     return __libcpp_thread_id_less(__x.__id_, __y.__id_);
50*06c3fb27SDimitry Andric   }
51*06c3fb27SDimitry Andric 
52*06c3fb27SDimitry Andric public:
53*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI __thread_id() _NOEXCEPT : __id_(0) {}
54*06c3fb27SDimitry Andric 
55*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI void __reset() { __id_ = 0; }
56*06c3fb27SDimitry Andric 
57*06c3fb27SDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
58*06c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
59*06c3fb27SDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
60*06c3fb27SDimitry Andric #  else  // _LIBCPP_STD_VER <= 17
61*06c3fb27SDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
62*06c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER <= 17
63*06c3fb27SDimitry Andric 
64*06c3fb27SDimitry Andric   template <class _CharT, class _Traits>
65*06c3fb27SDimitry Andric   friend _LIBCPP_HIDE_FROM_ABI basic_ostream<_CharT, _Traits>&
66*06c3fb27SDimitry Andric   operator<<(basic_ostream<_CharT, _Traits>& __os, __thread_id __id);
67*06c3fb27SDimitry Andric 
68*06c3fb27SDimitry Andric private:
69*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI __thread_id(__libcpp_thread_id __id) : __id_(__id) {}
70*06c3fb27SDimitry Andric 
71*06c3fb27SDimitry Andric   _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }
72*06c3fb27SDimitry Andric 
73*06c3fb27SDimitry Andric   friend __thread_id this_thread::get_id() _NOEXCEPT;
74*06c3fb27SDimitry Andric   friend class _LIBCPP_EXPORTED_FROM_ABI thread;
75*06c3fb27SDimitry Andric   friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
76*06c3fb27SDimitry Andric };
77*06c3fb27SDimitry Andric 
78*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT {
79*06c3fb27SDimitry Andric   // Don't pass id==0 to underlying routines
80*06c3fb27SDimitry Andric   if (__x.__id_ == 0)
81*06c3fb27SDimitry Andric     return __y.__id_ == 0;
82*06c3fb27SDimitry Andric   if (__y.__id_ == 0)
83*06c3fb27SDimitry Andric     return false;
84*06c3fb27SDimitry Andric   return __libcpp_thread_id_equal(__x.__id_, __y.__id_);
85*06c3fb27SDimitry Andric }
86*06c3fb27SDimitry Andric 
87*06c3fb27SDimitry Andric #  if _LIBCPP_STD_VER <= 17
88*06c3fb27SDimitry Andric 
89*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x == __y); }
90*06c3fb27SDimitry Andric 
91*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
92*06c3fb27SDimitry Andric   return __thread_id::__lt_impl(__x.__id_, __y.__id_);
93*06c3fb27SDimitry Andric }
94*06c3fb27SDimitry Andric 
95*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
96*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
97*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }
98*06c3fb27SDimitry Andric 
99*06c3fb27SDimitry Andric #  else // _LIBCPP_STD_VER <= 17
100*06c3fb27SDimitry Andric 
101*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
102*06c3fb27SDimitry Andric   if (__x == __y)
103*06c3fb27SDimitry Andric     return strong_ordering::equal;
104*06c3fb27SDimitry Andric   if (__thread_id::__lt_impl(__x, __y))
105*06c3fb27SDimitry Andric     return strong_ordering::less;
106*06c3fb27SDimitry Andric   return strong_ordering::greater;
107*06c3fb27SDimitry Andric }
108*06c3fb27SDimitry Andric 
109*06c3fb27SDimitry Andric #  endif // _LIBCPP_STD_VER <= 17
110*06c3fb27SDimitry Andric 
111*06c3fb27SDimitry Andric namespace this_thread {
112*06c3fb27SDimitry Andric 
113*06c3fb27SDimitry Andric inline _LIBCPP_HIDE_FROM_ABI __thread_id get_id() _NOEXCEPT { return __libcpp_thread_get_current_id(); }
114*06c3fb27SDimitry Andric 
115*06c3fb27SDimitry Andric } // namespace this_thread
116*06c3fb27SDimitry Andric 
117*06c3fb27SDimitry Andric #endif // !_LIBCPP_HAS_NO_THREADS
118*06c3fb27SDimitry Andric 
119*06c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
120*06c3fb27SDimitry Andric 
121*06c3fb27SDimitry Andric #endif // _LIBCPP___THREAD_ID_H
122