mutex.h (50774B)
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 58 #ifndef ABSL_SYNCHRONIZATION_MUTEX_H_ 59 #define ABSL_SYNCHRONIZATION_MUTEX_H_ 60 61 #include <atomic> 62 #include <cstdint> 63 #include <cstring> 64 #include <iterator> 65 #include <string> 66 67 #include "absl/base/attributes.h" 68 #include "absl/base/const_init.h" 69 #include "absl/base/internal/identity.h" 70 #include "absl/base/internal/low_level_alloc.h" 71 #include "absl/base/internal/thread_identity.h" 72 #include "absl/base/internal/tsan_mutex_interface.h" 73 #include "absl/base/nullability.h" 74 #include "absl/base/port.h" 75 #include "absl/base/thread_annotations.h" 76 #include "absl/synchronization/internal/kernel_timeout.h" 77 #include "absl/synchronization/internal/per_thread_sem.h" 78 #include "absl/time/time.h" 79 80 namespace absl { 81 ABSL_NAMESPACE_BEGIN 82 83 class Condition; 84 struct SynchWaitParams; 85 86 // ----------------------------------------------------------------------------- 87 // Mutex 88 // ----------------------------------------------------------------------------- 89 // 90 // A `Mutex` is a non-reentrant (aka non-recursive) Mutually Exclusive lock 91 // on some resource, typically a variable or data structure with associated 92 // invariants. Proper usage of mutexes prevents concurrent access by different 93 // threads to the same resource. 94 // 95 // A `Mutex` has two basic operations: `Mutex::Lock()` and `Mutex::Unlock()`. 96 // The `Lock()` operation *acquires* a `Mutex` (in a state known as an 97 // *exclusive* -- or *write* -- lock), and the `Unlock()` operation *releases* a 98 // Mutex. During the span of time between the Lock() and Unlock() operations, 99 // a mutex is said to be *held*. By design, all mutexes support exclusive/write 100 // locks, as this is the most common way to use a mutex. 101 // 102 // Mutex operations are only allowed under certain conditions; otherwise an 103 // operation is "invalid", and disallowed by the API. The conditions concern 104 // both the current state of the mutex and the identity of the threads that 105 // are performing the operations. 106 // 107 // The `Mutex` state machine for basic lock/unlock operations is quite simple: 108 // 109 // | | Lock() | Unlock() | 110 // |----------------+------------------------+----------| 111 // | Free | Exclusive | invalid | 112 // | Exclusive | blocks, then exclusive | Free | 113 // 114 // The full conditions are as follows. 115 // 116 // * Calls to `Unlock()` require that the mutex be held, and must be made in the 117 // same thread that performed the corresponding `Lock()` operation which 118 // acquired the mutex; otherwise the call is invalid. 119 // 120 // * The mutex being non-reentrant (or non-recursive) means that a call to 121 // `Lock()` or `TryLock()` must not be made in a thread that already holds the 122 // mutex; such a call is invalid. 123 // 124 // * In other words, the state of being "held" has both a temporal component 125 // (from `Lock()` until `Unlock()`) as well as a thread identity component: 126 // the mutex is held *by a particular thread*. 127 // 128 // An "invalid" operation has undefined behavior. The `Mutex` implementation 129 // is allowed to do anything on an invalid call, including, but not limited to, 130 // crashing with a useful error message, silently succeeding, or corrupting 131 // data structures. In debug mode, the implementation may crash with a useful 132 // error message. 133 // 134 // `Mutex` is not guaranteed to be "fair" in prioritizing waiting threads; it 135 // is, however, approximately fair over long periods, and starvation-free for 136 // threads at the same priority. 137 // 138 // The lock/unlock primitives are now annotated with lock annotations 139 // defined in (base/thread_annotations.h). When writing multi-threaded code, 140 // you should use lock annotations whenever possible to document your lock 141 // synchronization policy. Besides acting as documentation, these annotations 142 // also help compilers or static analysis tools to identify and warn about 143 // issues that could potentially result in race conditions and deadlocks. 144 // 145 // For more information about the lock annotations, please see 146 // [Thread Safety 147 // Analysis](http://clang.llvm.org/docs/ThreadSafetyAnalysis.html) in the Clang 148 // documentation. 149 // 150 // See also `MutexLock`, below, for scoped `Mutex` acquisition. 151 152 class ABSL_LOCKABLE ABSL_ATTRIBUTE_WARN_UNUSED Mutex { 153 public: 154 // Creates a `Mutex` that is not held by anyone. This constructor is 155 // typically used for Mutexes allocated on the heap or the stack. 156 // 157 // To create `Mutex` instances with static storage duration 158 // (e.g. a namespace-scoped or global variable), see 159 // `Mutex::Mutex(absl::kConstInit)` below instead. 160 Mutex(); 161 162 // Creates a mutex with static storage duration. A global variable 163 // constructed this way avoids the lifetime issues that can occur on program 164 // startup and shutdown. (See absl/base/const_init.h.) 165 // 166 // For Mutexes allocated on the heap and stack, instead use the default 167 // constructor, which can interact more fully with the thread sanitizer. 168 // 169 // Example usage: 170 // namespace foo { 171 // ABSL_CONST_INIT absl::Mutex mu(absl::kConstInit); 172 // } 173 explicit constexpr Mutex(absl::ConstInitType); 174 175 ~Mutex(); 176 177 // Mutex::Lock() 178 // 179 // Blocks the calling thread, if necessary, until this `Mutex` is free, and 180 // then acquires it exclusively. (This lock is also known as a "write lock.") 181 void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION(); 182 183 // Mutex::Unlock() 184 // 185 // Releases this `Mutex` and returns it from the exclusive/write state to the 186 // free state. Calling thread must hold the `Mutex` exclusively. 187 void Unlock() ABSL_UNLOCK_FUNCTION(); 188 189 // Mutex::TryLock() 190 // 191 // If the mutex can be acquired without blocking, does so exclusively and 192 // returns `true`. Otherwise, returns `false`. Returns `true` with high 193 // probability if the `Mutex` was free. 194 [[nodiscard]] bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true); 195 196 // Mutex::AssertHeld() 197 // 198 // Require that the mutex be held exclusively (write mode) by this thread. 199 // 200 // If the mutex is not currently held by this thread, this function may report 201 // an error (typically by crashing with a diagnostic) or it may do nothing. 202 // This function is intended only as a tool to assist debugging; it doesn't 203 // guarantee correctness. 204 void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK(); 205 206 // --------------------------------------------------------------------------- 207 // Reader-Writer Locking 208 // --------------------------------------------------------------------------- 209 210 // A Mutex can also be used as a starvation-free reader-writer lock. 211 // Neither read-locks nor write-locks are reentrant/recursive to avoid 212 // potential client programming errors. 213 // 214 // The Mutex API provides `Writer*()` aliases for the existing `Lock()`, 215 // `Unlock()` and `TryLock()` methods for use within applications mixing 216 // reader/writer locks. Using `Reader*()` and `Writer*()` operations in this 217 // manner can make locking behavior clearer when mixing read and write modes. 218 // 219 // Introducing reader locks necessarily complicates the `Mutex` state 220 // machine somewhat. The table below illustrates the allowed state transitions 221 // of a mutex in such cases. Note that ReaderLock() may block even if the lock 222 // is held in shared mode; this occurs when another thread is blocked on a 223 // call to WriterLock(). 224 // 225 // --------------------------------------------------------------------------- 226 // Operation: WriterLock() Unlock() ReaderLock() ReaderUnlock() 227 // --------------------------------------------------------------------------- 228 // State 229 // --------------------------------------------------------------------------- 230 // Free Exclusive invalid Shared(1) invalid 231 // Shared(1) blocks invalid Shared(2) or blocks Free 232 // Shared(n) n>1 blocks invalid Shared(n+1) or blocks Shared(n-1) 233 // Exclusive blocks Free blocks invalid 234 // --------------------------------------------------------------------------- 235 // 236 // In comments below, "shared" refers to a state of Shared(n) for any n > 0. 237 238 // Mutex::ReaderLock() 239 // 240 // Blocks the calling thread, if necessary, until this `Mutex` is either free, 241 // or in shared mode, and then acquires a share of it. Note that 242 // `ReaderLock()` will block if some other thread has an exclusive/writer lock 243 // on the mutex. 244 245 void ReaderLock() ABSL_SHARED_LOCK_FUNCTION(); 246 247 // Mutex::ReaderUnlock() 248 // 249 // Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to 250 // the free state if this thread holds the last reader lock on the mutex. Note 251 // that you cannot call `ReaderUnlock()` on a mutex held in write mode. 252 void ReaderUnlock() ABSL_UNLOCK_FUNCTION(); 253 254 // Mutex::ReaderTryLock() 255 // 256 // If the mutex can be acquired without blocking, acquires this mutex for 257 // shared access and returns `true`. Otherwise, returns `false`. Returns 258 // `true` with high probability if the `Mutex` was free or shared. 259 [[nodiscard]] bool ReaderTryLock() ABSL_SHARED_TRYLOCK_FUNCTION(true); 260 261 // Mutex::AssertReaderHeld() 262 // 263 // Require that the mutex be held at least in shared mode (read mode) by this 264 // thread. 265 // 266 // If the mutex is not currently held by this thread, this function may report 267 // an error (typically by crashing with a diagnostic) or it may do nothing. 268 // This function is intended only as a tool to assist debugging; it doesn't 269 // guarantee correctness. 270 void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK(); 271 272 // Mutex::WriterLock() 273 // Mutex::WriterUnlock() 274 // Mutex::WriterTryLock() 275 // 276 // Aliases for `Mutex::Lock()`, `Mutex::Unlock()`, and `Mutex::TryLock()`. 277 // 278 // These methods may be used (along with the complementary `Reader*()` 279 // methods) to distinguish simple exclusive `Mutex` usage (`Lock()`, 280 // etc.) from reader/writer lock usage. 281 void WriterLock() ABSL_EXCLUSIVE_LOCK_FUNCTION() { this->Lock(); } 282 283 void WriterUnlock() ABSL_UNLOCK_FUNCTION() { this->Unlock(); } 284 285 [[nodiscard]] bool WriterTryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true) { 286 return this->TryLock(); 287 } 288 289 // --------------------------------------------------------------------------- 290 // Conditional Critical Regions 291 // --------------------------------------------------------------------------- 292 293 // Conditional usage of a `Mutex` can occur using two distinct paradigms: 294 // 295 // * Use of `Mutex` member functions with `Condition` objects. 296 // * Use of the separate `CondVar` abstraction. 297 // 298 // In general, prefer use of `Condition` and the `Mutex` member functions 299 // listed below over `CondVar`. When there are multiple threads waiting on 300 // distinctly different conditions, however, a battery of `CondVar`s may be 301 // more efficient. This section discusses use of `Condition` objects. 302 // 303 // `Mutex` contains member functions for performing lock operations only under 304 // certain conditions, of class `Condition`. For correctness, the `Condition` 305 // must return a boolean that is a pure function, only of state protected by 306 // the `Mutex`. The condition must be invariant w.r.t. environmental state 307 // such as thread, cpu id, or time, and must be `noexcept`. The condition will 308 // always be invoked with the mutex held in at least read mode, so you should 309 // not block it for long periods or sleep it on a timer. 310 // 311 // Since a condition must not depend directly on the current time, use 312 // `*WithTimeout()` member function variants to make your condition 313 // effectively true after a given duration, or `*WithDeadline()` variants to 314 // make your condition effectively true after a given time. 315 // 316 // The condition function should have no side-effects aside from debug 317 // logging; as a special exception, the function may acquire other mutexes 318 // provided it releases all those that it acquires. (This exception was 319 // required to allow logging.) 320 321 // Mutex::Await() 322 // 323 // Unlocks this `Mutex` and blocks until simultaneously both `cond` is `true` 324 // and this `Mutex` can be reacquired, then reacquires this `Mutex` in the 325 // same mode in which it was previously held. If the condition is initially 326 // `true`, `Await()` *may* skip the release/re-acquire step. 327 // 328 // `Await()` requires that this thread holds this `Mutex` in some mode. 329 void Await(const Condition& cond) { 330 AwaitCommon(cond, synchronization_internal::KernelTimeout::Never()); 331 } 332 333 // Mutex::LockWhen() 334 // Mutex::ReaderLockWhen() 335 // Mutex::WriterLockWhen() 336 // 337 // Blocks until simultaneously both `cond` is `true` and this `Mutex` can 338 // be acquired, then atomically acquires this `Mutex`. `LockWhen()` is 339 // logically equivalent to `*Lock(); Await();` though they may have different 340 // performance characteristics. 341 void LockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() { 342 LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(), 343 true); 344 } 345 346 void ReaderLockWhen(const Condition& cond) ABSL_SHARED_LOCK_FUNCTION() { 347 LockWhenCommon(cond, synchronization_internal::KernelTimeout::Never(), 348 false); 349 } 350 351 void WriterLockWhen(const Condition& cond) ABSL_EXCLUSIVE_LOCK_FUNCTION() { 352 this->LockWhen(cond); 353 } 354 355 // --------------------------------------------------------------------------- 356 // Mutex Variants with Timeouts/Deadlines 357 // --------------------------------------------------------------------------- 358 359 // Mutex::AwaitWithTimeout() 360 // Mutex::AwaitWithDeadline() 361 // 362 // Unlocks this `Mutex` and blocks until simultaneously: 363 // - either `cond` is true or the {timeout has expired, deadline has passed} 364 // and 365 // - this `Mutex` can be reacquired, 366 // then reacquire this `Mutex` in the same mode in which it was previously 367 // held, returning `true` iff `cond` is `true` on return. 368 // 369 // If the condition is initially `true`, the implementation *may* skip the 370 // release/re-acquire step and return immediately. 371 // 372 // Deadlines in the past are equivalent to an immediate deadline. 373 // Negative timeouts are equivalent to a zero timeout. 374 // 375 // This method requires that this thread holds this `Mutex` in some mode. 376 bool AwaitWithTimeout(const Condition& cond, absl::Duration timeout) { 377 return AwaitCommon(cond, synchronization_internal::KernelTimeout{timeout}); 378 } 379 380 bool AwaitWithDeadline(const Condition& cond, absl::Time deadline) { 381 return AwaitCommon(cond, synchronization_internal::KernelTimeout{deadline}); 382 } 383 384 // Mutex::LockWhenWithTimeout() 385 // Mutex::ReaderLockWhenWithTimeout() 386 // Mutex::WriterLockWhenWithTimeout() 387 // 388 // Blocks until simultaneously both: 389 // - either `cond` is `true` or the timeout has expired, and 390 // - this `Mutex` can be acquired, 391 // then atomically acquires this `Mutex`, returning `true` iff `cond` is 392 // `true` on return. 393 // 394 // Negative timeouts are equivalent to a zero timeout. 395 bool LockWhenWithTimeout(const Condition& cond, absl::Duration timeout) 396 ABSL_EXCLUSIVE_LOCK_FUNCTION() { 397 return LockWhenCommon( 398 cond, synchronization_internal::KernelTimeout{timeout}, true); 399 } 400 bool ReaderLockWhenWithTimeout(const Condition& cond, absl::Duration timeout) 401 ABSL_SHARED_LOCK_FUNCTION() { 402 return LockWhenCommon( 403 cond, synchronization_internal::KernelTimeout{timeout}, false); 404 } 405 bool WriterLockWhenWithTimeout(const Condition& cond, absl::Duration timeout) 406 ABSL_EXCLUSIVE_LOCK_FUNCTION() { 407 return this->LockWhenWithTimeout(cond, timeout); 408 } 409 410 // Mutex::LockWhenWithDeadline() 411 // Mutex::ReaderLockWhenWithDeadline() 412 // Mutex::WriterLockWhenWithDeadline() 413 // 414 // Blocks until simultaneously both: 415 // - either `cond` is `true` or the deadline has been passed, and 416 // - this `Mutex` can be acquired, 417 // then atomically acquires this Mutex, returning `true` iff `cond` is `true` 418 // on return. 419 // 420 // Deadlines in the past are equivalent to an immediate deadline. 421 bool LockWhenWithDeadline(const Condition& cond, absl::Time deadline) 422 ABSL_EXCLUSIVE_LOCK_FUNCTION() { 423 return LockWhenCommon( 424 cond, synchronization_internal::KernelTimeout{deadline}, true); 425 } 426 bool ReaderLockWhenWithDeadline(const Condition& cond, absl::Time deadline) 427 ABSL_SHARED_LOCK_FUNCTION() { 428 return LockWhenCommon( 429 cond, synchronization_internal::KernelTimeout{deadline}, false); 430 } 431 bool WriterLockWhenWithDeadline(const Condition& cond, absl::Time deadline) 432 ABSL_EXCLUSIVE_LOCK_FUNCTION() { 433 return this->LockWhenWithDeadline(cond, deadline); 434 } 435 436 // --------------------------------------------------------------------------- 437 // Debug Support: Invariant Checking, Deadlock Detection, Logging. 438 // --------------------------------------------------------------------------- 439 440 // Mutex::EnableInvariantDebugging() 441 // 442 // If `invariant`!=null and if invariant debugging has been enabled globally, 443 // cause `(*invariant)(arg)` to be called at moments when the invariant for 444 // this `Mutex` should hold (for example: just after acquire, just before 445 // release). 446 // 447 // The routine `invariant` should have no side-effects since it is not 448 // guaranteed how many times it will be called; it should check the invariant 449 // and crash if it does not hold. Enabling global invariant debugging may 450 // substantially reduce `Mutex` performance; it should be set only for 451 // non-production runs. Optimization options may also disable invariant 452 // checks. 453 void EnableInvariantDebugging( 454 void (*absl_nullable invariant)(void* absl_nullability_unknown), 455 void* absl_nullability_unknown arg); 456 457 // Mutex::EnableDebugLog() 458 // 459 // Cause all subsequent uses of this `Mutex` to be logged via 460 // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if no previous 461 // call to `EnableInvariantDebugging()` or `EnableDebugLog()` has been made. 462 // 463 // Note: This method substantially reduces `Mutex` performance. 464 void EnableDebugLog(const char* absl_nullable name); 465 466 // Deadlock detection 467 468 // Mutex::ForgetDeadlockInfo() 469 // 470 // Forget any deadlock-detection information previously gathered 471 // about this `Mutex`. Call this method in debug mode when the lock ordering 472 // of a `Mutex` changes. 473 void ForgetDeadlockInfo(); 474 475 // Mutex::AssertNotHeld() 476 // 477 // Return immediately if this thread does not hold this `Mutex` in any 478 // mode; otherwise, may report an error (typically by crashing with a 479 // diagnostic), or may return immediately. 480 // 481 // Currently this check is performed only if all of: 482 // - in debug mode 483 // - SetMutexDeadlockDetectionMode() has been set to kReport or kAbort 484 // - number of locks concurrently held by this thread is not large. 485 // are true. 486 void AssertNotHeld() const; 487 488 // Special cases. 489 490 // A `MuHow` is a constant that indicates how a lock should be acquired. 491 // Internal implementation detail. Clients should ignore. 492 typedef const struct MuHowS* MuHow; 493 494 // Mutex::InternalAttemptToUseMutexInFatalSignalHandler() 495 // 496 // Causes the `Mutex` implementation to prepare itself for re-entry caused by 497 // future use of `Mutex` within a fatal signal handler. This method is 498 // intended for use only for last-ditch attempts to log crash information. 499 // It does not guarantee that attempts to use Mutexes within the handler will 500 // not deadlock; it merely makes other faults less likely. 501 // 502 // WARNING: This routine must be invoked from a signal handler, and the 503 // signal handler must either loop forever or terminate the process. 504 // Attempts to return from (or `longjmp` out of) the signal handler once this 505 // call has been made may cause arbitrary program behaviour including 506 // crashes and deadlocks. 507 static void InternalAttemptToUseMutexInFatalSignalHandler(); 508 509 private: 510 std::atomic<intptr_t> mu_; // The Mutex state. 511 512 // Post()/Wait() versus associated PerThreadSem; in class for required 513 // friendship with PerThreadSem. 514 static void IncrementSynchSem(Mutex* absl_nonnull mu, 515 base_internal::PerThreadSynch* absl_nonnull w); 516 static bool DecrementSynchSem(Mutex* absl_nonnull mu, 517 base_internal::PerThreadSynch* absl_nonnull w, 518 synchronization_internal::KernelTimeout t); 519 520 // slow path acquire 521 void LockSlowLoop(SynchWaitParams* absl_nonnull waitp, int flags); 522 // wrappers around LockSlowLoop() 523 bool LockSlowWithDeadline(MuHow absl_nonnull how, 524 const Condition* absl_nullable cond, 525 synchronization_internal::KernelTimeout t, 526 int flags); 527 void LockSlow(MuHow absl_nonnull how, const Condition* absl_nullable cond, 528 int flags) ABSL_ATTRIBUTE_COLD; 529 // slow path release 530 void UnlockSlow(SynchWaitParams* absl_nullable waitp) ABSL_ATTRIBUTE_COLD; 531 // TryLock slow path. 532 bool TryLockSlow(); 533 // ReaderTryLock slow path. 534 bool ReaderTryLockSlow(); 535 // Common code between Await() and AwaitWithTimeout/Deadline() 536 bool AwaitCommon(const Condition& cond, 537 synchronization_internal::KernelTimeout t); 538 bool LockWhenCommon(const Condition& cond, 539 synchronization_internal::KernelTimeout t, bool write); 540 // Attempt to remove thread s from queue. 541 void TryRemove(base_internal::PerThreadSynch* absl_nonnull s); 542 // Block a thread on mutex. 543 void Block(base_internal::PerThreadSynch* absl_nonnull s); 544 // Wake a thread; return successor. 545 base_internal::PerThreadSynch* absl_nullable Wakeup( 546 base_internal::PerThreadSynch* absl_nonnull w); 547 void Dtor(); 548 549 friend class CondVar; // for access to Trans()/Fer(). 550 void Trans(MuHow absl_nonnull how); // used for CondVar->Mutex transfer 551 void Fer(base_internal::PerThreadSynch* absl_nonnull 552 w); // used for CondVar->Mutex transfer 553 554 // Catch the error of writing Mutex when intending MutexLock. 555 explicit Mutex(const volatile Mutex* absl_nullable /*ignored*/) {} 556 557 Mutex(const Mutex&) = delete; 558 Mutex& operator=(const Mutex&) = delete; 559 }; 560 561 // ----------------------------------------------------------------------------- 562 // Mutex RAII Wrappers 563 // ----------------------------------------------------------------------------- 564 565 // MutexLock 566 // 567 // `MutexLock` is a helper class, which acquires and releases a `Mutex` via 568 // RAII. 569 // 570 // Example: 571 // 572 // Class Foo { 573 // public: 574 // Foo::Bar* Baz() { 575 // MutexLock lock(&mu_); 576 // ... 577 // return bar; 578 // } 579 // 580 // private: 581 // Mutex mu_; 582 // }; 583 class ABSL_SCOPED_LOCKABLE MutexLock { 584 public: 585 // Constructors 586 587 // Calls `mu->Lock()` and returns when that call returns. That is, `*mu` is 588 // guaranteed to be locked when this object is constructed. Requires that 589 // `mu` be dereferenceable. 590 explicit MutexLock(Mutex* absl_nonnull mu) ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 591 : mu_(mu) { 592 this->mu_->Lock(); 593 } 594 595 // Like above, but calls `mu->LockWhen(cond)` instead. That is, in addition to 596 // the above, the condition given by `cond` is also guaranteed to hold when 597 // this object is constructed. 598 explicit MutexLock(Mutex* absl_nonnull mu, const Condition& cond) 599 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 600 : mu_(mu) { 601 this->mu_->LockWhen(cond); 602 } 603 604 MutexLock(const MutexLock&) = delete; // NOLINT(runtime/mutex) 605 MutexLock(MutexLock&&) = delete; // NOLINT(runtime/mutex) 606 MutexLock& operator=(const MutexLock&) = delete; 607 MutexLock& operator=(MutexLock&&) = delete; 608 609 ~MutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->Unlock(); } 610 611 private: 612 Mutex* absl_nonnull const mu_; 613 }; 614 615 // ReaderMutexLock 616 // 617 // The `ReaderMutexLock` is a helper class, like `MutexLock`, which acquires and 618 // releases a shared lock on a `Mutex` via RAII. 619 class ABSL_SCOPED_LOCKABLE ReaderMutexLock { 620 public: 621 explicit ReaderMutexLock(Mutex* absl_nonnull mu) ABSL_SHARED_LOCK_FUNCTION(mu) 622 : mu_(mu) { 623 mu->ReaderLock(); 624 } 625 626 explicit ReaderMutexLock(Mutex* absl_nonnull mu, const Condition& cond) 627 ABSL_SHARED_LOCK_FUNCTION(mu) 628 : mu_(mu) { 629 mu->ReaderLockWhen(cond); 630 } 631 632 ReaderMutexLock(const ReaderMutexLock&) = delete; 633 ReaderMutexLock(ReaderMutexLock&&) = delete; 634 ReaderMutexLock& operator=(const ReaderMutexLock&) = delete; 635 ReaderMutexLock& operator=(ReaderMutexLock&&) = delete; 636 637 ~ReaderMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->ReaderUnlock(); } 638 639 private: 640 Mutex* absl_nonnull const mu_; 641 }; 642 643 // WriterMutexLock 644 // 645 // The `WriterMutexLock` is a helper class, like `MutexLock`, which acquires and 646 // releases a write (exclusive) lock on a `Mutex` via RAII. 647 class ABSL_SCOPED_LOCKABLE WriterMutexLock { 648 public: 649 explicit WriterMutexLock(Mutex* absl_nonnull mu) 650 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 651 : mu_(mu) { 652 mu->WriterLock(); 653 } 654 655 explicit WriterMutexLock(Mutex* absl_nonnull mu, const Condition& cond) 656 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 657 : mu_(mu) { 658 mu->WriterLockWhen(cond); 659 } 660 661 WriterMutexLock(const WriterMutexLock&) = delete; 662 WriterMutexLock(WriterMutexLock&&) = delete; 663 WriterMutexLock& operator=(const WriterMutexLock&) = delete; 664 WriterMutexLock& operator=(WriterMutexLock&&) = delete; 665 666 ~WriterMutexLock() ABSL_UNLOCK_FUNCTION() { this->mu_->WriterUnlock(); } 667 668 private: 669 Mutex* absl_nonnull const mu_; 670 }; 671 672 // ----------------------------------------------------------------------------- 673 // Condition 674 // ----------------------------------------------------------------------------- 675 // 676 // `Mutex` contains a number of member functions which take a `Condition` as an 677 // argument; clients can wait for conditions to become `true` before attempting 678 // to acquire the mutex. These sections are known as "condition critical" 679 // sections. To use a `Condition`, you simply need to construct it, and use 680 // within an appropriate `Mutex` member function; everything else in the 681 // `Condition` class is an implementation detail. 682 // 683 // A `Condition` is specified as a function pointer which returns a boolean. 684 // `Condition` functions should be pure functions -- their results should depend 685 // only on passed arguments, should not consult any external state (such as 686 // clocks), and should have no side-effects, aside from debug logging. Any 687 // objects that the function may access should be limited to those which are 688 // constant while the mutex is blocked on the condition (e.g. a stack variable), 689 // or objects of state protected explicitly by the mutex. 690 // 691 // No matter which construction is used for `Condition`, the underlying 692 // function pointer / functor / callable must not throw any 693 // exceptions. Correctness of `Mutex` / `Condition` is not guaranteed in 694 // the face of a throwing `Condition`. (When Abseil is allowed to depend 695 // on C++17, these function pointers will be explicitly marked 696 // `noexcept`; until then this requirement cannot be enforced in the 697 // type system.) 698 // 699 // Note: to use a `Condition`, you need only construct it and pass it to a 700 // suitable `Mutex' member function, such as `Mutex::Await()`, or to the 701 // constructor of one of the scope guard classes. 702 // 703 // Example using LockWhen/Unlock: 704 // 705 // // assume count_ is not internal reference count 706 // int count_ ABSL_GUARDED_BY(mu_); 707 // Condition count_is_zero(+[](int *count) { return *count == 0; }, &count_); 708 // 709 // mu_.LockWhen(count_is_zero); 710 // // ... 711 // mu_.Unlock(); 712 // 713 // Example using a scope guard: 714 // 715 // { 716 // MutexLock lock(&mu_, count_is_zero); 717 // // ... 718 // } 719 // 720 // When multiple threads are waiting on exactly the same condition, make sure 721 // that they are constructed with the same parameters (same pointer to function 722 // + arg, or same pointer to object + method), so that the mutex implementation 723 // can avoid redundantly evaluating the same condition for each thread. 724 class Condition { 725 public: 726 // A Condition that returns the result of "(*func)(arg)" 727 Condition(bool (*absl_nonnull func)(void* absl_nullability_unknown), 728 void* absl_nullability_unknown arg); 729 730 // Templated version for people who are averse to casts. 731 // 732 // To use a lambda, prepend it with unary plus, which converts the lambda 733 // into a function pointer: 734 // Condition(+[](T* t) { return ...; }, arg). 735 // 736 // Note: lambdas in this case must contain no bound variables. 737 // 738 // See class comment for performance advice. 739 template <typename T> 740 Condition(bool (*absl_nonnull func)(T* absl_nullability_unknown), 741 T* absl_nullability_unknown arg); 742 743 // Same as above, but allows for cases where `arg` comes from a pointer that 744 // is convertible to the function parameter type `T*` but not an exact match. 745 // 746 // For example, the argument might be `X*` but the function takes `const X*`, 747 // or the argument might be `Derived*` while the function takes `Base*`, and 748 // so on for cases where the argument pointer can be implicitly converted. 749 // 750 // Implementation notes: This constructor overload is required in addition to 751 // the one above to allow deduction of `T` from `arg` for cases such as where 752 // a function template is passed as `func`. Also, the dummy `typename = void` 753 // template parameter exists just to work around a MSVC mangling bug. 754 template <typename T, typename = void> 755 Condition( 756 bool (*absl_nonnull func)(T* absl_nullability_unknown), 757 typename absl::internal::type_identity<T>::type* absl_nullability_unknown 758 arg); 759 760 // Templated version for invoking a method that returns a `bool`. 761 // 762 // `Condition(object, &Class::Method)` constructs a `Condition` that evaluates 763 // `object->Method()`. 764 // 765 // Implementation Note: `absl::internal::type_identity` is used to allow 766 // methods to come from base classes. A simpler signature like 767 // `Condition(T*, bool (T::*)())` does not suffice. 768 template <typename T> 769 Condition( 770 T* absl_nonnull object, 771 bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()); 772 773 // Same as above, for const members 774 template <typename T> 775 Condition( 776 const T* absl_nonnull object, 777 bool (absl::internal::type_identity<T>::type::* absl_nonnull method)() 778 const); 779 780 // A Condition that returns the value of `*cond` 781 explicit Condition(const bool* absl_nonnull cond); 782 783 // Templated version for invoking a functor that returns a `bool`. 784 // This approach accepts pointers to non-mutable lambdas, `std::function`, 785 // the result of` std::bind` and user-defined functors that define 786 // `bool F::operator()() const`. 787 // 788 // Example: 789 // 790 // auto reached = [this, current]() { 791 // mu_.AssertReaderHeld(); // For annotalysis. 792 // return processed_ >= current; 793 // }; 794 // mu_.Await(Condition(&reached)); 795 // 796 // NOTE: never use "mu_.AssertHeld()" instead of "mu_.AssertReaderHeld()" in 797 // the lambda as it may be called when the mutex is being unlocked from a 798 // scope holding only a reader lock, which will make the assertion not 799 // fulfilled and crash the binary. 800 801 // See class comment for performance advice. In particular, if there 802 // might be more than one waiter for the same condition, make sure 803 // that all waiters construct the condition with the same pointers. 804 805 // Implementation note: The second template parameter ensures that this 806 // constructor doesn't participate in overload resolution if T doesn't have 807 // `bool operator() const`. 808 template <typename T, typename E = decltype(static_cast<bool (T::*)() const>( 809 &T::operator()))> 810 explicit Condition(const T* absl_nonnull obj) 811 : Condition(obj, static_cast<bool (T::*)() const>(&T::operator())) {} 812 813 // A Condition that always returns `true`. 814 // kTrue is only useful in a narrow set of circumstances, mostly when 815 // it's passed conditionally. For example: 816 // 817 // mu.LockWhen(some_flag ? kTrue : SomeOtherCondition); 818 // 819 // Note: {LockWhen,Await}With{Deadline,Timeout} methods with kTrue condition 820 // don't return immediately when the timeout happens, they still block until 821 // the Mutex becomes available. The return value of these methods does 822 // not indicate if the timeout was reached; rather it indicates whether or 823 // not the condition is true. 824 ABSL_CONST_INIT static const Condition kTrue; 825 826 // Evaluates the condition. 827 bool Eval() const; 828 829 // Returns `true` if the two conditions are guaranteed to return the same 830 // value if evaluated at the same time, `false` if the evaluation *may* return 831 // different results. 832 // 833 // Two `Condition` values are guaranteed equal if both their `func` and `arg` 834 // components are the same. A null pointer is equivalent to a `true` 835 // condition. 836 static bool GuaranteedEqual(const Condition* absl_nullable a, 837 const Condition* absl_nullable b); 838 839 private: 840 // Sizing an allocation for a method pointer can be subtle. In the Itanium 841 // specifications, a method pointer has a predictable, uniform size. On the 842 // other hand, MSVC ABI, method pointer sizes vary based on the 843 // inheritance of the class. Specifically, method pointers from classes with 844 // multiple inheritance are bigger than those of classes with single 845 // inheritance. Other variations also exist. 846 847 #ifndef _MSC_VER 848 // Allocation for a function pointer or method pointer. 849 // The {0} initializer ensures that all unused bytes of this buffer are 850 // always zeroed out. This is necessary, because GuaranteedEqual() compares 851 // all of the bytes, unaware of which bytes are relevant to a given `eval_`. 852 using MethodPtr = bool (Condition::*)(); 853 char callback_[sizeof(MethodPtr)] = {0}; 854 #else 855 // It is well known that the larget MSVC pointer-to-member is 24 bytes. This 856 // may be the largest known pointer-to-member of any platform. For this 857 // reason we will allocate 24 bytes for MSVC platform toolchains. 858 char callback_[24] = {0}; 859 #endif 860 861 // Function with which to evaluate callbacks and/or arguments. 862 bool (*absl_nullable eval_)(const Condition* absl_nonnull) = nullptr; 863 864 // Either an argument for a function call or an object for a method call. 865 void* absl_nullable arg_ = nullptr; 866 867 // Various functions eval_ can point to: 868 static bool CallVoidPtrFunction(const Condition* absl_nonnull c); 869 template <typename T> 870 static bool CastAndCallFunction(const Condition* absl_nonnull c); 871 template <typename T, typename ConditionMethodPtr> 872 static bool CastAndCallMethod(const Condition* absl_nonnull c); 873 874 // Helper methods for storing, validating, and reading callback arguments. 875 template <typename T> 876 inline void StoreCallback(T callback) { 877 static_assert( 878 sizeof(callback) <= sizeof(callback_), 879 "An overlarge pointer was passed as a callback to Condition."); 880 std::memcpy(callback_, &callback, sizeof(callback)); 881 } 882 883 template <typename T> 884 inline void ReadCallback(T* absl_nonnull callback) const { 885 std::memcpy(callback, callback_, sizeof(*callback)); 886 } 887 888 static bool AlwaysTrue(const Condition* absl_nullable) { return true; } 889 890 // Used only to create kTrue. 891 constexpr Condition() : eval_(AlwaysTrue), arg_(nullptr) {} 892 }; 893 894 // ----------------------------------------------------------------------------- 895 // CondVar 896 // ----------------------------------------------------------------------------- 897 // 898 // A condition variable, reflecting state evaluated separately outside of the 899 // `Mutex` object, which can be signaled to wake callers. 900 // This class is not normally needed; use `Mutex` member functions such as 901 // `Mutex::Await()` and intrinsic `Condition` abstractions. In rare cases 902 // with many threads and many conditions, `CondVar` may be faster. 903 // 904 // The implementation may deliver signals to any condition variable at 905 // any time, even when no call to `Signal()` or `SignalAll()` is made; as a 906 // result, upon being awoken, you must check the logical condition you have 907 // been waiting upon. 908 // 909 // Examples: 910 // 911 // Usage for a thread waiting for some condition C protected by mutex mu: 912 // mu.Lock(); 913 // while (!C) { cv->Wait(&mu); } // releases and reacquires mu 914 // // C holds; process data 915 // mu.Unlock(); 916 // 917 // Usage to wake T is: 918 // mu.Lock(); 919 // // process data, possibly establishing C 920 // if (C) { cv->Signal(); } 921 // mu.Unlock(); 922 // 923 // If C may be useful to more than one waiter, use `SignalAll()` instead of 924 // `Signal()`. 925 // 926 // With this implementation it is efficient to use `Signal()/SignalAll()` inside 927 // the locked region; this usage can make reasoning about your program easier. 928 // 929 class CondVar { 930 public: 931 // A `CondVar` allocated on the heap or on the stack can use the this 932 // constructor. 933 CondVar(); 934 935 // CondVar::Wait() 936 // 937 // Atomically releases a `Mutex` and blocks on this condition variable. 938 // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a 939 // spurious wakeup), then reacquires the `Mutex` and returns. 940 // 941 // Requires and ensures that the current thread holds the `Mutex`. 942 void Wait(Mutex* absl_nonnull mu) { 943 WaitCommon(mu, synchronization_internal::KernelTimeout::Never()); 944 } 945 946 // CondVar::WaitWithTimeout() 947 // 948 // Atomically releases a `Mutex` and blocks on this condition variable. 949 // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a 950 // spurious wakeup), or until the timeout has expired, then reacquires 951 // the `Mutex` and returns. 952 // 953 // Returns true if the timeout has expired without this `CondVar` 954 // being signalled in any manner. If both the timeout has expired 955 // and this `CondVar` has been signalled, the implementation is free 956 // to return `true` or `false`. 957 // 958 // Requires and ensures that the current thread holds the `Mutex`. 959 bool WaitWithTimeout(Mutex* absl_nonnull mu, absl::Duration timeout) { 960 return WaitCommon(mu, synchronization_internal::KernelTimeout(timeout)); 961 } 962 963 // CondVar::WaitWithDeadline() 964 // 965 // Atomically releases a `Mutex` and blocks on this condition variable. 966 // Waits until awakened by a call to `Signal()` or `SignalAll()` (or a 967 // spurious wakeup), or until the deadline has passed, then reacquires 968 // the `Mutex` and returns. 969 // 970 // Deadlines in the past are equivalent to an immediate deadline. 971 // 972 // Returns true if the deadline has passed without this `CondVar` 973 // being signalled in any manner. If both the deadline has passed 974 // and this `CondVar` has been signalled, the implementation is free 975 // to return `true` or `false`. 976 // 977 // Requires and ensures that the current thread holds the `Mutex`. 978 bool WaitWithDeadline(Mutex* absl_nonnull mu, absl::Time deadline) { 979 return WaitCommon(mu, synchronization_internal::KernelTimeout(deadline)); 980 } 981 982 // CondVar::Signal() 983 // 984 // Signal this `CondVar`; wake at least one waiter if one exists. 985 void Signal(); 986 987 // CondVar::SignalAll() 988 // 989 // Signal this `CondVar`; wake all waiters. 990 void SignalAll(); 991 992 // CondVar::EnableDebugLog() 993 // 994 // Causes all subsequent uses of this `CondVar` to be logged via 995 // `ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if `name != 0`. 996 // Note: this method substantially reduces `CondVar` performance. 997 void EnableDebugLog(const char* absl_nullable name); 998 999 private: 1000 bool WaitCommon(Mutex* absl_nonnull mutex, 1001 synchronization_internal::KernelTimeout t); 1002 void Remove(base_internal::PerThreadSynch* absl_nonnull s); 1003 std::atomic<intptr_t> cv_; // Condition variable state. 1004 CondVar(const CondVar&) = delete; 1005 CondVar& operator=(const CondVar&) = delete; 1006 }; 1007 1008 // Variants of MutexLock. 1009 // 1010 // If you find yourself using one of these, consider instead using 1011 // Mutex::Unlock() and/or if-statements for clarity. 1012 1013 // MutexLockMaybe 1014 // 1015 // MutexLockMaybe is like MutexLock, but is a no-op when mu is null. 1016 class ABSL_SCOPED_LOCKABLE MutexLockMaybe { 1017 public: 1018 explicit MutexLockMaybe(Mutex* absl_nullable mu) 1019 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 1020 : mu_(mu) { 1021 if (this->mu_ != nullptr) { 1022 this->mu_->Lock(); 1023 } 1024 } 1025 1026 explicit MutexLockMaybe(Mutex* absl_nullable mu, const Condition& cond) 1027 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 1028 : mu_(mu) { 1029 if (this->mu_ != nullptr) { 1030 this->mu_->LockWhen(cond); 1031 } 1032 } 1033 1034 ~MutexLockMaybe() ABSL_UNLOCK_FUNCTION() { 1035 if (this->mu_ != nullptr) { 1036 this->mu_->Unlock(); 1037 } 1038 } 1039 1040 private: 1041 Mutex* absl_nullable const mu_; 1042 MutexLockMaybe(const MutexLockMaybe&) = delete; 1043 MutexLockMaybe(MutexLockMaybe&&) = delete; 1044 MutexLockMaybe& operator=(const MutexLockMaybe&) = delete; 1045 MutexLockMaybe& operator=(MutexLockMaybe&&) = delete; 1046 }; 1047 1048 // ReleasableMutexLock 1049 // 1050 // ReleasableMutexLock is like MutexLock, but permits `Release()` of its 1051 // mutex before destruction. `Release()` may be called at most once. 1052 class ABSL_SCOPED_LOCKABLE ReleasableMutexLock { 1053 public: 1054 explicit ReleasableMutexLock(Mutex* absl_nonnull mu) 1055 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 1056 : mu_(mu) { 1057 this->mu_->Lock(); 1058 } 1059 1060 explicit ReleasableMutexLock(Mutex* absl_nonnull mu, const Condition& cond) 1061 ABSL_EXCLUSIVE_LOCK_FUNCTION(mu) 1062 : mu_(mu) { 1063 this->mu_->LockWhen(cond); 1064 } 1065 1066 ~ReleasableMutexLock() ABSL_UNLOCK_FUNCTION() { 1067 if (this->mu_ != nullptr) { 1068 this->mu_->Unlock(); 1069 } 1070 } 1071 1072 void Release() ABSL_UNLOCK_FUNCTION(); 1073 1074 private: 1075 Mutex* absl_nonnull mu_; 1076 ReleasableMutexLock(const ReleasableMutexLock&) = delete; 1077 ReleasableMutexLock(ReleasableMutexLock&&) = delete; 1078 ReleasableMutexLock& operator=(const ReleasableMutexLock&) = delete; 1079 ReleasableMutexLock& operator=(ReleasableMutexLock&&) = delete; 1080 }; 1081 1082 inline Mutex::Mutex() : mu_(0) { 1083 ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); 1084 } 1085 1086 inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {} 1087 1088 #if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL) 1089 ABSL_ATTRIBUTE_ALWAYS_INLINE 1090 inline Mutex::~Mutex() { Dtor(); } 1091 #endif 1092 1093 #if defined(NDEBUG) && !defined(ABSL_HAVE_THREAD_SANITIZER) 1094 // Use default (empty) destructor in release build for performance reasons. 1095 // We need to mark both Dtor and ~Mutex as always inline for inconsistent 1096 // builds that use both NDEBUG and !NDEBUG with dynamic libraries. In these 1097 // cases we want the empty functions to dissolve entirely rather than being 1098 // exported from dynamic libraries and potentially override the non-empty ones. 1099 ABSL_ATTRIBUTE_ALWAYS_INLINE 1100 inline void Mutex::Dtor() {} 1101 #endif 1102 1103 inline CondVar::CondVar() : cv_(0) {} 1104 1105 // static 1106 template <typename T, typename ConditionMethodPtr> 1107 bool Condition::CastAndCallMethod(const Condition* absl_nonnull c) { 1108 T* object = static_cast<T*>(c->arg_); 1109 ConditionMethodPtr condition_method_pointer; 1110 c->ReadCallback(&condition_method_pointer); 1111 return (object->*condition_method_pointer)(); 1112 } 1113 1114 // static 1115 template <typename T> 1116 bool Condition::CastAndCallFunction(const Condition* absl_nonnull c) { 1117 bool (*function)(T*); 1118 c->ReadCallback(&function); 1119 T* argument = static_cast<T*>(c->arg_); 1120 return (*function)(argument); 1121 } 1122 1123 template <typename T> 1124 inline Condition::Condition( 1125 bool (*absl_nonnull func)(T* absl_nullability_unknown), 1126 T* absl_nullability_unknown arg) 1127 : eval_(&CastAndCallFunction<T>), 1128 arg_(const_cast<void*>(static_cast<const void*>(arg))) { 1129 static_assert(sizeof(&func) <= sizeof(callback_), 1130 "An overlarge function pointer was passed to Condition."); 1131 StoreCallback(func); 1132 } 1133 1134 template <typename T, typename> 1135 inline Condition::Condition( 1136 bool (*absl_nonnull func)(T* absl_nullability_unknown), 1137 typename absl::internal::type_identity<T>::type* absl_nullability_unknown 1138 arg) 1139 // Just delegate to the overload above. 1140 : Condition(func, arg) {} 1141 1142 template <typename T> 1143 inline Condition::Condition( 1144 T* absl_nonnull object, 1145 bool (absl::internal::type_identity<T>::type::* absl_nonnull method)()) 1146 : eval_(&CastAndCallMethod<T, decltype(method)>), arg_(object) { 1147 static_assert(sizeof(&method) <= sizeof(callback_), 1148 "An overlarge method pointer was passed to Condition."); 1149 StoreCallback(method); 1150 } 1151 1152 template <typename T> 1153 inline Condition::Condition( 1154 const T* absl_nonnull object, 1155 bool (absl::internal::type_identity<T>::type::* absl_nonnull method)() 1156 const) 1157 : eval_(&CastAndCallMethod<const T, decltype(method)>), 1158 arg_(reinterpret_cast<void*>(const_cast<T*>(object))) { 1159 StoreCallback(method); 1160 } 1161 1162 // Register hooks for profiling support. 1163 // 1164 // The function pointer registered here will be called whenever a mutex is 1165 // contended. The callback is given the cycles for which waiting happened (as 1166 // measured by //absl/base/internal/cycleclock.h, and which may not 1167 // be real "cycle" counts.) 1168 // 1169 // There is no ordering guarantee between when the hook is registered and when 1170 // callbacks will begin. Only a single profiler can be installed in a running 1171 // binary; if this function is called a second time with a different function 1172 // pointer, the value is ignored (and will cause an assertion failure in debug 1173 // mode.) 1174 void RegisterMutexProfiler(void (*absl_nonnull fn)(int64_t wait_cycles)); 1175 1176 // Register a hook for Mutex tracing. 1177 // 1178 // The function pointer registered here will be called whenever a mutex is 1179 // contended. The callback is given an opaque handle to the contended mutex, 1180 // an event name, and the number of wait cycles (as measured by 1181 // //absl/base/internal/cycleclock.h, and which may not be real 1182 // "cycle" counts.) 1183 // 1184 // The only event name currently sent is "slow release". 1185 // 1186 // This has the same ordering and single-use limitations as 1187 // RegisterMutexProfiler() above. 1188 void RegisterMutexTracer(void (*absl_nonnull fn)(const char* absl_nonnull msg, 1189 const void* absl_nonnull obj, 1190 int64_t wait_cycles)); 1191 1192 // Register a hook for CondVar tracing. 1193 // 1194 // The function pointer registered here will be called here on various CondVar 1195 // events. The callback is given an opaque handle to the CondVar object and 1196 // a string identifying the event. This is thread-safe, but only a single 1197 // tracer can be registered. 1198 // 1199 // Events that can be sent are "Wait", "Unwait", "Signal wakeup", and 1200 // "SignalAll wakeup". 1201 // 1202 // This has the same ordering and single-use limitations as 1203 // RegisterMutexProfiler() above. 1204 void RegisterCondVarTracer(void (*absl_nonnull fn)( 1205 const char* absl_nonnull msg, const void* absl_nonnull cv)); 1206 1207 // EnableMutexInvariantDebugging() 1208 // 1209 // Enable or disable global support for Mutex invariant debugging. If enabled, 1210 // then invariant predicates can be registered per-Mutex for debug checking. 1211 // See Mutex::EnableInvariantDebugging(). 1212 void EnableMutexInvariantDebugging(bool enabled); 1213 1214 // When in debug mode, and when the feature has been enabled globally, the 1215 // implementation will keep track of lock ordering and complain (or optionally 1216 // crash) if a cycle is detected in the acquired-before graph. 1217 1218 // Possible modes of operation for the deadlock detector in debug mode. 1219 enum class OnDeadlockCycle { 1220 kIgnore, // Neither report on nor attempt to track cycles in lock ordering 1221 kReport, // Report lock cycles to stderr when detected 1222 kAbort, // Report lock cycles to stderr when detected, then abort 1223 }; 1224 1225 // SetMutexDeadlockDetectionMode() 1226 // 1227 // Enable or disable global support for detection of potential deadlocks 1228 // due to Mutex lock ordering inversions. When set to 'kIgnore', tracking of 1229 // lock ordering is disabled. Otherwise, in debug builds, a lock ordering graph 1230 // will be maintained internally, and detected cycles will be reported in 1231 // the manner chosen here. 1232 void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode); 1233 1234 ABSL_NAMESPACE_END 1235 } // namespace absl 1236 1237 // In some build configurations we pass --detect-odr-violations to the 1238 // gold linker. This causes it to flag weak symbol overrides as ODR 1239 // violations. Because ODR only applies to C++ and not C, 1240 // --detect-odr-violations ignores symbols not mangled with C++ names. 1241 // By changing our extension points to be extern "C", we dodge this 1242 // check. 1243 extern "C" { 1244 void ABSL_INTERNAL_C_SYMBOL(AbslInternalMutexYield)(); 1245 } // extern "C" 1246 1247 #endif // ABSL_SYNCHRONIZATION_MUTEX_H_