thread_identity.h 11 KB

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