xref: /freebsd-src/contrib/llvm-project/libcxx/include/__thread/id.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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