/src/abseil-cpp/absl/base/internal/thread_identity.h
Line  | Count  | Source  | 
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 { | 
38  |  | ABSL_NAMESPACE_BEGIN  | 
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.  | 
49  |  | struct PerThreadSynch { | 
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.  | 
61  | 0  |   ThreadIdentity* thread_identity() { | 
62  | 0  |     return reinterpret_cast<ThreadIdentity*>(this);  | 
63  | 0  |   }  | 
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.  | 
79  |  |   bool cond_waiter;  | 
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 { kAvailable, kQueued }; | 
108  |  |   std::atomic<State> state;  | 
109  |  |  | 
110  |  |   // The wait parameters of the current wait.  waitp is null if the  | 
111  |  |   // thread is not waiting. Transitions from null to non-null must  | 
112  |  |   // occur before the enqueue commit point (state = kQueued in  | 
113  |  |   // Enqueue() and CondVarEnqueue()). Transitions from non-null to  | 
114  |  |   // null must occur after the wait is finished (state = kAvailable in  | 
115  |  |   // Mutex::Block() and CondVar::WaitCommon()). This field may be  | 
116  |  |   // changed only by the thread that describes this PerThreadSynch.  A  | 
117  |  |   // special case is Fer(), which calls Enqueue() on another thread,  | 
118  |  |   // but with an identical SynchWaitParams pointer, thus leaving the  | 
119  |  |   // pointer unchanged.  | 
120  |  |   SynchWaitParams* waitp;  | 
121  |  |  | 
122  |  |   intptr_t readers;  // Number of readers in mutex.  | 
123  |  |  | 
124  |  |   // When priority will next be read (cycles).  | 
125  |  |   int64_t next_priority_read_cycles;  | 
126  |  |  | 
127  |  |   // Locks held; used during deadlock detection.  | 
128  |  |   // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity().  | 
129  |  |   SynchLocksHeld* all_locks;  | 
130  |  | };  | 
131  |  |  | 
132  |  | // The instances of this class are allocated in NewThreadIdentity() with an  | 
133  |  | // alignment of PerThreadSynch::kAlignment and never destroyed. Initialization  | 
134  |  | // should happen in OneTimeInitThreadIdentity().  | 
135  |  | //  | 
136  |  | // Instances may be reused by new threads - fields should be reset in  | 
137  |  | // ResetThreadIdentityBetweenReuse().  | 
138  |  | //  | 
139  |  | // NOTE: The layout of fields in this structure is critical, please do not  | 
140  |  | //       add, remove, or modify the field placements without fully auditing the  | 
141  |  | //       layout.  | 
142  |  | struct ThreadIdentity { | 
143  |  |   // Must be the first member.  The Mutex implementation requires that  | 
144  |  |   // the PerThreadSynch object associated with each thread is  | 
145  |  |   // PerThreadSynch::kAlignment aligned.  We provide this alignment on  | 
146  |  |   // ThreadIdentity itself.  | 
147  |  |   PerThreadSynch per_thread_synch;  | 
148  |  |  | 
149  |  |   // Private: Reserved for absl::synchronization_internal::Waiter.  | 
150  |  |   struct WaiterState { | 
151  |  |     alignas(void*) char data[256];  | 
152  |  |   } waiter_state;  | 
153  |  |  | 
154  |  |   // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). | 
155  |  |   std::atomic<int>* blocked_count_ptr;  | 
156  |  |  | 
157  |  |   // The following variables are mostly read/written just by the  | 
158  |  |   // thread itself.  The only exception is that these are read by  | 
159  |  |   // a ticker thread as a hint.  | 
160  |  |   std::atomic<int> ticker;      // Tick counter, incremented once per second.  | 
161  |  |   std::atomic<int> wait_start;  // Ticker value when thread started waiting.  | 
162  |  |   std::atomic<bool> is_idle;    // Has thread become idle yet?  | 
163  |  |  | 
164  |  |   ThreadIdentity* next;  | 
165  |  | };  | 
166  |  |  | 
167  |  | // Returns the ThreadIdentity object representing the calling thread; guaranteed  | 
168  |  | // to be unique for its lifetime.  The returned object will remain valid for the  | 
169  |  | // program's lifetime; although it may be re-assigned to a subsequent thread.  | 
170  |  | // If one does not exist, return nullptr instead.  | 
171  |  | //  | 
172  |  | // Does not malloc(*), and is async-signal safe.  | 
173  |  | // [*] Technically pthread_setspecific() does malloc on first use; however this  | 
174  |  | // is handled internally within tcmalloc's initialization already. Note that  | 
175  |  | // darwin does *not* use tcmalloc, so this can catch you if using MallocHooks  | 
176  |  | // on Apple platforms. Whatever function is calling your MallocHooks will need  | 
177  |  | // to watch for recursion on Apple platforms.  | 
178  |  | //  | 
179  |  | // New ThreadIdentity objects can be constructed and associated with a thread  | 
180  |  | // by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h.  | 
181  |  | ThreadIdentity* CurrentThreadIdentityIfPresent();  | 
182  |  |  | 
183  |  | using ThreadIdentityReclaimerFunction = void (*)(void*);  | 
184  |  |  | 
185  |  | // Sets the current thread identity to the given value.  'reclaimer' is a  | 
186  |  | // pointer to the global function for cleaning up instances on thread  | 
187  |  | // destruction.  | 
188  |  | void SetCurrentThreadIdentity(ThreadIdentity* identity,  | 
189  |  |                               ThreadIdentityReclaimerFunction reclaimer);  | 
190  |  |  | 
191  |  | // Removes the currently associated ThreadIdentity from the running thread.  | 
192  |  | // This must be called from inside the ThreadIdentityReclaimerFunction, and only  | 
193  |  | // from that function.  | 
194  |  | void ClearCurrentThreadIdentity();  | 
195  |  |  | 
196  |  | // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode  | 
197  |  | // index>  | 
198  |  | #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC  | 
199  |  | #error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set  | 
200  |  | #else  | 
201  |  | #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0  | 
202  |  | #endif  | 
203  |  |  | 
204  |  | #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS  | 
205  |  | #error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set  | 
206  |  | #else  | 
207  |  | #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1  | 
208  |  | #endif  | 
209  |  |  | 
210  |  | #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11  | 
211  |  | #error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set  | 
212  |  | #else  | 
213  |  | #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2  | 
214  |  | #endif  | 
215  |  |  | 
216  |  | #ifdef ABSL_THREAD_IDENTITY_MODE  | 
217  |  | #error ABSL_THREAD_IDENTITY_MODE cannot be directly set  | 
218  |  | #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE)  | 
219  |  | #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE  | 
220  |  | #elif defined(_WIN32) && !defined(__MINGW32__)  | 
221  |  | #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11  | 
222  |  | #elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL)  | 
223  |  | #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11  | 
224  |  | #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \  | 
225  |  |     (__GOOGLE_GRTE_VERSION__ >= 20140228L)  | 
226  |  | // Support for async-safe TLS was specifically added in GRTEv4.  It's not  | 
227  |  | // present in the upstream eglibc.  | 
228  |  | // Note:  Current default for production systems.  | 
229  |  | #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS  | 
230  |  | #else  | 
231  |  | #define ABSL_THREAD_IDENTITY_MODE \  | 
232  |  |   ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC  | 
233  |  | #endif  | 
234  |  |  | 
235  |  | #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \  | 
236  |  |     ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11  | 
237  |  |  | 
238  |  | #if ABSL_PER_THREAD_TLS  | 
239  |  | ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity*  | 
240  |  |     thread_identity_ptr;  | 
241  |  | #elif defined(ABSL_HAVE_THREAD_LOCAL)  | 
242  |  | ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr;  | 
243  |  | #else  | 
244  |  | #error Thread-local storage not detected on this platform  | 
245  |  | #endif  | 
246  |  |  | 
247  |  | // thread_local variables cannot be in headers exposed by DLLs or in certain  | 
248  |  | // build configurations on Apple platforms. However, it is important for  | 
249  |  | // performance reasons in general that `CurrentThreadIdentityIfPresent` be  | 
250  |  | // inlined. In the other cases we opt to have the function not be inlined. Note  | 
251  |  | // that `CurrentThreadIdentityIfPresent` is declared above so we can exclude  | 
252  |  | // this entire inline definition.  | 
253  |  | #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \  | 
254  |  |     !defined(ABSL_CONSUME_DLL)  | 
255  |  | #define ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 1  | 
256  |  | #endif  | 
257  |  |  | 
258  |  | #ifdef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT  | 
259  |  | inline ThreadIdentity* CurrentThreadIdentityIfPresent() { | 
260  |  |   return thread_identity_ptr;  | 
261  |  | }  | 
262  |  | #endif  | 
263  |  |  | 
264  |  | #elif ABSL_THREAD_IDENTITY_MODE != \  | 
265  |  |     ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC  | 
266  |  | #error Unknown ABSL_THREAD_IDENTITY_MODE  | 
267  |  | #endif  | 
268  |  |  | 
269  |  | }  // namespace base_internal  | 
270  |  | ABSL_NAMESPACE_END  | 
271  |  | }  // namespace absl  | 
272  |  |  | 
273  |  | #endif  // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_  |