aboutsummaryrefslogtreecommitdiff
path: root/libcxx/include/__thread/id.h
blob: 533f8500622fb8371173d714245e14640034d750 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___THREAD_ID_H
#define _LIBCPP___THREAD_ID_H

#include <__compare/ordering.h>
#include <__config>
#include <__fwd/hash.h>
#include <__threading_support>
#include <iosfwd>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#  pragma GCC system_header
#endif

_LIBCPP_BEGIN_NAMESPACE_STD

#ifndef _LIBCPP_HAS_NO_THREADS

class _LIBCPP_EXPORTED_FROM_ABI thread;
class _LIBCPP_EXPORTED_FROM_ABI __thread_id;

namespace this_thread
{

_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;

} // namespace 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_;

    static _LIBCPP_HIDE_FROM_ABI
        bool __lt_impl(__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_);
        }

public:
    _LIBCPP_INLINE_VISIBILITY
    __thread_id() _NOEXCEPT : __id_(0) {}

    _LIBCPP_INLINE_VISIBILITY
    void __reset() { __id_ = 0; }

    friend _LIBCPP_HIDE_FROM_ABI bool operator==(__thread_id __x, __thread_id __y) _NOEXCEPT;
#if _LIBCPP_STD_VER <= 17
    friend _LIBCPP_HIDE_FROM_ABI bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT;
#else // _LIBCPP_STD_VER <= 17
    friend _LIBCPP_HIDE_FROM_ABI strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept;
#endif // _LIBCPP_STD_VER <= 17

    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) {}

    _LIBCPP_HIDE_FROM_ABI friend __libcpp_thread_id __get_underlying_id(const __thread_id __id) { return __id.__id_; }

    friend __thread_id this_thread::get_id() _NOEXCEPT;
    friend class _LIBCPP_EXPORTED_FROM_ABI thread;
    friend struct _LIBCPP_TEMPLATE_VIS hash<__thread_id>;
};

inline _LIBCPP_HIDE_FROM_ABI
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_);
}

#if _LIBCPP_STD_VER <= 17

inline _LIBCPP_HIDE_FROM_ABI
bool operator!=(__thread_id __x, __thread_id __y) _NOEXCEPT {
  return !(__x == __y);
}

inline _LIBCPP_HIDE_FROM_ABI
bool operator<(__thread_id __x, __thread_id __y) _NOEXCEPT {
  return __thread_id::__lt_impl(__x.__id_, __y.__id_);
}

inline _LIBCPP_HIDE_FROM_ABI bool operator<=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__y < __x); }
inline _LIBCPP_HIDE_FROM_ABI bool operator>(__thread_id __x, __thread_id __y) _NOEXCEPT { return __y < __x; }
inline _LIBCPP_HIDE_FROM_ABI bool operator>=(__thread_id __x, __thread_id __y) _NOEXCEPT { return !(__x < __y); }

#else // _LIBCPP_STD_VER <= 17

inline _LIBCPP_HIDE_FROM_ABI
strong_ordering operator<=>(__thread_id __x, __thread_id __y) noexcept {
  if (__x == __y)
    return strong_ordering::equal;
  if (__thread_id::__lt_impl(__x, __y))
    return strong_ordering::less;
  return strong_ordering::greater;
}

#endif // _LIBCPP_STD_VER <= 17

namespace this_thread
{

_LIBCPP_INLINE_VISIBILITY __thread_id get_id() _NOEXCEPT;

} // namespace this_thread

namespace this_thread
{

inline _LIBCPP_INLINE_VISIBILITY
__thread_id
get_id() _NOEXCEPT
{
    return __libcpp_thread_get_current_id();
}

} // namespace this_thread

#endif // !_LIBCPP_HAS_NO_THREADS

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP___THREAD_ID_H