abseil-cpp/absl/base/internal/thread_identity.h
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Each active thread has an ThreadIdentity that may represent the thread in
16 // various level interfaces. ThreadIdentity objects are never deallocated.
17 // When a thread terminates, its ThreadIdentity object may be reused for a
18 // thread created later.
19 
20 #ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
21 #define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
22 
23 #ifndef _WIN32
24 #include <pthread.h>
25 // Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when
26 // supported.
27 #include <unistd.h>
28 #endif
29 
30 #include <atomic>
31 #include <cstdint>
32 
33 #include "absl/base/config.h"
34 #include "absl/base/internal/per_thread_tls.h"
35 #include "absl/base/optimization.h"
36 
37 namespace absl {
39 
40 struct SynchLocksHeld;
41 struct SynchWaitParams;
42 
43 namespace base_internal {
44 
45 class SpinLock;
46 struct ThreadIdentity;
47 
48 // Used by the implementation of absl::Mutex and absl::CondVar.
50  // The internal representation of absl::Mutex and absl::CondVar rely
51  // on the alignment of PerThreadSynch. Both store the address of the
52  // PerThreadSynch in the high-order bits of their internal state,
53  // which means the low kLowZeroBits of the address of PerThreadSynch
54  // must be zero.
55  static constexpr int kLowZeroBits = 8;
56  static constexpr int kAlignment = 1 << kLowZeroBits;
57 
58  // Returns the associated ThreadIdentity.
59  // This can be implemented as a cast because we guarantee
60  // PerThreadSynch is the first element of ThreadIdentity.
62  return reinterpret_cast<ThreadIdentity*>(this);
63  }
64 
65  PerThreadSynch *next; // Circular waiter queue; initialized to 0.
66  PerThreadSynch *skip; // If non-zero, all entries in Mutex queue
67  // up to and including "skip" have same
68  // condition as this, and will be woken later
69  bool may_skip; // if false while on mutex queue, a mutex unlocker
70  // is using this PerThreadSynch as a terminator. Its
71  // skip field must not be filled in because the loop
72  // might then skip over the terminator.
73  bool wake; // This thread is to be woken from a Mutex.
74  // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the
75  // waiter is waiting on the mutex as part of a CV Wait or Mutex Await.
76  //
77  // The value of "x->cond_waiter" is meaningless if "x" is not on a
78  // Mutex waiter list.
80  bool maybe_unlocking; // Valid at head of Mutex waiter queue;
81  // true if UnlockSlow could be searching
82  // for a waiter to wake. Used for an optimization
83  // in Enqueue(). true is always a valid value.
84  // Can be reset to false when the unlocker or any
85  // writer releases the lock, or a reader fully
86  // releases the lock. It may not be set to false
87  // by a reader that decrements the count to
88  // non-zero. protected by mutex spinlock
89  bool suppress_fatal_errors; // If true, try to proceed even in the face
90  // of broken invariants. This is used within
91  // fatal signal handlers to improve the
92  // chances of debug logging information being
93  // output successfully.
94  int priority; // Priority of thread (updated every so often).
95 
96  // State values:
97  // kAvailable: This PerThreadSynch is available.
98  // kQueued: This PerThreadSynch is unavailable, it's currently queued on a
99  // Mutex or CondVar waistlist.
100  //
101  // Transitions from kQueued to kAvailable require a release
102  // barrier. This is needed as a waiter may use "state" to
103  // independently observe that it's no longer queued.
104  //
105  // Transitions from kAvailable to kQueued require no barrier, they
106  // are externally ordered by the Mutex.
107  enum State {
110  };
111  std::atomic<State> state;
112 
113  // The wait parameters of the current wait. waitp is null if the
114  // thread is not waiting. Transitions from null to non-null must
115  // occur before the enqueue commit point (state = kQueued in
116  // Enqueue() and CondVarEnqueue()). Transitions from non-null to
117  // null must occur after the wait is finished (state = kAvailable in
118  // Mutex::Block() and CondVar::WaitCommon()). This field may be
119  // changed only by the thread that describes this PerThreadSynch. A
120  // special case is Fer(), which calls Enqueue() on another thread,
121  // but with an identical SynchWaitParams pointer, thus leaving the
122  // pointer unchanged.
124 
125  intptr_t readers; // Number of readers in mutex.
126 
127  // When priority will next be read (cycles).
129 
130  // Locks held; used during deadlock detection.
131  // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity().
133 };
134 
135 // The instances of this class are allocated in NewThreadIdentity() with an
136 // alignment of PerThreadSynch::kAlignment.
138  // Must be the first member. The Mutex implementation requires that
139  // the PerThreadSynch object associated with each thread is
140  // PerThreadSynch::kAlignment aligned. We provide this alignment on
141  // ThreadIdentity itself.
143 
144  // Private: Reserved for absl::synchronization_internal::Waiter.
145  struct WaiterState {
146  alignas(void*) char data[128];
147  } waiter_state;
148 
149  // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter().
150  std::atomic<int>* blocked_count_ptr;
151 
152  // The following variables are mostly read/written just by the
153  // thread itself. The only exception is that these are read by
154  // a ticker thread as a hint.
155  std::atomic<int> ticker; // Tick counter, incremented once per second.
156  std::atomic<int> wait_start; // Ticker value when thread started waiting.
157  std::atomic<bool> is_idle; // Has thread become idle yet?
158 
160 };
161 
162 // Returns the ThreadIdentity object representing the calling thread; guaranteed
163 // to be unique for its lifetime. The returned object will remain valid for the
164 // program's lifetime; although it may be re-assigned to a subsequent thread.
165 // If one does not exist, return nullptr instead.
166 //
167 // Does not malloc(*), and is async-signal safe.
168 // [*] Technically pthread_setspecific() does malloc on first use; however this
169 // is handled internally within tcmalloc's initialization already.
170 //
171 // New ThreadIdentity objects can be constructed and associated with a thread
172 // by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h.
174 
175 using ThreadIdentityReclaimerFunction = void (*)(void*);
176 
177 // Sets the current thread identity to the given value. 'reclaimer' is a
178 // pointer to the global function for cleaning up instances on thread
179 // destruction.
182 
183 // Removes the currently associated ThreadIdentity from the running thread.
184 // This must be called from inside the ThreadIdentityReclaimerFunction, and only
185 // from that function.
187 
188 // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode
189 // index>
190 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
191 #error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set
192 #else
193 #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0
194 #endif
195 
196 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS
197 #error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set
198 #else
199 #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1
200 #endif
201 
202 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11
203 #error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set
204 #else
205 #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2
206 #endif
207 
208 #ifdef ABSL_THREAD_IDENTITY_MODE
209 #error ABSL_THREAD_IDENTITY_MODE cannot be directly set
210 #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE)
211 #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE
212 #elif defined(_WIN32) && !defined(__MINGW32__)
213 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
214 #elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL)
215 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11
216 #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \
217  (__GOOGLE_GRTE_VERSION__ >= 20140228L)
218 // Support for async-safe TLS was specifically added in GRTEv4. It's not
219 // present in the upstream eglibc.
220 // Note: Current default for production systems.
221 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS
222 #else
223 #define ABSL_THREAD_IDENTITY_MODE \
224  ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
225 #endif
226 
227 #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \
228  ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11
229 
230 #if ABSL_PER_THREAD_TLS
231 ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity*
232  thread_identity_ptr;
233 #elif defined(ABSL_HAVE_THREAD_LOCAL)
234 ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;
235 #else
236 #error Thread-local storage not detected on this platform
237 #endif
238 
239 // thread_local variables cannot be in headers exposed by DLLs or in certain
240 // build configurations on Apple platforms. However, it is important for
241 // performance reasons in general that `CurrentThreadIdentityIfPresent` be
242 // inlined. In the other cases we opt to have the function not be inlined. Note
243 // that `CurrentThreadIdentityIfPresent` is declared above so we can exclude
244 // this entire inline definition.
245 #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \
246  !defined(ABSL_CONSUME_DLL)
247 #define ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 1
248 #endif
249 
250 #ifdef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT
251 inline ThreadIdentity* CurrentThreadIdentityIfPresent() {
252  return thread_identity_ptr;
253 }
254 #endif
255 
256 #elif ABSL_THREAD_IDENTITY_MODE != \
257  ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC
258 #error Unknown ABSL_THREAD_IDENTITY_MODE
259 #endif
260 
261 } // namespace base_internal
263 } // namespace absl
264 
265 #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
absl::base_internal::PerThreadSynch::State
State
Definition: abseil-cpp/absl/base/internal/thread_identity.h:107
absl::base_internal::ThreadIdentity
Definition: abseil-cpp/absl/base/internal/thread_identity.h:137
ABSL_CONST_INIT
#define ABSL_CONST_INIT
Definition: abseil-cpp/absl/base/attributes.h:716
absl::base_internal::ThreadIdentity::ticker
std::atomic< int > ticker
Definition: abseil-cpp/absl/base/internal/thread_identity.h:155
absl::base_internal::PerThreadSynch::skip
PerThreadSynch * skip
Definition: abseil-cpp/absl/base/internal/thread_identity.h:66
absl::base_internal::PerThreadSynch::waitp
SynchWaitParams * waitp
Definition: abseil-cpp/absl/base/internal/thread_identity.h:123
absl::base_internal::ThreadIdentity::wait_start
std::atomic< int > wait_start
Definition: abseil-cpp/absl/base/internal/thread_identity.h:156
absl::base_internal::ThreadIdentity::next
ThreadIdentity * next
Definition: abseil-cpp/absl/base/internal/thread_identity.h:159
absl::base_internal::PerThreadSynch::kAvailable
@ kAvailable
Definition: abseil-cpp/absl/base/internal/thread_identity.h:108
absl::base_internal::PerThreadSynch::maybe_unlocking
bool maybe_unlocking
Definition: abseil-cpp/absl/base/internal/thread_identity.h:80
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::base_internal::PerThreadSynch
Definition: abseil-cpp/absl/base/internal/thread_identity.h:49
absl::base_internal::CurrentThreadIdentityIfPresent
ThreadIdentity * CurrentThreadIdentityIfPresent()
Definition: abseil-cpp/absl/base/internal/thread_identity.cc:128
absl::base_internal::ThreadIdentity::waiter_state
struct absl::base_internal::ThreadIdentity::WaiterState waiter_state
absl::SynchLocksHeld
Definition: abseil-cpp/absl/synchronization/mutex.cc:509
absl::base_internal::PerThreadSynch::wake
bool wake
Definition: abseil-cpp/absl/base/internal/thread_identity.h:73
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::base_internal::PerThreadSynch::thread_identity
ThreadIdentity * thread_identity()
Definition: abseil-cpp/absl/base/internal/thread_identity.h:61
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
absl::base_internal::ThreadIdentity::WaiterState
Definition: abseil-cpp/absl/base/internal/thread_identity.h:145
absl::base_internal::ThreadIdentity::per_thread_synch
PerThreadSynch per_thread_synch
Definition: abseil-cpp/absl/base/internal/thread_identity.h:142
absl::base_internal::PerThreadSynch::may_skip
bool may_skip
Definition: abseil-cpp/absl/base/internal/thread_identity.h:69
intptr_t
_W64 signed int intptr_t
Definition: stdint-msvc2008.h:118
ABSL_PER_THREAD_TLS_KEYWORD
#define ABSL_PER_THREAD_TLS_KEYWORD
Definition: abseil-cpp/absl/base/internal/per_thread_tls.h:48
absl::base_internal::PerThreadSynch::suppress_fatal_errors
bool suppress_fatal_errors
Definition: abseil-cpp/absl/base/internal/thread_identity.h:89
absl::base_internal::ThreadIdentity::blocked_count_ptr
std::atomic< int > * blocked_count_ptr
Definition: abseil-cpp/absl/base/internal/thread_identity.h:150
absl::SynchWaitParams
Definition: abseil-cpp/absl/synchronization/mutex.cc:478
absl::base_internal::SetCurrentThreadIdentity
ABSL_CONST_INIT void SetCurrentThreadIdentity(ThreadIdentity *identity, ThreadIdentityReclaimerFunction reclaimer)
Definition: abseil-cpp/absl/base/internal/thread_identity.cc:71
absl::base_internal::ClearCurrentThreadIdentity
void ClearCurrentThreadIdentity()
Definition: abseil-cpp/absl/base/internal/thread_identity.cc:132
absl::base_internal::PerThreadSynch::next_priority_read_cycles
int64_t next_priority_read_cycles
Definition: abseil-cpp/absl/base/internal/thread_identity.h:128
absl::base_internal::ThreadIdentityReclaimerFunction
void(*)(void *) ThreadIdentityReclaimerFunction
Definition: abseil-cpp/absl/base/internal/thread_identity.h:175
absl::base_internal::PerThreadSynch::next
PerThreadSynch * next
Definition: abseil-cpp/absl/base/internal/thread_identity.h:65
absl::base_internal::PerThreadSynch::readers
intptr_t readers
Definition: abseil-cpp/absl/base/internal/thread_identity.h:125
absl::base_internal::PerThreadSynch::kLowZeroBits
static constexpr int kLowZeroBits
Definition: abseil-cpp/absl/base/internal/thread_identity.h:55
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::base_internal::PerThreadSynch::cond_waiter
bool cond_waiter
Definition: abseil-cpp/absl/base/internal/thread_identity.h:79
absl::base_internal::PerThreadSynch::state
std::atomic< State > state
Definition: abseil-cpp/absl/base/internal/thread_identity.h:111
absl::base_internal::ThreadIdentity::WaiterState::data
char data[128]
Definition: abseil-cpp/absl/base/internal/thread_identity.h:146
absl::base_internal::PerThreadSynch::kAlignment
static constexpr int kAlignment
Definition: abseil-cpp/absl/base/internal/thread_identity.h:56
absl::base_internal::PerThreadSynch::priority
int priority
Definition: abseil-cpp/absl/base/internal/thread_identity.h:94
absl::base_internal::PerThreadSynch::kQueued
@ kQueued
Definition: abseil-cpp/absl/base/internal/thread_identity.h:109
absl::base_internal::ThreadIdentity::is_idle
std::atomic< bool > is_idle
Definition: abseil-cpp/absl/base/internal/thread_identity.h:157
absl::base_internal::PerThreadSynch::all_locks
SynchLocksHeld * all_locks
Definition: abseil-cpp/absl/base/internal/thread_identity.h:132


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:35