mutex.h 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  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. // -----------------------------------------------------------------------------
  16. // mutex.h
  17. // -----------------------------------------------------------------------------
  18. //
  19. // This header file defines a `Mutex` -- a mutually exclusive lock -- and the
  20. // most common type of synchronization primitive for facilitating locks on
  21. // shared resources. A mutex is used to prevent multiple threads from accessing
  22. // and/or writing to a shared resource concurrently.
  23. //
  24. // Unlike a `std::mutex`, the Abseil `Mutex` provides the following additional
  25. // features:
  26. // * Conditional predicates intrinsic to the `Mutex` object
  27. // * Shared/reader locks, in addition to standard exclusive/writer locks
  28. // * Deadlock detection and debug support.
  29. //
  30. // The following helper classes are also defined within this file:
  31. //
  32. // MutexLock - An RAII wrapper to acquire and release a `Mutex` for exclusive/
  33. // write access within the current scope.
  34. //
  35. // ReaderMutexLock
  36. // - An RAII wrapper to acquire and release a `Mutex` for shared/read
  37. // access within the current scope.
  38. //
  39. // WriterMutexLock
  40. // - Effectively an alias for `MutexLock` above, designed for use in
  41. // distinguishing reader and writer locks within code.
  42. //
  43. // In addition to simple mutex locks, this file also defines ways to perform
  44. // locking under certain conditions.
  45. //
  46. // Condition - (Preferred) Used to wait for a particular predicate that
  47. // depends on state protected by the `Mutex` to become true.
  48. // CondVar - A lower-level variant of `Condition` that relies on
  49. // application code to explicitly signal the `CondVar` when
  50. // a condition has been met.
  51. //
  52. // See below for more information on using `Condition` or `CondVar`.
  53. //
  54. // Mutexes and mutex behavior can be quite complicated. The information within
  55. // this header file is limited, as a result. Please consult the Mutex guide for
  56. // more complete information and examples.
  57. #ifndef ABSL_SYNCHRONIZATION_MUTEX_H_
  58. #define ABSL_SYNCHRONIZATION_MUTEX_H_
  59. #include <atomic>
  60. #include <cstdint>
  61. #include <string>
  62. #include "absl/base/const_init.h"
  63. #include "absl/base/internal/identity.h"
  64. #include "absl/base/internal/low_level_alloc.h"
  65. #include "absl/base/internal/thread_identity.h"
  66. #include "absl/base/internal/tsan_mutex_interface.h"
  67. #include "absl/base/port.h"
  68. #include "absl/base/thread_annotations.h"
  69. #include "absl/synchronization/internal/kernel_timeout.h"
  70. #include "absl/synchronization/internal/per_thread_sem.h"
  71. #include "absl/time/time.h"
  72. namespace absl {
  73. ABSL_NAMESPACE_BEGIN
  74. class Condition;
  75. struct SynchWaitParams;
  76. // -----------------------------------------------------------------------------
  77. // Mutex
  78. // -----------------------------------------------------------------------------
  79. //
  80. // A `Mutex` is a non-reentrant (aka non-recursive) Mutually Exclusive lock
  81. // on some resource, typically a variable or data structure with associated
  82. // invariants. Proper usage of mutexes prevents concurrent access by different
  83. // threads to the same resource.
  84. //
  85. // A `Mutex` has two basic operations: `Mutex::Lock()` and `Mutex::Unlock()`.
  86. // The `Lock()` operation *acquires* a `Mutex` (in a state known as an
  87. // *exclusive* -- or write -- lock), while the `Unlock()` operation *releases* a
  88. // Mutex. During the span of time between the Lock() and Unlock() operations,
  89. // a mutex is said to be *held*. By design all mutexes support exclusive/write
  90. // locks, as this is the most common way to use a mutex.
  91. //
  92. // The `Mutex` state machine for basic lock/unlock operations is quite simple:
  93. //
  94. // | | Lock() | Unlock() |
  95. // |----------------+------------+----------|
  96. // | Free | Exclusive | invalid |
  97. // | Exclusive | blocks | Free |
  98. //
  99. // Attempts to `Unlock()` must originate from the thread that performed the
  100. // corresponding `Lock()` operation.
  101. //
  102. // An "invalid" operation is disallowed by the API. The `Mutex` implementation
  103. // is allowed to do anything on an invalid call, including but not limited to
  104. // crashing with a useful error message, silently succeeding, or corrupting
  105. // data structures. In debug mode, the implementation attempts to crash with a
  106. // useful error message.
  107. //
  108. // `Mutex` is not guaranteed to be "fair" in prioritizing waiting threads; it
  109. // is, however, approximately fair over long periods, and starvation-free for
  110. // threads at the same priority.
  111. //
  112. // The lock/unlock primitives are now annotated with lock annotations
  113. // defined in (base/thread_annotations.h). When writing multi-threaded code,
  114. // you should use lock annotations whenever possible to document your lock
  115. // synchronization policy. Besides acting as documentation, these annotations
  116. // also help compilers or static analysis tools to identify and warn about
  117. // issues that could potentially result in race conditions and deadlocks.
  118. //
  119. // For more information about the lock annotations, please see
  120. // [Thread Safety Analysis](http://clang.llvm.org/docs/ThreadSafetyAnalysis.html)
  121. // in the Clang documentation.
  122. //
  123. // See also `MutexLock`, below, for scoped `Mutex` acquisition.
  124. class ABSL_LOCKABLE Mutex {
  125. public:
  126. // Creates a `Mutex` that is not held by anyone. This constructor is
  127. // typically used for Mutexes allocated on the heap or the stack.
  128. //
  129. // To create `Mutex` instances with static storage duration
  130. // (e.g. a namespace-scoped or global variable), see
  131. // `Mutex::Mutex(absl::kConstInit)` below instead.
  132. Mutex();
  133. // Creates a mutex with static storage duration. A global variable
  134. // constructed this way avoids the lifetime issues that can occur on program
  135. // startup and shutdown. (See absl/base/const_init.h.)
  136. //
  137. // For Mutexes allocated on the heap and stack, instead use the default
  138. // constructor, which can interact more fully with the thread sanitizer.
  139. //
  140. // Example usage:
  141. // namespace foo {
  142. // ABSL_CONST_INIT absl::Mutex mu(absl::kConstInit);
  143. // }
  144. explicit constexpr Mutex(absl::ConstInitType);
  145. ~Mutex();
  146. // Mutex::Lock()
  147. //
  148. // Blocks the calling thread, if necessary, until this `Mutex` is free, and
  149. // then acquires it exclusively. (This lock is also known as a "write lock.")
  150. void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION();
  151. // Mutex::Unlock()
  152. //
  153. // Releases this `Mutex` and returns it from the exclusive/write state to the
  154. // free state. Calling thread must hold the `Mutex` exclusively.
  155. void Unlock() ABSL_UNLOCK_FUNCTION();
  156. // Mutex::TryLock()
  157. //
  158. // If the mutex can be acquired without blocking, does so exclusively and
  159. // returns `true`. Otherwise, returns `false`. Returns `true` with high
  160. // probability if the `Mutex` was free.
  161. bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true);
  162. // Mutex::AssertHeld()
  163. //
  164. // Return immediately if this thread holds the `Mutex` exclusively (in write
  165. // mode). Otherwise, may report an error (typically by crashing with a
  166. // diagnostic), or may return immediately.
  167. void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK();
  168. // ---------------------------------------------------------------------------
  169. // Reader-Writer Locking
  170. // ---------------------------------------------------------------------------
  171. // A Mutex can also be used as a starvation-free reader-writer lock.
  172. // Neither read-locks nor write-locks are reentrant/recursive to avoid
  173. // potential client programming errors.
  174. //
  175. // The Mutex API provides `Writer*()` aliases for the existing `Lock()`,
  176. // `Unlock()` and `TryLock()` methods for use within applications mixing
  177. // reader/writer locks. Using `Reader*()` and `Writer*()` operations in this
  178. // manner can make locking behavior clearer when mixing read and write modes.
  179. //
  180. // Introducing reader locks necessarily complicates the `Mutex` state
  181. // machine somewhat. The table below illustrates the allowed state transitions
  182. // of a mutex in such cases. Note that ReaderLock() may block even if the lock
  183. // is held in shared mode; this occurs when another thread is blocked on a
  184. // call to WriterLock().
  185. //
  186. // ---------------------------------------------------------------------------
  187. // Operation: WriterLock() Unlock() ReaderLock() ReaderUnlock()
  188. // ---------------------------------------------------------------------------
  189. // State
  190. // ---------------------------------------------------------------------------
  191. // Free Exclusive invalid Shared(1) invalid
  192. // Shared(1) blocks invalid Shared(2) or blocks Free
  193. // Shared(n) n>1 blocks invalid Shared(n+1) or blocks Shared(n-1)
  194. // Exclusive blocks Free blocks invalid
  195. // ---------------------------------------------------------------------------
  196. //
  197. // In comments below, "shared" refers to a state of Shared(n) for any n > 0.
  198. // Mutex::ReaderLock()
  199. //
  200. // Blocks the calling thread, if necessary, until this `Mutex` is either free,
  201. // or in shared mode, and then acquires a share of it. Note that
  202. // `ReaderLock()` will block if some other thread has an exclusive/writer lock
  203. // on the mutex.
  204. void ReaderLock() ABSL_SHARED_LOCK_FUNCTION();
  205. // Mutex::ReaderUnlock()
  206. //
  207. // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to
  208. // the free state if this thread holds the last reader lock on the mutex. Note
  209. // that you cannot call `ReaderUnlock()` on a mutex held in write mode.
  210. void ReaderUnlock() ABSL_UNLOCK_FUNCTION();
  211. // Mutex::ReaderTryLock()
  212. //
  213. // If the mutex can be acquired without blocking, acquires this mutex for
  214. // shared access and returns `true`. Otherwise, returns `false`. Returns
  215. // `true` with high probability if the `Mutex` was free or shared.
  216. bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true);
  217. // Mutex::AssertReaderHeld()
  218. //
  219. // Returns immediately if this thread holds the `Mutex` in at least shared
  220. // mode (read mode). Otherwise, may report an error (typically by
  221. // crashing with a diagnostic), or may return immediately.
  222. void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();
  223. // Mutex::WriterLock()
  224. // Mutex::WriterUnlock()
  225. // Mutex::WriterTryLock()
  226. //
  227. // Aliases for `Mutex::Lock()`, `Mutex::Unlock()`, and `Mutex::TryLock()`.
  228. //
  229. // These methods may be used (along with the complementary `Reader*()`
  230. // methods) to distingish simple exclusive `Mutex` usage (`Lock()`,
  231. // etc.) from reader/writer lock usage.
  232. void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); }
  233. void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); }
  234. bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) {
  235. return this->TryLock();
  236. }
  237. // ---------------------------------------------------------------------------
  238. // Conditional Critical Regions
  239. // ---------------------------------------------------------------------------
  240. // Conditional usage of a `Mutex` can occur using two distinct paradigms:
  241. //
  242. // * Use of `Mutex` member functions with `Condition` objects.
  243. // * Use of the separate `CondVar` abstraction.
  244. //
  245. // In general, prefer use of `Condition` and the `Mutex` member functions
  246. // listed below over `CondVar`. When there are multiple threads waiting on
  247. // distinctly different conditions, however, a battery of `CondVar`s may be
  248. // more efficient. This section discusses use of `Condition` objects.
  249. //
  250. // `Mutex` contains member functions for performing lock operations only under
  251. // certain conditions, of class `Condition`. For correctness, the `Condition`
  252. // must return a boolean that is a pure function, only of state protected by
  253. // the `Mutex`. The condition must be invariant w.r.t. environmental state
  254. // such as thread, cpu id, or time, and must be `noexcept`. The condition will
  255. // always be invoked with the mutex held in at least read mode, so you should
  256. // not block it for long periods or sleep it on a timer.
  257. //
  258. // Since a condition must not depend directly on the current time, use
  259. // `*WithTimeout()` member function variants to make your condition
  260. // effectively true after a given duration, or `*WithDeadline()` variants to
  261. // make your condition effectively true after a given time.
  262. //
  263. // The condition function should have no side-effects aside from debug
  264. // logging; as a special exception, the function may acquire other mutexes
  265. // provided it releases all those that it acquires. (This exception was
  266. // required to allow logging.)
  267. // Mutex::Await()
  268. //
  269. // Unlocks this `Mutex` and blocks until simultaneously both `cond` is `true`
  270. // and this `Mutex` can be reacquired, then reacquires this `Mutex` in the
  271. // same mode in which it was previously held. If the condition is initially
  272. // `true`, `Await()` *may* skip the release/re-acquire step.
  273. //
  274. // `Await()` requires that this thread holds this `Mutex` in some mode.
  275. void Await(const Condition &cond);
  276. // Mutex::LockWhen()
  277. // Mutex::ReaderLockWhen()
  278. // Mutex::WriterLockWhen()
  279. //
  280. // Blocks until simultaneously both `cond` is `true` and this `Mutex` can
  281. // be acquired, then atomically acquires this `Mutex`. `LockWhen()` is
  282. // logically equivalent to `*Lock(); Await();` though they may have different
  283. // performance characteristics.
  284. void LockWhen(const Condition &cond) ABSL_EXCLUSIVE_LOCK_FUNCTION();
  285. void ReaderLockWhen(const Condition &cond) ABSL_SHARED_LOCK_FUNCTION();
  286. void WriterLockWhen(const Condition &cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() {
  287. this->LockWhen(cond);
  288. }
  289. // ---------------------------------------------------------------------------
  290. // Mutex Variants with Timeouts/Deadlines
  291. // ---------------------------------------------------------------------------
  292. // Mutex::AwaitWithTimeout()
  293. // Mutex::AwaitWithDeadline()
  294. //
  295. // Unlocks this `Mutex` and blocks until simultaneously:
  296. // - either `cond` is true or the {timeout has expired, deadline has passed}
  297. // and
  298. // - this `Mutex` can be reacquired,
  299. // then reacquire this `Mutex` in the same mode in which it was previously
  300. // held, returning `true` iff `cond` is `true` on return.
  301. //
  302. // If the condition is initially `true`, the implementation *may* skip the
  303. // release/re-acquire step and return immediately.
  304. //
  305. // Deadlines in the past are equivalent to an immediate deadline.
  306. // Negative timeouts are equivalent to a zero timeout.
  307. //
  308. // This method requires that this thread holds this `Mutex` in some mode.
  309. bool AwaitWithTimeout(const Condition &cond, absl::Duration timeout);
  310. bool AwaitWithDeadline(const Condition &cond, absl::Time deadline);
  311. // Mutex::LockWhenWithTimeout()
  312. // Mutex::ReaderLockWhenWithTimeout()
  313. // Mutex::WriterLockWhenWithTimeout()
  314. //
  315. // Blocks until simultaneously both:
  316. // - either `cond` is `true` or the timeout has expired, and
  317. // - this `Mutex` can be acquired,
  318. // then atomically acquires this `Mutex`, returning `true` iff `cond` is
  319. // `true` on return.
  320. //
  321. // Negative timeouts are equivalent to a zero timeout.
  322. bool LockWhenWithTimeout(const Condition &cond, absl::Duration timeout)
  323. ABSL_EXCLUSIVE_LOCK_FUNCTION();
  324. bool ReaderLockWhenWithTimeout(const Condition &cond, absl::Duration timeout)
  325. ABSL_SHARED_LOCK_FUNCTION();
  326. bool WriterLockWhenWithTimeout(const Condition &cond, absl::Duration timeout)
  327. ABSL_EXCLUSIVE_LOCK_FUNCTION() {
  328. return this->LockWhenWithTimeout(cond, timeout);
  329. }
  330. // Mutex::LockWhenWithDeadline()
  331. // Mutex::ReaderLockWhenWithDeadline()
  332. // Mutex::WriterLockWhenWithDeadline()
  333. //
  334. // Blocks until simultaneously both:
  335. // - either `cond` is `true` or the deadline has been passed, and
  336. // - this `Mutex` can be acquired,
  337. // then atomically acquires this Mutex, returning `true` iff `cond` is `true`
  338. // on return.
  339. //
  340. // Deadlines in the past are equivalent to an immediate deadline.
  341. bool LockWhenWithDeadline(const Condition &cond, absl::Time deadline)
  342. ABSL_EXCLUSIVE_LOCK_FUNCTION();
  343. bool ReaderLockWhenWithDeadline(const Condition &cond, absl::Time deadline)
  344. ABSL_SHARED_LOCK_FUNCTION();
  345. bool WriterLockWhenWithDeadline(const Condition &cond, absl::Time deadline)
  346. ABSL_EXCLUSIVE_LOCK_FUNCTION() {
  347. return this->LockWhenWithDeadline(cond, deadline);
  348. }
  349. // ---------------------------------------------------------------------------
  350. // Debug Support: Invariant Checking, Deadlock Detection, Logging.
  351. // ---------------------------------------------------------------------------
  352. // Mutex::EnableInvariantDebugging()
  353. //
  354. // If `invariant`!=null and if invariant debugging has been enabled globally,
  355. // cause `(*invariant)(arg)` to be called at moments when the invariant for
  356. // this `Mutex` should hold (for example: just after acquire, just before
  357. // release).
  358. //
  359. // The routine `invariant` should have no side-effects since it is not
  360. // guaranteed how many times it will be called; it should check the invariant
  361. // and crash if it does not hold. Enabling global invariant debugging may
  362. // substantially reduce `Mutex` performance; it should be set only for
  363. // non-production runs. Optimization options may also disable invariant
  364. // checks.
  365. void EnableInvariantDebugging(void (*invariant)(void *), void *arg);
  366. // Mutex::EnableDebugLog()
  367. //
  368. // Cause all subsequent uses of this `Mutex` to be logged via
  369. // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if no previous
  370. // call to `EnableInvariantDebugging()` or `EnableDebugLog()` has been made.
  371. //
  372. // Note: This method substantially reduces `Mutex` performance.
  373. void EnableDebugLog(const char *name);
  374. // Deadlock detection
  375. // Mutex::ForgetDeadlockInfo()
  376. //
  377. // Forget any deadlock-detection information previously gathered
  378. // about this `Mutex`. Call this method in debug mode when the lock ordering
  379. // of a `Mutex` changes.
  380. void ForgetDeadlockInfo();
  381. // Mutex::AssertNotHeld()
  382. //
  383. // Return immediately if this thread does not hold this `Mutex` in any
  384. // mode; otherwise, may report an error (typically by crashing with a
  385. // diagnostic), or may return immediately.
  386. //
  387. // Currently this check is performed only if all of:
  388. // - in debug mode
  389. // - SetMutexDeadlockDetectionMode() has been set to kReport or kAbort
  390. // - number of locks concurrently held by this thread is not large.
  391. // are true.
  392. void AssertNotHeld() const;
  393. // Special cases.
  394. // A `MuHow` is a constant that indicates how a lock should be acquired.
  395. // Internal implementation detail. Clients should ignore.
  396. typedef const struct MuHowS *MuHow;
  397. // Mutex::InternalAttemptToUseMutexInFatalSignalHandler()
  398. //
  399. // Causes the `Mutex` implementation to prepare itself for re-entry caused by
  400. // future use of `Mutex` within a fatal signal handler. This method is
  401. // intended for use only for last-ditch attempts to log crash information.
  402. // It does not guarantee that attempts to use Mutexes within the handler will
  403. // not deadlock; it merely makes other faults less likely.
  404. //
  405. // WARNING: This routine must be invoked from a signal handler, and the
  406. // signal handler must either loop forever or terminate the process.
  407. // Attempts to return from (or `longjmp` out of) the signal handler once this
  408. // call has been made may cause arbitrary program behaviour including
  409. // crashes and deadlocks.
  410. static void InternalAttemptToUseMutexInFatalSignalHandler();
  411. private:
  412. std::atomic<intptr_t> mu_; // The Mutex state.
  413. // Post()/Wait() versus associated PerThreadSem; in class for required
  414. // friendship with PerThreadSem.
  415. static void IncrementSynchSem(Mutex *mu, base_internal::PerThreadSynch *w);
  416. static bool DecrementSynchSem(Mutex *mu, base_internal::PerThreadSynch *w,
  417. synchronization_internal::KernelTimeout t);
  418. // slow path acquire
  419. void LockSlowLoop(SynchWaitParams *waitp, int flags);
  420. // wrappers around LockSlowLoop()
  421. bool LockSlowWithDeadline(MuHow how, const Condition *cond,
  422. synchronization_internal::KernelTimeout t,
  423. int flags);
  424. void LockSlow(MuHow how, const Condition *cond,
  425. int flags) ABSL_ATTRIBUTE_COLD;
  426. // slow path release
  427. void UnlockSlow(SynchWaitParams *waitp) ABSL_ATTRIBUTE_COLD;
  428. // Common code between Await() and AwaitWithTimeout/Deadline()
  429. bool AwaitCommon(const Condition &cond,
  430. synchronization_internal::KernelTimeout t);
  431. // Attempt to remove thread s from queue.
  432. void TryRemove(base_internal::PerThreadSynch *s);
  433. // Block a thread on mutex.
  434. void Block(base_internal::PerThreadSynch *s);
  435. // Wake a thread; return successor.
  436. base_internal::PerThreadSynch *Wakeup(base_internal::PerThreadSynch *w);
  437. friend class CondVar; // for access to Trans()/Fer().
  438. void Trans(MuHow how); // used for CondVar->Mutex transfer
  439. void Fer(
  440. base_internal::PerThreadSynch *w); // used for CondVar->Mutex transfer
  441. // Catch the error of writing Mutex when intending MutexLock.
  442. Mutex(const volatile Mutex * /*ignored*/) {} // NOLINT(runtime/explicit)
  443. Mutex(const Mutex&) = delete;
  444. Mutex& operator=(const Mutex&) = delete;
  445. };
  446. // -----------------------------------------------------------------------------
  447. // Mutex RAII Wrappers
  448. // -----------------------------------------------------------------------------
  449. // MutexLock
  450. //
  451. // `MutexLock` is a helper class, which acquires and releases a `Mutex` via
  452. // RAII.
  453. //
  454. // Example:
  455. //
  456. // Class Foo {
  457. // public:
  458. // Foo::Bar* Baz() {
  459. // MutexLock lock(&mu_);
  460. // ...
  461. // return bar;
  462. // }
  463. //
  464. // private:
  465. // Mutex mu_;
  466. // };
  467. class ABSL_SCOPED_LOCKABLE MutexLock {
  468. public:
  469. // Constructors
  470. // Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is
  471. // guaranteed to be locked when this object is constructed. Requires that
  472. // `mu` be dereferenceable.
  473. explicit MutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) : mu_(mu) {
  474. this->mu_->Lock();
  475. }
  476. // Like above, but calls `mu->LockWhen(cond)` instead. That is, in addition to
  477. // the above, the condition given by `cond` is also guaranteed to hold when
  478. // this object is constructed.
  479. explicit MutexLock(Mutex *mu, const Condition &cond)
  480. ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  481. : mu_(mu) {
  482. this->mu_->LockWhen(cond);
  483. }
  484. MutexLock(const MutexLock &) = delete; // NOLINT(runtime/mutex)
  485. MutexLock(MutexLock&&) = delete; // NOLINT(runtime/mutex)
  486. MutexLock& operator=(const MutexLock&) = delete;
  487. MutexLock& operator=(MutexLock&&) = delete;
  488. ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); }
  489. private:
  490. Mutex *const mu_;
  491. };
  492. // ReaderMutexLock
  493. //
  494. // The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and
  495. // releases a shared lock on a `Mutex` via RAII.
  496. class ABSL_SCOPED_LOCKABLE ReaderMutexLock {
  497. public:
  498. explicit ReaderMutexLock(Mutex *mu) ABSL_SHARED_LOCK_FUNCTION(mu) : mu_(mu) {
  499. mu->ReaderLock();
  500. }
  501. explicit ReaderMutexLock(Mutex *mu, const Condition &cond)
  502. ABSL_SHARED_LOCK_FUNCTION(mu)
  503. : mu_(mu) {
  504. mu->ReaderLockWhen(cond);
  505. }
  506. ReaderMutexLock(const ReaderMutexLock&) = delete;
  507. ReaderMutexLock(ReaderMutexLock&&) = delete;
  508. ReaderMutexLock& operator=(const ReaderMutexLock&) = delete;
  509. ReaderMutexLock& operator=(ReaderMutexLock&&) = delete;
  510. ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); }
  511. private:
  512. Mutex *const mu_;
  513. };
  514. // WriterMutexLock
  515. //
  516. // The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and
  517. // releases a write (exclusive) lock on a `Mutex` via RAII.
  518. class ABSL_SCOPED_LOCKABLE WriterMutexLock {
  519. public:
  520. explicit WriterMutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  521. : mu_(mu) {
  522. mu->WriterLock();
  523. }
  524. explicit WriterMutexLock(Mutex *mu, const Condition &cond)
  525. ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  526. : mu_(mu) {
  527. mu->WriterLockWhen(cond);
  528. }
  529. WriterMutexLock(const WriterMutexLock&) = delete;
  530. WriterMutexLock(WriterMutexLock&&) = delete;
  531. WriterMutexLock& operator=(const WriterMutexLock&) = delete;
  532. WriterMutexLock& operator=(WriterMutexLock&&) = delete;
  533. ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->WriterUnlock(); }
  534. private:
  535. Mutex *const mu_;
  536. };
  537. // -----------------------------------------------------------------------------
  538. // Condition
  539. // -----------------------------------------------------------------------------
  540. //
  541. // As noted above, `Mutex` contains a number of member functions which take a
  542. // `Condition` as an argument; clients can wait for conditions to become `true`
  543. // before attempting to acquire the mutex. These sections are known as
  544. // "condition critical" sections. To use a `Condition`, you simply need to
  545. // construct it, and use within an appropriate `Mutex` member function;
  546. // everything else in the `Condition` class is an implementation detail.
  547. //
  548. // A `Condition` is specified as a function pointer which returns a boolean.
  549. // `Condition` functions should be pure functions -- their results should depend
  550. // only on passed arguments, should not consult any external state (such as
  551. // clocks), and should have no side-effects, aside from debug logging. Any
  552. // objects that the function may access should be limited to those which are
  553. // constant while the mutex is blocked on the condition (e.g. a stack variable),
  554. // or objects of state protected explicitly by the mutex.
  555. //
  556. // No matter which construction is used for `Condition`, the underlying
  557. // function pointer / functor / callable must not throw any
  558. // exceptions. Correctness of `Mutex` / `Condition` is not guaranteed in
  559. // the face of a throwing `Condition`. (When Abseil is allowed to depend
  560. // on C++17, these function pointers will be explicitly marked
  561. // `noexcept`; until then this requirement cannot be enforced in the
  562. // type system.)
  563. //
  564. // Note: to use a `Condition`, you need only construct it and pass it to a
  565. // suitable `Mutex' member function, such as `Mutex::Await()`, or to the
  566. // constructor of one of the scope guard classes.
  567. //
  568. // Example using LockWhen/Unlock:
  569. //
  570. // // assume count_ is not internal reference count
  571. // int count_ ABSL_GUARDED_BY(mu_);
  572. // Condition count_is_zero(+[](int *count) { return *count == 0; }, &count_);
  573. //
  574. // mu_.LockWhen(count_is_zero);
  575. // // ...
  576. // mu_.Unlock();
  577. //
  578. // Example using a scope guard:
  579. //
  580. // {
  581. // MutexLock lock(&mu_, count_is_zero);
  582. // // ...
  583. // }
  584. //
  585. // When multiple threads are waiting on exactly the same condition, make sure
  586. // that they are constructed with the same parameters (same pointer to function
  587. // + arg, or same pointer to object + method), so that the mutex implementation
  588. // can avoid redundantly evaluating the same condition for each thread.
  589. class Condition {
  590. public:
  591. // A Condition that returns the result of "(*func)(arg)"
  592. Condition(bool (*func)(void *), void *arg);
  593. // Templated version for people who are averse to casts.
  594. //
  595. // To use a lambda, prepend it with unary plus, which converts the lambda
  596. // into a function pointer:
  597. // Condition(+[](T* t) { return ...; }, arg).
  598. //
  599. // Note: lambdas in this case must contain no bound variables.
  600. //
  601. // See class comment for performance advice.
  602. template<typename T>
  603. Condition(bool (*func)(T *), T *arg);
  604. // Templated version for invoking a method that returns a `bool`.
  605. //
  606. // `Condition(object, &Class::Method)` constructs a `Condition` that evaluates
  607. // `object->Method()`.
  608. //
  609. // Implementation Note: `absl::internal::identity` is used to allow methods to
  610. // come from base classes. A simpler signature like
  611. // `Condition(T*, bool (T::*)())` does not suffice.
  612. template<typename T>
  613. Condition(T *object, bool (absl::internal::identity<T>::type::* method)());
  614. // Same as above, for const members
  615. template<typename T>
  616. Condition(const T *object,
  617. bool (absl::internal::identity<T>::type::* method)() const);
  618. // A Condition that returns the value of `*cond`
  619. explicit Condition(const bool *cond);
  620. // Templated version for invoking a functor that returns a `bool`.
  621. // This approach accepts pointers to non-mutable lambdas, `std::function`,
  622. // the result of` std::bind` and user-defined functors that define
  623. // `bool F::operator()() const`.
  624. //
  625. // Example:
  626. //
  627. // auto reached = [this, current]() {
  628. // mu_.AssertReaderHeld(); // For annotalysis.
  629. // return processed_ >= current;
  630. // };
  631. // mu_.Await(Condition(&reached));
  632. //
  633. // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in
  634. // the lambda as it may be called when the mutex is being unlocked from a
  635. // scope holding only a reader lock, which will make the assertion not
  636. // fulfilled and crash the binary.
  637. // See class comment for performance advice. In particular, if there
  638. // might be more than one waiter for the same condition, make sure
  639. // that all waiters construct the condition with the same pointers.
  640. // Implementation note: The second template parameter ensures that this
  641. // constructor doesn't participate in overload resolution if T doesn't have
  642. // `bool operator() const`.
  643. template <typename T, typename E = decltype(
  644. static_cast<bool (T::*)() const>(&T::operator()))>
  645. explicit Condition(const T *obj)
  646. : Condition(obj, static_cast<bool (T::*)() const>(&T::operator())) {}
  647. // A Condition that always returns `true`.
  648. static const Condition kTrue;
  649. // Evaluates the condition.
  650. bool Eval() const;
  651. // Returns `true` if the two conditions are guaranteed to return the same
  652. // value if evaluated at the same time, `false` if the evaluation *may* return
  653. // different results.
  654. //
  655. // Two `Condition` values are guaranteed equal if both their `func` and `arg`
  656. // components are the same. A null pointer is equivalent to a `true`
  657. // condition.
  658. static bool GuaranteedEqual(const Condition *a, const Condition *b);
  659. private:
  660. typedef bool (*InternalFunctionType)(void * arg);
  661. typedef bool (Condition::*InternalMethodType)();
  662. typedef bool (*InternalMethodCallerType)(void * arg,
  663. InternalMethodType internal_method);
  664. bool (*eval_)(const Condition*); // Actual evaluator
  665. InternalFunctionType function_; // function taking pointer returning bool
  666. InternalMethodType method_; // method returning bool
  667. void *arg_; // arg of function_ or object of method_
  668. Condition(); // null constructor used only to create kTrue
  669. // Various functions eval_ can point to:
  670. static bool CallVoidPtrFunction(const Condition*);
  671. template <typename T> static bool CastAndCallFunction(const Condition* c);
  672. template <typename T> static bool CastAndCallMethod(const Condition* c);
  673. };
  674. // -----------------------------------------------------------------------------
  675. // CondVar
  676. // -----------------------------------------------------------------------------
  677. //
  678. // A condition variable, reflecting state evaluated separately outside of the
  679. // `Mutex` object, which can be signaled to wake callers.
  680. // This class is not normally needed; use `Mutex` member functions such as
  681. // `Mutex::Await()` and intrinsic `Condition` abstractions. In rare cases
  682. // with many threads and many conditions, `CondVar` may be faster.
  683. //
  684. // The implementation may deliver signals to any condition variable at
  685. // any time, even when no call to `Signal()` or `SignalAll()` is made; as a
  686. // result, upon being awoken, you must check the logical condition you have
  687. // been waiting upon.
  688. //
  689. // Examples:
  690. //
  691. // Usage for a thread waiting for some condition C protected by mutex mu:
  692. // mu.Lock();
  693. // while (!C) { cv->Wait(&mu); } // releases and reacquires mu
  694. // // C holds; process data
  695. // mu.Unlock();
  696. //
  697. // Usage to wake T is:
  698. // mu.Lock();
  699. // // process data, possibly establishing C
  700. // if (C) { cv->Signal(); }
  701. // mu.Unlock();
  702. //
  703. // If C may be useful to more than one waiter, use `SignalAll()` instead of
  704. // `Signal()`.
  705. //
  706. // With this implementation it is efficient to use `Signal()/SignalAll()` inside
  707. // the locked region; this usage can make reasoning about your program easier.
  708. //
  709. class CondVar {
  710. public:
  711. // A `CondVar` allocated on the heap or on the stack can use the this
  712. // constructor.
  713. CondVar();
  714. ~CondVar();
  715. // CondVar::Wait()
  716. //
  717. // Atomically releases a `Mutex` and blocks on this condition variable.
  718. // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  719. // spurious wakeup), then reacquires the `Mutex` and returns.
  720. //
  721. // Requires and ensures that the current thread holds the `Mutex`.
  722. void Wait(Mutex *mu);
  723. // CondVar::WaitWithTimeout()
  724. //
  725. // Atomically releases a `Mutex` and blocks on this condition variable.
  726. // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  727. // spurious wakeup), or until the timeout has expired, then reacquires
  728. // the `Mutex` and returns.
  729. //
  730. // Returns true if the timeout has expired without this `CondVar`
  731. // being signalled in any manner. If both the timeout has expired
  732. // and this `CondVar` has been signalled, the implementation is free
  733. // to return `true` or `false`.
  734. //
  735. // Requires and ensures that the current thread holds the `Mutex`.
  736. bool WaitWithTimeout(Mutex *mu, absl::Duration timeout);
  737. // CondVar::WaitWithDeadline()
  738. //
  739. // Atomically releases a `Mutex` and blocks on this condition variable.
  740. // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a
  741. // spurious wakeup), or until the deadline has passed, then reacquires
  742. // the `Mutex` and returns.
  743. //
  744. // Deadlines in the past are equivalent to an immediate deadline.
  745. //
  746. // Returns true if the deadline has passed without this `CondVar`
  747. // being signalled in any manner. If both the deadline has passed
  748. // and this `CondVar` has been signalled, the implementation is free
  749. // to return `true` or `false`.
  750. //
  751. // Requires and ensures that the current thread holds the `Mutex`.
  752. bool WaitWithDeadline(Mutex *mu, absl::Time deadline);
  753. // CondVar::Signal()
  754. //
  755. // Signal this `CondVar`; wake at least one waiter if one exists.
  756. void Signal();
  757. // CondVar::SignalAll()
  758. //
  759. // Signal this `CondVar`; wake all waiters.
  760. void SignalAll();
  761. // CondVar::EnableDebugLog()
  762. //
  763. // Causes all subsequent uses of this `CondVar` to be logged via
  764. // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if `name != 0`.
  765. // Note: this method substantially reduces `CondVar` performance.
  766. void EnableDebugLog(const char *name);
  767. private:
  768. bool WaitCommon(Mutex *mutex, synchronization_internal::KernelTimeout t);
  769. void Remove(base_internal::PerThreadSynch *s);
  770. void Wakeup(base_internal::PerThreadSynch *w);
  771. std::atomic<intptr_t> cv_; // Condition variable state.
  772. CondVar(const CondVar&) = delete;
  773. CondVar& operator=(const CondVar&) = delete;
  774. };
  775. // Variants of MutexLock.
  776. //
  777. // If you find yourself using one of these, consider instead using
  778. // Mutex::Unlock() and/or if-statements for clarity.
  779. // MutexLockMaybe
  780. //
  781. // MutexLockMaybe is like MutexLock, but is a no-op when mu is null.
  782. class ABSL_SCOPED_LOCKABLE MutexLockMaybe {
  783. public:
  784. explicit MutexLockMaybe(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  785. : mu_(mu) {
  786. if (this->mu_ != nullptr) {
  787. this->mu_->Lock();
  788. }
  789. }
  790. explicit MutexLockMaybe(Mutex *mu, const Condition &cond)
  791. ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  792. : mu_(mu) {
  793. if (this->mu_ != nullptr) {
  794. this->mu_->LockWhen(cond);
  795. }
  796. }
  797. ~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() {
  798. if (this->mu_ != nullptr) { this->mu_->Unlock(); }
  799. }
  800. private:
  801. Mutex *const mu_;
  802. MutexLockMaybe(const MutexLockMaybe&) = delete;
  803. MutexLockMaybe(MutexLockMaybe&&) = delete;
  804. MutexLockMaybe& operator=(const MutexLockMaybe&) = delete;
  805. MutexLockMaybe& operator=(MutexLockMaybe&&) = delete;
  806. };
  807. // ReleasableMutexLock
  808. //
  809. // ReleasableMutexLock is like MutexLock, but permits `Release()` of its
  810. // mutex before destruction. `Release()` may be called at most once.
  811. class ABSL_SCOPED_LOCKABLE ReleasableMutexLock {
  812. public:
  813. explicit ReleasableMutexLock(Mutex *mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  814. : mu_(mu) {
  815. this->mu_->Lock();
  816. }
  817. explicit ReleasableMutexLock(Mutex *mu, const Condition &cond)
  818. ABSL_EXCLUSIVE_LOCK_FUNCTION(mu)
  819. : mu_(mu) {
  820. this->mu_->LockWhen(cond);
  821. }
  822. ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() {
  823. if (this->mu_ != nullptr) { this->mu_->Unlock(); }
  824. }
  825. void Release() ABSL_UNLOCK_FUNCTION();
  826. private:
  827. Mutex *mu_;
  828. ReleasableMutexLock(const ReleasableMutexLock&) = delete;
  829. ReleasableMutexLock(ReleasableMutexLock&&) = delete;
  830. ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete;
  831. ReleasableMutexLock& operator=(ReleasableMutexLock&&) = delete;
  832. };
  833. inline Mutex::Mutex() : mu_(0) {
  834. ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
  835. }
  836. inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
  837. inline CondVar::CondVar() : cv_(0) {}
  838. // static
  839. template <typename T>
  840. bool Condition::CastAndCallMethod(const Condition *c) {
  841. typedef bool (T::*MemberType)();
  842. MemberType rm = reinterpret_cast<MemberType>(c->method_);
  843. T *x = static_cast<T *>(c->arg_);
  844. return (x->*rm)();
  845. }
  846. // static
  847. template <typename T>
  848. bool Condition::CastAndCallFunction(const Condition *c) {
  849. typedef bool (*FuncType)(T *);
  850. FuncType fn = reinterpret_cast<FuncType>(c->function_);
  851. T *x = static_cast<T *>(c->arg_);
  852. return (*fn)(x);
  853. }
  854. template <typename T>
  855. inline Condition::Condition(bool (*func)(T *), T *arg)
  856. : eval_(&CastAndCallFunction<T>),
  857. function_(reinterpret_cast<InternalFunctionType>(func)),
  858. method_(nullptr),
  859. arg_(const_cast<void *>(static_cast<const void *>(arg))) {}
  860. template <typename T>
  861. inline Condition::Condition(T *object,
  862. bool (absl::internal::identity<T>::type::*method)())
  863. : eval_(&CastAndCallMethod<T>),
  864. function_(nullptr),
  865. method_(reinterpret_cast<InternalMethodType>(method)),
  866. arg_(object) {}
  867. template <typename T>
  868. inline Condition::Condition(const T *object,
  869. bool (absl::internal::identity<T>::type::*method)()
  870. const)
  871. : eval_(&CastAndCallMethod<T>),
  872. function_(nullptr),
  873. method_(reinterpret_cast<InternalMethodType>(method)),
  874. arg_(reinterpret_cast<void *>(const_cast<T *>(object))) {}
  875. // Register a hook for profiling support.
  876. //
  877. // The function pointer registered here will be called whenever a mutex is
  878. // contended. The callback is given the absl/base/cycleclock.h timestamp when
  879. // waiting began.
  880. //
  881. // Calls to this function do not race or block, but there is no ordering
  882. // guaranteed between calls to this function and call to the provided hook.
  883. // In particular, the previously registered hook may still be called for some
  884. // time after this function returns.
  885. void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp));
  886. // Register a hook for Mutex tracing.
  887. //
  888. // The function pointer registered here will be called whenever a mutex is
  889. // contended. The callback is given an opaque handle to the contended mutex,
  890. // an event name, and the number of wait cycles (as measured by
  891. // //absl/base/internal/cycleclock.h, and which may not be real
  892. // "cycle" counts.)
  893. //
  894. // The only event name currently sent is "slow release".
  895. //
  896. // This has the same memory ordering concerns as RegisterMutexProfiler() above.
  897. void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj,
  898. int64_t wait_cycles));
  899. // TODO(gfalcon): Combine RegisterMutexProfiler() and RegisterMutexTracer()
  900. // into a single interface, since they are only ever called in pairs.
  901. // Register a hook for CondVar tracing.
  902. //
  903. // The function pointer registered here will be called here on various CondVar
  904. // events. The callback is given an opaque handle to the CondVar object and
  905. // a string identifying the event. This is thread-safe, but only a single
  906. // tracer can be registered.
  907. //
  908. // Events that can be sent are "Wait", "Unwait", "Signal wakeup", and
  909. // "SignalAll wakeup".
  910. //
  911. // This has the same memory ordering concerns as RegisterMutexProfiler() above.
  912. void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv));
  913. // Register a hook for symbolizing stack traces in deadlock detector reports.
  914. //
  915. // 'pc' is the program counter being symbolized, 'out' is the buffer to write
  916. // into, and 'out_size' is the size of the buffer. This function can return
  917. // false if symbolizing failed, or true if a NUL-terminated symbol was written
  918. // to 'out.'
  919. //
  920. // This has the same memory ordering concerns as RegisterMutexProfiler() above.
  921. //
  922. // DEPRECATED: The default symbolizer function is absl::Symbolize() and the
  923. // ability to register a different hook for symbolizing stack traces will be
  924. // removed on or after 2023-05-01.
  925. ABSL_DEPRECATED("absl::RegisterSymbolizer() is deprecated and will be removed "
  926. "on or after 2023-05-01")
  927. void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size));
  928. // EnableMutexInvariantDebugging()
  929. //
  930. // Enable or disable global support for Mutex invariant debugging. If enabled,
  931. // then invariant predicates can be registered per-Mutex for debug checking.
  932. // See Mutex::EnableInvariantDebugging().
  933. void EnableMutexInvariantDebugging(bool enabled);
  934. // When in debug mode, and when the feature has been enabled globally, the
  935. // implementation will keep track of lock ordering and complain (or optionally
  936. // crash) if a cycle is detected in the acquired-before graph.
  937. // Possible modes of operation for the deadlock detector in debug mode.
  938. enum class OnDeadlockCycle {
  939. kIgnore, // Neither report on nor attempt to track cycles in lock ordering
  940. kReport, // Report lock cycles to stderr when detected
  941. kAbort, // Report lock cycles to stderr when detected, then abort
  942. };
  943. // SetMutexDeadlockDetectionMode()
  944. //
  945. // Enable or disable global support for detection of potential deadlocks
  946. // due to Mutex lock ordering inversions. When set to 'kIgnore', tracking of
  947. // lock ordering is disabled. Otherwise, in debug builds, a lock ordering graph
  948. // will be maintained internally, and detected cycles will be reported in
  949. // the manner chosen here.
  950. void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode);
  951. ABSL_NAMESPACE_END
  952. } // namespace absl
  953. // In some build configurations we pass --detect-odr-violations to the
  954. // gold linker. This causes it to flag weak symbol overrides as ODR
  955. // violations. Because ODR only applies to C++ and not C,
  956. // --detect-odr-violations ignores symbols not mangled with C++ names.
  957. // By changing our extension points to be extern "C", we dodge this
  958. // check.
  959. extern "C" {
  960. void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)();
  961. } // extern "C"
  962. #endif // ABSL_SYNCHRONIZATION_MUTEX_H_