00001 // Copyright 2017 The Abseil Authors. 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // https://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 // 00015 // Each active thread has an ThreadIdentity that may represent the thread in 00016 // various level interfaces. ThreadIdentity objects are never deallocated. 00017 // When a thread terminates, its ThreadIdentity object may be reused for a 00018 // thread created later. 00019 00020 #ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ 00021 #define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ 00022 00023 #ifndef _WIN32 00024 #include <pthread.h> 00025 // Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when 00026 // supported. 00027 #include <unistd.h> 00028 #endif 00029 00030 #include <atomic> 00031 #include <cstdint> 00032 00033 #include "absl/base/internal/per_thread_tls.h" 00034 00035 namespace absl { 00036 00037 struct SynchLocksHeld; 00038 struct SynchWaitParams; 00039 00040 namespace base_internal { 00041 00042 class SpinLock; 00043 struct ThreadIdentity; 00044 00045 // Used by the implementation of absl::Mutex and absl::CondVar. 00046 struct PerThreadSynch { 00047 // The internal representation of absl::Mutex and absl::CondVar rely 00048 // on the alignment of PerThreadSynch. Both store the address of the 00049 // PerThreadSynch in the high-order bits of their internal state, 00050 // which means the low kLowZeroBits of the address of PerThreadSynch 00051 // must be zero. 00052 static constexpr int kLowZeroBits = 8; 00053 static constexpr int kAlignment = 1 << kLowZeroBits; 00054 00055 // Returns the associated ThreadIdentity. 00056 // This can be implemented as a cast because we guarantee 00057 // PerThreadSynch is the first element of ThreadIdentity. 00058 ThreadIdentity* thread_identity() { 00059 return reinterpret_cast<ThreadIdentity*>(this); 00060 } 00061 00062 PerThreadSynch *next; // Circular waiter queue; initialized to 0. 00063 PerThreadSynch *skip; // If non-zero, all entries in Mutex queue 00064 // up to and including "skip" have same 00065 // condition as this, and will be woken later 00066 bool may_skip; // if false while on mutex queue, a mutex unlocker 00067 // is using this PerThreadSynch as a terminator. Its 00068 // skip field must not be filled in because the loop 00069 // might then skip over the terminator. 00070 00071 // The wait parameters of the current wait. waitp is null if the 00072 // thread is not waiting. Transitions from null to non-null must 00073 // occur before the enqueue commit point (state = kQueued in 00074 // Enqueue() and CondVarEnqueue()). Transitions from non-null to 00075 // null must occur after the wait is finished (state = kAvailable in 00076 // Mutex::Block() and CondVar::WaitCommon()). This field may be 00077 // changed only by the thread that describes this PerThreadSynch. A 00078 // special case is Fer(), which calls Enqueue() on another thread, 00079 // but with an identical SynchWaitParams pointer, thus leaving the 00080 // pointer unchanged. 00081 SynchWaitParams *waitp; 00082 00083 bool suppress_fatal_errors; // If true, try to proceed even in the face of 00084 // broken invariants. This is used within fatal 00085 // signal handlers to improve the chances of 00086 // debug logging information being output 00087 // successfully. 00088 00089 intptr_t readers; // Number of readers in mutex. 00090 int priority; // Priority of thread (updated every so often). 00091 00092 // When priority will next be read (cycles). 00093 int64_t next_priority_read_cycles; 00094 00095 // State values: 00096 // kAvailable: This PerThreadSynch is available. 00097 // kQueued: This PerThreadSynch is unavailable, it's currently queued on a 00098 // Mutex or CondVar waistlist. 00099 // 00100 // Transitions from kQueued to kAvailable require a release 00101 // barrier. This is needed as a waiter may use "state" to 00102 // independently observe that it's no longer queued. 00103 // 00104 // Transitions from kAvailable to kQueued require no barrier, they 00105 // are externally ordered by the Mutex. 00106 enum State { 00107 kAvailable, 00108 kQueued 00109 }; 00110 std::atomic<State> state; 00111 00112 bool maybe_unlocking; // Valid at head of Mutex waiter queue; 00113 // true if UnlockSlow could be searching 00114 // for a waiter to wake. Used for an optimization 00115 // in Enqueue(). true is always a valid value. 00116 // Can be reset to false when the unlocker or any 00117 // writer releases the lock, or a reader fully releases 00118 // the lock. It may not be set to false by a reader 00119 // that decrements the count to non-zero. 00120 // protected by mutex spinlock 00121 00122 bool wake; // This thread is to be woken from a Mutex. 00123 00124 // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the 00125 // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. 00126 // 00127 // The value of "x->cond_waiter" is meaningless if "x" is not on a 00128 // Mutex waiter list. 00129 bool cond_waiter; 00130 00131 // Locks held; used during deadlock detection. 00132 // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity(). 00133 SynchLocksHeld *all_locks; 00134 }; 00135 00136 struct ThreadIdentity { 00137 // Must be the first member. The Mutex implementation requires that 00138 // the PerThreadSynch object associated with each thread is 00139 // PerThreadSynch::kAlignment aligned. We provide this alignment on 00140 // ThreadIdentity itself. 00141 PerThreadSynch per_thread_synch; 00142 00143 // Private: Reserved for absl::synchronization_internal::Waiter. 00144 struct WaiterState { 00145 char data[128]; 00146 } waiter_state; 00147 00148 // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). 00149 std::atomic<int>* blocked_count_ptr; 00150 00151 // The following variables are mostly read/written just by the 00152 // thread itself. The only exception is that these are read by 00153 // a ticker thread as a hint. 00154 std::atomic<int> ticker; // Tick counter, incremented once per second. 00155 std::atomic<int> wait_start; // Ticker value when thread started waiting. 00156 std::atomic<bool> is_idle; // Has thread become idle yet? 00157 00158 ThreadIdentity* next; 00159 }; 00160 00161 // Returns the ThreadIdentity object representing the calling thread; guaranteed 00162 // to be unique for its lifetime. The returned object will remain valid for the 00163 // program's lifetime; although it may be re-assigned to a subsequent thread. 00164 // If one does not exist, return nullptr instead. 00165 // 00166 // Does not malloc(*), and is async-signal safe. 00167 // [*] Technically pthread_setspecific() does malloc on first use; however this 00168 // is handled internally within tcmalloc's initialization already. 00169 // 00170 // New ThreadIdentity objects can be constructed and associated with a thread 00171 // by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h. 00172 ThreadIdentity* CurrentThreadIdentityIfPresent(); 00173 00174 using ThreadIdentityReclaimerFunction = void (*)(void*); 00175 00176 // Sets the current thread identity to the given value. 'reclaimer' is a 00177 // pointer to the global function for cleaning up instances on thread 00178 // destruction. 00179 void SetCurrentThreadIdentity(ThreadIdentity* identity, 00180 ThreadIdentityReclaimerFunction reclaimer); 00181 00182 // Removes the currently associated ThreadIdentity from the running thread. 00183 // This must be called from inside the ThreadIdentityReclaimerFunction, and only 00184 // from that function. 00185 void ClearCurrentThreadIdentity(); 00186 00187 // May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE=<mode 00188 // index> 00189 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 00190 #error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be direcly set 00191 #else 00192 #define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 00193 #endif 00194 00195 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS 00196 #error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be direcly set 00197 #else 00198 #define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 00199 #endif 00200 00201 #ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 00202 #error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be direcly set 00203 #else 00204 #define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 00205 #endif 00206 00207 #ifdef ABSL_THREAD_IDENTITY_MODE 00208 #error ABSL_THREAD_IDENTITY_MODE cannot be direcly set 00209 #elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) 00210 #define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE 00211 #elif defined(_WIN32) 00212 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 00213 #elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \ 00214 (__GOOGLE_GRTE_VERSION__ >= 20140228L) 00215 // Support for async-safe TLS was specifically added in GRTEv4. It's not 00216 // present in the upstream eglibc. 00217 // Note: Current default for production systems. 00218 #define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS 00219 #else 00220 #define ABSL_THREAD_IDENTITY_MODE \ 00221 ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 00222 #endif 00223 00224 #if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ 00225 ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 00226 00227 extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr; 00228 00229 inline ThreadIdentity* CurrentThreadIdentityIfPresent() { 00230 return thread_identity_ptr; 00231 } 00232 00233 #elif ABSL_THREAD_IDENTITY_MODE != \ 00234 ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 00235 #error Unknown ABSL_THREAD_IDENTITY_MODE 00236 #endif 00237 00238 } // namespace base_internal 00239 } // namespace absl 00240 00241 #endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_