|
|
|||
File indexing completed on 2025-12-18 09:41:34
0001 // Copyright 2017 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 // 0015 // Each active thread has an ThreadIdentity that may represent the thread in 0016 // various level interfaces. ThreadIdentity objects are never deallocated. 0017 // When a thread terminates, its ThreadIdentity object may be reused for a 0018 // thread created later. 0019 0020 #ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ 0021 #define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ 0022 0023 #ifndef _WIN32 0024 #include <pthread.h> 0025 // Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when 0026 // supported. 0027 #include <unistd.h> 0028 #endif 0029 0030 #include <atomic> 0031 #include <cstdint> 0032 0033 #include "absl/base/config.h" 0034 #include "absl/base/internal/per_thread_tls.h" 0035 #include "absl/base/optimization.h" 0036 0037 namespace absl { 0038 ABSL_NAMESPACE_BEGIN 0039 0040 struct SynchLocksHeld; 0041 struct SynchWaitParams; 0042 0043 namespace base_internal { 0044 0045 class SpinLock; 0046 struct ThreadIdentity; 0047 0048 // Used by the implementation of absl::Mutex and absl::CondVar. 0049 struct PerThreadSynch { 0050 // The internal representation of absl::Mutex and absl::CondVar rely 0051 // on the alignment of PerThreadSynch. Both store the address of the 0052 // PerThreadSynch in the high-order bits of their internal state, 0053 // which means the low kLowZeroBits of the address of PerThreadSynch 0054 // must be zero. 0055 static constexpr int kLowZeroBits = 8; 0056 static constexpr int kAlignment = 1 << kLowZeroBits; 0057 0058 // Returns the associated ThreadIdentity. 0059 // This can be implemented as a cast because we guarantee 0060 // PerThreadSynch is the first element of ThreadIdentity. 0061 ThreadIdentity* thread_identity() { 0062 return reinterpret_cast<ThreadIdentity*>(this); 0063 } 0064 0065 PerThreadSynch* next; // Circular waiter queue; initialized to 0. 0066 PerThreadSynch* skip; // If non-zero, all entries in Mutex queue 0067 // up to and including "skip" have same 0068 // condition as this, and will be woken later 0069 bool may_skip; // if false while on mutex queue, a mutex unlocker 0070 // is using this PerThreadSynch as a terminator. Its 0071 // skip field must not be filled in because the loop 0072 // might then skip over the terminator. 0073 bool wake; // This thread is to be woken from a Mutex. 0074 // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the 0075 // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. 0076 // 0077 // The value of "x->cond_waiter" is meaningless if "x" is not on a 0078 // Mutex waiter list. 0079 bool cond_waiter; 0080 bool maybe_unlocking; // Valid at head of Mutex waiter queue; 0081 // true if UnlockSlow could be searching 0082 // for a waiter to wake. Used for an optimization 0083 // in Enqueue(). true is always a valid value. 0084 // Can be reset to false when the unlocker or any 0085 // writer releases the lock, or a reader fully 0086 // releases the lock. It may not be set to false 0087 // by a reader that decrements the count to 0088 // non-zero. protected by mutex spinlock 0089 bool suppress_fatal_errors; // If true, try to proceed even in the face 0090 // of broken invariants. This is used within 0091 // fatal signal handlers to improve the 0092 // chances of debug logging information being 0093 // output successfully. 0094 int priority; // Priority of thread (updated every so often). 0095 0096 // State values: 0097 // kAvailable: This PerThreadSynch is available. 0098 // kQueued: This PerThreadSynch is unavailable, it's currently queued on a 0099 // Mutex or CondVar waistlist. 0100 // 0101 // Transitions from kQueued to kAvailable require a release 0102 // barrier. This is needed as a waiter may use "state" to 0103 // independently observe that it's no longer queued. 0104 // 0105 // Transitions from kAvailable to kQueued require no barrier, they 0106 // are externally ordered by the Mutex. 0107 enum State { kAvailable, kQueued }; 0108 std::atomic<State> state; 0109 0110 // The wait parameters of the current wait. waitp is null if the 0111 // thread is not waiting. Transitions from null to non-null must 0112 // occur before the enqueue commit point (state = kQueued in 0113 // Enqueue() and CondVarEnqueue()). Transitions from non-null to 0114 // null must occur after the wait is finished (state = kAvailable in 0115 // Mutex::Block() and CondVar::WaitCommon()). This field may be 0116 // changed only by the thread that describes this PerThreadSynch. A 0117 // special case is Fer(), which calls Enqueue() on another thread, 0118 // but with an identical SynchWaitParams pointer, thus leaving the 0119 // pointer unchanged. 0120 SynchWaitParams* waitp; 0121 0122 intptr_t readers; // Number of readers in mutex. 0123 0124 // When priority will next be read (cycles). 0125 int64_t next_priority_read_cycles; 0126 0127 // Locks held; used during deadlock detection. 0128 // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity(). 0129 SynchLocksHeld* all_locks; 0130 }; 0131 0132 // The instances of this class are allocated in NewThreadIdentity() with an 0133 // alignment of PerThreadSynch::kAlignment. 0134 // 0135 // NOTE: The layout of fields in this structure is critical, please do not 0136 // add, remove, or modify the field placements without fully auditing the 0137 // layout. 0138 struct ThreadIdentity { 0139 // Must be the first member. The Mutex implementation requires that 0140 // the PerThreadSynch object associated with each thread is 0141 // PerThreadSynch::kAlignment aligned. We provide this alignment on 0142 // ThreadIdentity itself. 0143 PerThreadSynch per_thread_synch; 0144 0145 // Private: Reserved for absl::synchronization_internal::Waiter. 0146 struct WaiterState { 0147 alignas(void*) char data[256]; 0148 } waiter_state; 0149 0150 // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). 0151 std::atomic<int>* blocked_count_ptr; 0152 0153 // The following variables are mostly read/written just by the 0154 // thread itself. The only exception is that these are read by 0155 // a ticker thread as a hint. 0156 std::atomic<int> ticker; // Tick counter, incremented once per second. 0157 std::atomic<int> wait_start; // Ticker value when thread started waiting. 0158 std::atomic<bool> is_idle; // Has thread become idle yet? 0159 0160 ThreadIdentity* next; 0161 }; 0162 0163 // Returns the ThreadIdentity object representing the calling thread; guaranteed 0164 // to be unique for its lifetime. The returned object will remain valid for the 0165 // program's lifetime; although it may be re-assigned to a subsequent thread. 0166 // If one does not exist, return nullptr instead. 0167 // 0168 // Does not malloc(*), and is async-signal safe. 0169 // [*] Technically pthread_setspecific() does malloc on first use; however this 0170 // is handled internally within tcmalloc's initialization already. Note that 0171 // darwin does *not* use tcmalloc, so this can catch you if using MallocHooks 0172 // on Apple platforms. Whatever function is calling your MallocHooks will need 0173 // to watch for recursion on Apple platforms. 0174 // 0175 // New ThreadIdentity objects can be constructed and associated with a thread 0176 // by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h. 0177 ThreadIdentity* CurrentThreadIdentityIfPresent(); 0178 0179 using ThreadIdentityReclaimerFunction = void (*)(void*); 0180 0181 // Sets the current thread identity to the given value. 'reclaimer' is a 0182 // pointer to the global function for cleaning up instances on thread 0183 // destruction. 0184 void SetCurrentThreadIdentity(ThreadIdentity* identity, 0185 ThreadIdentityReclaimerFunction reclaimer); 0186 0187 // Removes the currently associated ThreadIdentity from the running thread. 0188 // This must be called from inside the ThreadIdentityReclaimerFunction, and only 0189 // from that function. 0190 void ClearCurrentThreadIdentity(); 0191 0192 // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode 0193 // index> 0194 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0195 #error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be directly set 0196 #else 0197 #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 0198 #endif 0199 0200 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS 0201 #error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be directly set 0202 #else 0203 #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 0204 #endif 0205 0206 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 0207 #error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be directly set 0208 #else 0209 #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 0210 #endif 0211 0212 #ifdef ABSL_THREAD_IDENTITY_MODE 0213 #error ABSL_THREAD_IDENTITY_MODE cannot be directly set 0214 #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) 0215 #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE 0216 #elif defined(_WIN32) && !defined(__MINGW32__) 0217 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 0218 #elif defined(__APPLE__) && defined(ABSL_HAVE_THREAD_LOCAL) 0219 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 0220 #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \ 0221 (__GOOGLE_GRTE_VERSION__ >= 20140228L) 0222 // Support for async-safe TLS was specifically added in GRTEv4. It's not 0223 // present in the upstream eglibc. 0224 // Note: Current default for production systems. 0225 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS 0226 #else 0227 #define ABSL_THREAD_IDENTITY_MODE \ 0228 ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0229 #endif 0230 0231 #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ 0232 ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 0233 0234 #if ABSL_PER_THREAD_TLS 0235 ABSL_CONST_INIT extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* 0236 thread_identity_ptr; 0237 #elif defined(ABSL_HAVE_THREAD_LOCAL) 0238 ABSL_CONST_INIT extern thread_local ThreadIdentity* thread_identity_ptr; 0239 #else 0240 #error Thread-local storage not detected on this platform 0241 #endif 0242 0243 // thread_local variables cannot be in headers exposed by DLLs or in certain 0244 // build configurations on Apple platforms. However, it is important for 0245 // performance reasons in general that `CurrentThreadIdentityIfPresent` be 0246 // inlined. In the other cases we opt to have the function not be inlined. Note 0247 // that `CurrentThreadIdentityIfPresent` is declared above so we can exclude 0248 // this entire inline definition. 0249 #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) && \ 0250 !defined(ABSL_CONSUME_DLL) 0251 #define ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 1 0252 #endif 0253 0254 #ifdef ABSL_INTERNAL_INLINE_CURRENT_THREAD_IDENTITY_IF_PRESENT 0255 inline ThreadIdentity* CurrentThreadIdentityIfPresent() { 0256 return thread_identity_ptr; 0257 } 0258 #endif 0259 0260 #elif ABSL_THREAD_IDENTITY_MODE != \ 0261 ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0262 #error Unknown ABSL_THREAD_IDENTITY_MODE 0263 #endif 0264 0265 } // namespace base_internal 0266 ABSL_NAMESPACE_END 0267 } // namespace absl 0268 0269 #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|