You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

thread_identity.h 12 kB

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