• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "absl/synchronization/mutex.h"
16 
17 #ifdef _WIN32
18 #include <windows.h>
19 #ifdef ERROR
20 #undef ERROR
21 #endif
22 #else
23 #include <fcntl.h>
24 #include <pthread.h>
25 #include <sched.h>
26 #include <sys/time.h>
27 #endif
28 
29 #include <assert.h>
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <time.h>
35 
36 #include <algorithm>
37 #include <atomic>
38 #include <cinttypes>
39 #include <thread>  // NOLINT(build/c++11)
40 
41 #include "absl/base/attributes.h"
42 #include "absl/base/config.h"
43 #include "absl/base/dynamic_annotations.h"
44 #include "absl/base/internal/atomic_hook.h"
45 #include "absl/base/internal/cycleclock.h"
46 #include "absl/base/internal/hide_ptr.h"
47 #include "absl/base/internal/low_level_alloc.h"
48 #include "absl/base/internal/raw_logging.h"
49 #include "absl/base/internal/spinlock.h"
50 #include "absl/base/internal/sysinfo.h"
51 #include "absl/base/internal/thread_identity.h"
52 #include "absl/base/port.h"
53 #include "absl/debugging/stacktrace.h"
54 #include "absl/debugging/symbolize.h"
55 #include "absl/synchronization/internal/graphcycles.h"
56 #include "absl/synchronization/internal/per_thread_sem.h"
57 #include "absl/time/time.h"
58 
59 using absl::base_internal::CurrentThreadIdentityIfPresent;
60 using absl::base_internal::PerThreadSynch;
61 using absl::base_internal::ThreadIdentity;
62 using absl::synchronization_internal::GetOrCreateCurrentThreadIdentity;
63 using absl::synchronization_internal::GraphCycles;
64 using absl::synchronization_internal::GraphId;
65 using absl::synchronization_internal::InvalidGraphId;
66 using absl::synchronization_internal::KernelTimeout;
67 using absl::synchronization_internal::PerThreadSem;
68 
69 extern "C" {
AbslInternalMutexYield()70 ABSL_ATTRIBUTE_WEAK void AbslInternalMutexYield() { std::this_thread::yield(); }
71 }  // extern "C"
72 
73 namespace absl {
74 ABSL_NAMESPACE_BEGIN
75 
76 namespace {
77 
78 #if defined(THREAD_SANITIZER)
79 constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kIgnore;
80 #else
81 constexpr OnDeadlockCycle kDeadlockDetectionDefault = OnDeadlockCycle::kAbort;
82 #endif
83 
84 ABSL_CONST_INIT std::atomic<OnDeadlockCycle> synch_deadlock_detection(
85     kDeadlockDetectionDefault);
86 ABSL_CONST_INIT std::atomic<bool> synch_check_invariants(false);
87 
88 // ------------------------------------------ spinlock support
89 
90 // Make sure read-only globals used in the Mutex code are contained on the
91 // same cacheline and cacheline aligned to eliminate any false sharing with
92 // other globals from this and other modules.
93 static struct MutexGlobals {
MutexGlobalsabsl::__anon50fe7d610111::MutexGlobals94   MutexGlobals() {
95     // Find machine-specific data needed for Delay() and
96     // TryAcquireWithSpinning(). This runs in the global constructor
97     // sequence, and before that zeros are safe values.
98     num_cpus = absl::base_internal::NumCPUs();
99     spinloop_iterations = num_cpus > 1 ? 1500 : 0;
100   }
101   int num_cpus;
102   int spinloop_iterations;
103   // Pad this struct to a full cacheline to prevent false sharing.
104   char padding[ABSL_CACHELINE_SIZE - 2 * sizeof(int)];
105 } ABSL_CACHELINE_ALIGNED mutex_globals;
106 static_assert(
107     sizeof(MutexGlobals) == ABSL_CACHELINE_SIZE,
108     "MutexGlobals must occupy an entire cacheline to prevent false sharing");
109 
110 ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
111     absl::base_internal::AtomicHook<void (*)(int64_t wait_cycles)>
112         submit_profile_data;
113 ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<void (*)(
114     const char *msg, const void *obj, int64_t wait_cycles)>
115     mutex_tracer;
116 ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
117     absl::base_internal::AtomicHook<void (*)(const char *msg, const void *cv)>
118         cond_var_tracer;
119 ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES absl::base_internal::AtomicHook<
120     bool (*)(const void *pc, char *out, int out_size)>
121     symbolizer(absl::Symbolize);
122 
123 }  // namespace
124 
125 static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu,
126                                           bool locking, bool trylock,
127                                           bool read_lock);
128 
RegisterMutexProfiler(void (* fn)(int64_t wait_timestamp))129 void RegisterMutexProfiler(void (*fn)(int64_t wait_timestamp)) {
130   submit_profile_data.Store(fn);
131 }
132 
RegisterMutexTracer(void (* fn)(const char * msg,const void * obj,int64_t wait_cycles))133 void RegisterMutexTracer(void (*fn)(const char *msg, const void *obj,
134                                     int64_t wait_cycles)) {
135   mutex_tracer.Store(fn);
136 }
137 
RegisterCondVarTracer(void (* fn)(const char * msg,const void * cv))138 void RegisterCondVarTracer(void (*fn)(const char *msg, const void *cv)) {
139   cond_var_tracer.Store(fn);
140 }
141 
RegisterSymbolizer(bool (* fn)(const void * pc,char * out,int out_size))142 void RegisterSymbolizer(bool (*fn)(const void *pc, char *out, int out_size)) {
143   symbolizer.Store(fn);
144 }
145 
146 // spinlock delay on iteration c.  Returns new c.
147 namespace {
148   enum DelayMode { AGGRESSIVE, GENTLE };
149 };
Delay(int32_t c,DelayMode mode)150 static int Delay(int32_t c, DelayMode mode) {
151   // If this a uniprocessor, only yield/sleep.  Otherwise, if the mode is
152   // aggressive then spin many times before yielding.  If the mode is
153   // gentle then spin only a few times before yielding.  Aggressive spinning is
154   // used to ensure that an Unlock() call, which  must get the spin lock for
155   // any thread to make progress gets it without undue delay.
156   int32_t limit = (mutex_globals.num_cpus > 1) ?
157       ((mode == AGGRESSIVE) ? 5000 : 250) : 0;
158   if (c < limit) {
159     c++;               // spin
160   } else {
161     ABSL_TSAN_MUTEX_PRE_DIVERT(nullptr, 0);
162     if (c == limit) {  // yield once
163       AbslInternalMutexYield();
164       c++;
165     } else {           // then wait
166       absl::SleepFor(absl::Microseconds(10));
167       c = 0;
168     }
169     ABSL_TSAN_MUTEX_POST_DIVERT(nullptr, 0);
170   }
171   return (c);
172 }
173 
174 // --------------------------Generic atomic ops
175 // Ensure that "(*pv & bits) == bits" by doing an atomic update of "*pv" to
176 // "*pv | bits" if necessary.  Wait until (*pv & wait_until_clear)==0
177 // before making any change.
178 // This is used to set flags in mutex and condition variable words.
AtomicSetBits(std::atomic<intptr_t> * pv,intptr_t bits,intptr_t wait_until_clear)179 static void AtomicSetBits(std::atomic<intptr_t>* pv, intptr_t bits,
180                           intptr_t wait_until_clear) {
181   intptr_t v;
182   do {
183     v = pv->load(std::memory_order_relaxed);
184   } while ((v & bits) != bits &&
185            ((v & wait_until_clear) != 0 ||
186             !pv->compare_exchange_weak(v, v | bits,
187                                        std::memory_order_release,
188                                        std::memory_order_relaxed)));
189 }
190 
191 // Ensure that "(*pv & bits) == 0" by doing an atomic update of "*pv" to
192 // "*pv & ~bits" if necessary.  Wait until (*pv & wait_until_clear)==0
193 // before making any change.
194 // This is used to unset flags in mutex and condition variable words.
AtomicClearBits(std::atomic<intptr_t> * pv,intptr_t bits,intptr_t wait_until_clear)195 static void AtomicClearBits(std::atomic<intptr_t>* pv, intptr_t bits,
196                             intptr_t wait_until_clear) {
197   intptr_t v;
198   do {
199     v = pv->load(std::memory_order_relaxed);
200   } while ((v & bits) != 0 &&
201            ((v & wait_until_clear) != 0 ||
202             !pv->compare_exchange_weak(v, v & ~bits,
203                                        std::memory_order_release,
204                                        std::memory_order_relaxed)));
205 }
206 
207 //------------------------------------------------------------------
208 
209 // Data for doing deadlock detection.
210 static absl::base_internal::SpinLock deadlock_graph_mu(
211     absl::base_internal::kLinkerInitialized);
212 
213 // graph used to detect deadlocks.
214 static GraphCycles *deadlock_graph ABSL_GUARDED_BY(deadlock_graph_mu)
215     ABSL_PT_GUARDED_BY(deadlock_graph_mu);
216 
217 //------------------------------------------------------------------
218 // An event mechanism for debugging mutex use.
219 // It also allows mutexes to be given names for those who can't handle
220 // addresses, and instead like to give their data structures names like
221 // "Henry", "Fido", or "Rupert IV, King of Yondavia".
222 
223 namespace {  // to prevent name pollution
224 enum {       // Mutex and CondVar events passed as "ev" to PostSynchEvent
225              // Mutex events
226   SYNCH_EV_TRYLOCK_SUCCESS,
227   SYNCH_EV_TRYLOCK_FAILED,
228   SYNCH_EV_READERTRYLOCK_SUCCESS,
229   SYNCH_EV_READERTRYLOCK_FAILED,
230   SYNCH_EV_LOCK,
231   SYNCH_EV_LOCK_RETURNING,
232   SYNCH_EV_READERLOCK,
233   SYNCH_EV_READERLOCK_RETURNING,
234   SYNCH_EV_UNLOCK,
235   SYNCH_EV_READERUNLOCK,
236 
237   // CondVar events
238   SYNCH_EV_WAIT,
239   SYNCH_EV_WAIT_RETURNING,
240   SYNCH_EV_SIGNAL,
241   SYNCH_EV_SIGNALALL,
242 };
243 
244 enum {                    // Event flags
245   SYNCH_F_R = 0x01,       // reader event
246   SYNCH_F_LCK = 0x02,     // PostSynchEvent called with mutex held
247   SYNCH_F_TRY = 0x04,     // TryLock or ReaderTryLock
248   SYNCH_F_UNLOCK = 0x08,  // Unlock or ReaderUnlock
249 
250   SYNCH_F_LCK_W = SYNCH_F_LCK,
251   SYNCH_F_LCK_R = SYNCH_F_LCK | SYNCH_F_R,
252 };
253 }  // anonymous namespace
254 
255 // Properties of the events.
256 static const struct {
257   int flags;
258   const char *msg;
259 } event_properties[] = {
260     {SYNCH_F_LCK_W | SYNCH_F_TRY, "TryLock succeeded "},
261     {0, "TryLock failed "},
262     {SYNCH_F_LCK_R | SYNCH_F_TRY, "ReaderTryLock succeeded "},
263     {0, "ReaderTryLock failed "},
264     {0, "Lock blocking "},
265     {SYNCH_F_LCK_W, "Lock returning "},
266     {0, "ReaderLock blocking "},
267     {SYNCH_F_LCK_R, "ReaderLock returning "},
268     {SYNCH_F_LCK_W | SYNCH_F_UNLOCK, "Unlock "},
269     {SYNCH_F_LCK_R | SYNCH_F_UNLOCK, "ReaderUnlock "},
270     {0, "Wait on "},
271     {0, "Wait unblocked "},
272     {0, "Signal on "},
273     {0, "SignalAll on "},
274 };
275 
276 static absl::base_internal::SpinLock synch_event_mu(
277     absl::base_internal::kLinkerInitialized);
278 // protects synch_event
279 
280 // Hash table size; should be prime > 2.
281 // Can't be too small, as it's used for deadlock detection information.
282 static const uint32_t kNSynchEvent = 1031;
283 
284 static struct SynchEvent {     // this is a trivial hash table for the events
285   // struct is freed when refcount reaches 0
286   int refcount ABSL_GUARDED_BY(synch_event_mu);
287 
288   // buckets have linear, 0-terminated  chains
289   SynchEvent *next ABSL_GUARDED_BY(synch_event_mu);
290 
291   // Constant after initialization
292   uintptr_t masked_addr;  // object at this address is called "name"
293 
294   // No explicit synchronization used.  Instead we assume that the
295   // client who enables/disables invariants/logging on a Mutex does so
296   // while the Mutex is not being concurrently accessed by others.
297   void (*invariant)(void *arg);  // called on each event
298   void *arg;            // first arg to (*invariant)()
299   bool log;             // logging turned on
300 
301   // Constant after initialization
302   char name[1];         // actually longer---NUL-terminated std::string
303 } * synch_event[kNSynchEvent] ABSL_GUARDED_BY(synch_event_mu);
304 
305 // Ensure that the object at "addr" has a SynchEvent struct associated with it,
306 // set "bits" in the word there (waiting until lockbit is clear before doing
307 // so), and return a refcounted reference that will remain valid until
308 // UnrefSynchEvent() is called.  If a new SynchEvent is allocated,
309 // the string name is copied into it.
310 // When used with a mutex, the caller should also ensure that kMuEvent
311 // is set in the mutex word, and similarly for condition variables and kCVEvent.
EnsureSynchEvent(std::atomic<intptr_t> * addr,const char * name,intptr_t bits,intptr_t lockbit)312 static SynchEvent *EnsureSynchEvent(std::atomic<intptr_t> *addr,
313                                     const char *name, intptr_t bits,
314                                     intptr_t lockbit) {
315   uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent;
316   SynchEvent *e;
317   // first look for existing SynchEvent struct..
318   synch_event_mu.Lock();
319   for (e = synch_event[h];
320        e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
321        e = e->next) {
322   }
323   if (e == nullptr) {  // no SynchEvent struct found; make one.
324     if (name == nullptr) {
325       name = "";
326     }
327     size_t l = strlen(name);
328     e = reinterpret_cast<SynchEvent *>(
329         base_internal::LowLevelAlloc::Alloc(sizeof(*e) + l));
330     e->refcount = 2;    // one for return value, one for linked list
331     e->masked_addr = base_internal::HidePtr(addr);
332     e->invariant = nullptr;
333     e->arg = nullptr;
334     e->log = false;
335     strcpy(e->name, name);  // NOLINT(runtime/printf)
336     e->next = synch_event[h];
337     AtomicSetBits(addr, bits, lockbit);
338     synch_event[h] = e;
339   } else {
340     e->refcount++;      // for return value
341   }
342   synch_event_mu.Unlock();
343   return e;
344 }
345 
346 // Deallocate the SynchEvent *e, whose refcount has fallen to zero.
DeleteSynchEvent(SynchEvent * e)347 static void DeleteSynchEvent(SynchEvent *e) {
348   base_internal::LowLevelAlloc::Free(e);
349 }
350 
351 // Decrement the reference count of *e, or do nothing if e==null.
UnrefSynchEvent(SynchEvent * e)352 static void UnrefSynchEvent(SynchEvent *e) {
353   if (e != nullptr) {
354     synch_event_mu.Lock();
355     bool del = (--(e->refcount) == 0);
356     synch_event_mu.Unlock();
357     if (del) {
358       DeleteSynchEvent(e);
359     }
360   }
361 }
362 
363 // Forget the mapping from the object (Mutex or CondVar) at address addr
364 // to SynchEvent object, and clear "bits" in its word (waiting until lockbit
365 // is clear before doing so).
ForgetSynchEvent(std::atomic<intptr_t> * addr,intptr_t bits,intptr_t lockbit)366 static void ForgetSynchEvent(std::atomic<intptr_t> *addr, intptr_t bits,
367                              intptr_t lockbit) {
368   uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent;
369   SynchEvent **pe;
370   SynchEvent *e;
371   synch_event_mu.Lock();
372   for (pe = &synch_event[h];
373        (e = *pe) != nullptr && e->masked_addr != base_internal::HidePtr(addr);
374        pe = &e->next) {
375   }
376   bool del = false;
377   if (e != nullptr) {
378     *pe = e->next;
379     del = (--(e->refcount) == 0);
380   }
381   AtomicClearBits(addr, bits, lockbit);
382   synch_event_mu.Unlock();
383   if (del) {
384     DeleteSynchEvent(e);
385   }
386 }
387 
388 // Return a refcounted reference to the SynchEvent of the object at address
389 // "addr", if any.  The pointer returned is valid until the UnrefSynchEvent() is
390 // called.
GetSynchEvent(const void * addr)391 static SynchEvent *GetSynchEvent(const void *addr) {
392   uint32_t h = reinterpret_cast<intptr_t>(addr) % kNSynchEvent;
393   SynchEvent *e;
394   synch_event_mu.Lock();
395   for (e = synch_event[h];
396        e != nullptr && e->masked_addr != base_internal::HidePtr(addr);
397        e = e->next) {
398   }
399   if (e != nullptr) {
400     e->refcount++;
401   }
402   synch_event_mu.Unlock();
403   return e;
404 }
405 
406 // Called when an event "ev" occurs on a Mutex of CondVar "obj"
407 // if event recording is on
PostSynchEvent(void * obj,int ev)408 static void PostSynchEvent(void *obj, int ev) {
409   SynchEvent *e = GetSynchEvent(obj);
410   // logging is on if event recording is on and either there's no event struct,
411   // or it explicitly says to log
412   if (e == nullptr || e->log) {
413     void *pcs[40];
414     int n = absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 1);
415     // A buffer with enough space for the ASCII for all the PCs, even on a
416     // 64-bit machine.
417     char buffer[ABSL_ARRAYSIZE(pcs) * 24];
418     int pos = snprintf(buffer, sizeof (buffer), " @");
419     for (int i = 0; i != n; i++) {
420       pos += snprintf(&buffer[pos], sizeof (buffer) - pos, " %p", pcs[i]);
421     }
422     ABSL_RAW_LOG(INFO, "%s%p %s %s", event_properties[ev].msg, obj,
423                  (e == nullptr ? "" : e->name), buffer);
424   }
425   const int flags = event_properties[ev].flags;
426   if ((flags & SYNCH_F_LCK) != 0 && e != nullptr && e->invariant != nullptr) {
427     // Calling the invariant as is causes problems under ThreadSanitizer.
428     // We are currently inside of Mutex Lock/Unlock and are ignoring all
429     // memory accesses and synchronization. If the invariant transitively
430     // synchronizes something else and we ignore the synchronization, we will
431     // get false positive race reports later.
432     // Reuse EvalConditionAnnotated to properly call into user code.
433     struct local {
434       static bool pred(SynchEvent *ev) {
435         (*ev->invariant)(ev->arg);
436         return false;
437       }
438     };
439     Condition cond(&local::pred, e);
440     Mutex *mu = static_cast<Mutex *>(obj);
441     const bool locking = (flags & SYNCH_F_UNLOCK) == 0;
442     const bool trylock = (flags & SYNCH_F_TRY) != 0;
443     const bool read_lock = (flags & SYNCH_F_R) != 0;
444     EvalConditionAnnotated(&cond, mu, locking, trylock, read_lock);
445   }
446   UnrefSynchEvent(e);
447 }
448 
449 //------------------------------------------------------------------
450 
451 // The SynchWaitParams struct encapsulates the way in which a thread is waiting:
452 // whether it has a timeout, the condition, exclusive/shared, and whether a
453 // condition variable wait has an associated Mutex (as opposed to another
454 // type of lock).  It also points to the PerThreadSynch struct of its thread.
455 // cv_word tells Enqueue() to enqueue on a CondVar using CondVarEnqueue().
456 //
457 // This structure is held on the stack rather than directly in
458 // PerThreadSynch because a thread can be waiting on multiple Mutexes if,
459 // while waiting on one Mutex, the implementation calls a client callback
460 // (such as a Condition function) that acquires another Mutex. We don't
461 // strictly need to allow this, but programmers become confused if we do not
462 // allow them to use functions such a LOG() within Condition functions.  The
463 // PerThreadSynch struct points at the most recent SynchWaitParams struct when
464 // the thread is on a Mutex's waiter queue.
465 struct SynchWaitParams {
SynchWaitParamsabsl::SynchWaitParams466   SynchWaitParams(Mutex::MuHow how_arg, const Condition *cond_arg,
467                   KernelTimeout timeout_arg, Mutex *cvmu_arg,
468                   PerThreadSynch *thread_arg,
469                   std::atomic<intptr_t> *cv_word_arg)
470       : how(how_arg),
471         cond(cond_arg),
472         timeout(timeout_arg),
473         cvmu(cvmu_arg),
474         thread(thread_arg),
475         cv_word(cv_word_arg),
476         contention_start_cycles(base_internal::CycleClock::Now()) {}
477 
478   const Mutex::MuHow how;  // How this thread needs to wait.
479   const Condition *cond;  // The condition that this thread is waiting for.
480                           // In Mutex, this field is set to zero if a timeout
481                           // expires.
482   KernelTimeout timeout;  // timeout expiry---absolute time
483                           // In Mutex, this field is set to zero if a timeout
484                           // expires.
485   Mutex *const cvmu;      // used for transfer from cond var to mutex
486   PerThreadSynch *const thread;  // thread that is waiting
487 
488   // If not null, thread should be enqueued on the CondVar whose state
489   // word is cv_word instead of queueing normally on the Mutex.
490   std::atomic<intptr_t> *cv_word;
491 
492   int64_t contention_start_cycles;  // Time (in cycles) when this thread started
493                                   // to contend for the mutex.
494 };
495 
496 struct SynchLocksHeld {
497   int n;              // number of valid entries in locks[]
498   bool overflow;      // true iff we overflowed the array at some point
499   struct {
500     Mutex *mu;        // lock acquired
501     int32_t count;      // times acquired
502     GraphId id;       // deadlock_graph id of acquired lock
503   } locks[40];
504   // If a thread overfills the array during deadlock detection, we
505   // continue, discarding information as needed.  If no overflow has
506   // taken place, we can provide more error checking, such as
507   // detecting when a thread releases a lock it does not hold.
508 };
509 
510 // A sentinel value in lists that is not 0.
511 // A 0 value is used to mean "not on a list".
512 static PerThreadSynch *const kPerThreadSynchNull =
513   reinterpret_cast<PerThreadSynch *>(1);
514 
LocksHeldAlloc()515 static SynchLocksHeld *LocksHeldAlloc() {
516   SynchLocksHeld *ret = reinterpret_cast<SynchLocksHeld *>(
517       base_internal::LowLevelAlloc::Alloc(sizeof(SynchLocksHeld)));
518   ret->n = 0;
519   ret->overflow = false;
520   return ret;
521 }
522 
523 // Return the PerThreadSynch-struct for this thread.
Synch_GetPerThread()524 static PerThreadSynch *Synch_GetPerThread() {
525   ThreadIdentity *identity = GetOrCreateCurrentThreadIdentity();
526   return &identity->per_thread_synch;
527 }
528 
Synch_GetPerThreadAnnotated(Mutex * mu)529 static PerThreadSynch *Synch_GetPerThreadAnnotated(Mutex *mu) {
530   if (mu) {
531     ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
532   }
533   PerThreadSynch *w = Synch_GetPerThread();
534   if (mu) {
535     ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
536   }
537   return w;
538 }
539 
Synch_GetAllLocks()540 static SynchLocksHeld *Synch_GetAllLocks() {
541   PerThreadSynch *s = Synch_GetPerThread();
542   if (s->all_locks == nullptr) {
543     s->all_locks = LocksHeldAlloc();  // Freed by ReclaimThreadIdentity.
544   }
545   return s->all_locks;
546 }
547 
548 // Post on "w"'s associated PerThreadSem.
IncrementSynchSem(Mutex * mu,PerThreadSynch * w)549 inline void Mutex::IncrementSynchSem(Mutex *mu, PerThreadSynch *w) {
550   if (mu) {
551     ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
552   }
553   PerThreadSem::Post(w->thread_identity());
554   if (mu) {
555     ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
556   }
557 }
558 
559 // Wait on "w"'s associated PerThreadSem; returns false if timeout expired.
DecrementSynchSem(Mutex * mu,PerThreadSynch * w,KernelTimeout t)560 bool Mutex::DecrementSynchSem(Mutex *mu, PerThreadSynch *w, KernelTimeout t) {
561   if (mu) {
562     ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
563   }
564   assert(w == Synch_GetPerThread());
565   static_cast<void>(w);
566   bool res = PerThreadSem::Wait(t);
567   if (mu) {
568     ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
569   }
570   return res;
571 }
572 
573 // We're in a fatal signal handler that hopes to use Mutex and to get
574 // lucky by not deadlocking.  We try to improve its chances of success
575 // by effectively disabling some of the consistency checks.  This will
576 // prevent certain ABSL_RAW_CHECK() statements from being triggered when
577 // re-rentry is detected.  The ABSL_RAW_CHECK() statements are those in the
578 // Mutex code checking that the "waitp" field has not been reused.
InternalAttemptToUseMutexInFatalSignalHandler()579 void Mutex::InternalAttemptToUseMutexInFatalSignalHandler() {
580   // Fix the per-thread state only if it exists.
581   ThreadIdentity *identity = CurrentThreadIdentityIfPresent();
582   if (identity != nullptr) {
583     identity->per_thread_synch.suppress_fatal_errors = true;
584   }
585   // Don't do deadlock detection when we are already failing.
586   synch_deadlock_detection.store(OnDeadlockCycle::kIgnore,
587                                  std::memory_order_release);
588 }
589 
590 // --------------------------time support
591 
592 // Return the current time plus the timeout.  Use the same clock as
593 // PerThreadSem::Wait() for consistency.  Unfortunately, we don't have
594 // such a choice when a deadline is given directly.
DeadlineFromTimeout(absl::Duration timeout)595 static absl::Time DeadlineFromTimeout(absl::Duration timeout) {
596 #ifndef _WIN32
597   struct timeval tv;
598   gettimeofday(&tv, nullptr);
599   return absl::TimeFromTimeval(tv) + timeout;
600 #else
601   return absl::Now() + timeout;
602 #endif
603 }
604 
605 // --------------------------Mutexes
606 
607 // In the layout below, the msb of the bottom byte is currently unused.  Also,
608 // the following constraints were considered in choosing the layout:
609 //  o Both the debug allocator's "uninitialized" and "freed" patterns (0xab and
610 //    0xcd) are illegal: reader and writer lock both held.
611 //  o kMuWriter and kMuEvent should exceed kMuDesig and kMuWait, to enable the
612 //    bit-twiddling trick in Mutex::Unlock().
613 //  o kMuWriter / kMuReader == kMuWrWait / kMuWait,
614 //    to enable the bit-twiddling trick in CheckForMutexCorruption().
615 static const intptr_t kMuReader      = 0x0001L;  // a reader holds the lock
616 static const intptr_t kMuDesig       = 0x0002L;  // there's a designated waker
617 static const intptr_t kMuWait        = 0x0004L;  // threads are waiting
618 static const intptr_t kMuWriter      = 0x0008L;  // a writer holds the lock
619 static const intptr_t kMuEvent       = 0x0010L;  // record this mutex's events
620 // INVARIANT1:  there's a thread that was blocked on the mutex, is
621 // no longer, yet has not yet acquired the mutex.  If there's a
622 // designated waker, all threads can avoid taking the slow path in
623 // unlock because the designated waker will subsequently acquire
624 // the lock and wake someone.  To maintain INVARIANT1 the bit is
625 // set when a thread is unblocked(INV1a), and threads that were
626 // unblocked reset the bit when they either acquire or re-block
627 // (INV1b).
628 static const intptr_t kMuWrWait      = 0x0020L;  // runnable writer is waiting
629                                                  // for a reader
630 static const intptr_t kMuSpin        = 0x0040L;  // spinlock protects wait list
631 static const intptr_t kMuLow         = 0x00ffL;  // mask all mutex bits
632 static const intptr_t kMuHigh        = ~kMuLow;  // mask pointer/reader count
633 
634 // Hack to make constant values available to gdb pretty printer
635 enum {
636   kGdbMuSpin = kMuSpin,
637   kGdbMuEvent = kMuEvent,
638   kGdbMuWait = kMuWait,
639   kGdbMuWriter = kMuWriter,
640   kGdbMuDesig = kMuDesig,
641   kGdbMuWrWait = kMuWrWait,
642   kGdbMuReader = kMuReader,
643   kGdbMuLow = kMuLow,
644 };
645 
646 // kMuWrWait implies kMuWait.
647 // kMuReader and kMuWriter are mutually exclusive.
648 // If kMuReader is zero, there are no readers.
649 // Otherwise, if kMuWait is zero, the high order bits contain a count of the
650 // number of readers.  Otherwise, the reader count is held in
651 // PerThreadSynch::readers of the most recently queued waiter, again in the
652 // bits above kMuLow.
653 static const intptr_t kMuOne = 0x0100;  // a count of one reader
654 
655 // flags passed to Enqueue and LockSlow{,WithTimeout,Loop}
656 static const int kMuHasBlocked = 0x01;  // already blocked (MUST == 1)
657 static const int kMuIsCond = 0x02;      // conditional waiter (CV or Condition)
658 
659 static_assert(PerThreadSynch::kAlignment > kMuLow,
660               "PerThreadSynch::kAlignment must be greater than kMuLow");
661 
662 // This struct contains various bitmasks to be used in
663 // acquiring and releasing a mutex in a particular mode.
664 struct MuHowS {
665   // if all the bits in fast_need_zero are zero, the lock can be acquired by
666   // adding fast_add and oring fast_or.  The bit kMuDesig should be reset iff
667   // this is the designated waker.
668   intptr_t fast_need_zero;
669   intptr_t fast_or;
670   intptr_t fast_add;
671 
672   intptr_t slow_need_zero;  // fast_need_zero with events (e.g. logging)
673 
674   intptr_t slow_inc_need_zero;  // if all the bits in slow_inc_need_zero are
675                                 // zero a reader can acquire a read share by
676                                 // setting the reader bit and incrementing
677                                 // the reader count (in last waiter since
678                                 // we're now slow-path).  kMuWrWait be may
679                                 // be ignored if we already waited once.
680 };
681 
682 static const MuHowS kSharedS = {
683     // shared or read lock
684     kMuWriter | kMuWait | kMuEvent,   // fast_need_zero
685     kMuReader,                        // fast_or
686     kMuOne,                           // fast_add
687     kMuWriter | kMuWait,              // slow_need_zero
688     kMuSpin | kMuWriter | kMuWrWait,  // slow_inc_need_zero
689 };
690 static const MuHowS kExclusiveS = {
691     // exclusive or write lock
692     kMuWriter | kMuReader | kMuEvent,  // fast_need_zero
693     kMuWriter,                         // fast_or
694     0,                                 // fast_add
695     kMuWriter | kMuReader,             // slow_need_zero
696     ~static_cast<intptr_t>(0),         // slow_inc_need_zero
697 };
698 static const Mutex::MuHow kShared = &kSharedS;        // shared lock
699 static const Mutex::MuHow kExclusive = &kExclusiveS;  // exclusive lock
700 
701 #ifdef NDEBUG
702 static constexpr bool kDebugMode = false;
703 #else
704 static constexpr bool kDebugMode = true;
705 #endif
706 
707 #ifdef THREAD_SANITIZER
TsanFlags(Mutex::MuHow how)708 static unsigned TsanFlags(Mutex::MuHow how) {
709   return how == kShared ? __tsan_mutex_read_lock : 0;
710 }
711 #endif
712 
DebugOnlyIsExiting()713 static bool DebugOnlyIsExiting() {
714   return false;
715 }
716 
~Mutex()717 Mutex::~Mutex() {
718   intptr_t v = mu_.load(std::memory_order_relaxed);
719   if ((v & kMuEvent) != 0 && !DebugOnlyIsExiting()) {
720     ForgetSynchEvent(&this->mu_, kMuEvent, kMuSpin);
721   }
722   if (kDebugMode) {
723     this->ForgetDeadlockInfo();
724   }
725   ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static);
726 }
727 
EnableDebugLog(const char * name)728 void Mutex::EnableDebugLog(const char *name) {
729   SynchEvent *e = EnsureSynchEvent(&this->mu_, name, kMuEvent, kMuSpin);
730   e->log = true;
731   UnrefSynchEvent(e);
732 }
733 
EnableMutexInvariantDebugging(bool enabled)734 void EnableMutexInvariantDebugging(bool enabled) {
735   synch_check_invariants.store(enabled, std::memory_order_release);
736 }
737 
EnableInvariantDebugging(void (* invariant)(void *),void * arg)738 void Mutex::EnableInvariantDebugging(void (*invariant)(void *),
739                                      void *arg) {
740   if (synch_check_invariants.load(std::memory_order_acquire) &&
741       invariant != nullptr) {
742     SynchEvent *e = EnsureSynchEvent(&this->mu_, nullptr, kMuEvent, kMuSpin);
743     e->invariant = invariant;
744     e->arg = arg;
745     UnrefSynchEvent(e);
746   }
747 }
748 
SetMutexDeadlockDetectionMode(OnDeadlockCycle mode)749 void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode) {
750   synch_deadlock_detection.store(mode, std::memory_order_release);
751 }
752 
753 // Return true iff threads x and y are waiting on the same condition for the
754 // same type of lock.  Requires that x and y be waiting on the same Mutex
755 // queue.
MuSameCondition(PerThreadSynch * x,PerThreadSynch * y)756 static bool MuSameCondition(PerThreadSynch *x, PerThreadSynch *y) {
757   return x->waitp->how == y->waitp->how &&
758          Condition::GuaranteedEqual(x->waitp->cond, y->waitp->cond);
759 }
760 
761 // Given the contents of a mutex word containing a PerThreadSynch pointer,
762 // return the pointer.
GetPerThreadSynch(intptr_t v)763 static inline PerThreadSynch *GetPerThreadSynch(intptr_t v) {
764   return reinterpret_cast<PerThreadSynch *>(v & kMuHigh);
765 }
766 
767 // The next several routines maintain the per-thread next and skip fields
768 // used in the Mutex waiter queue.
769 // The queue is a circular singly-linked list, of which the "head" is the
770 // last element, and head->next if the first element.
771 // The skip field has the invariant:
772 //   For thread x, x->skip is one of:
773 //     - invalid (iff x is not in a Mutex wait queue),
774 //     - null, or
775 //     - a pointer to a distinct thread waiting later in the same Mutex queue
776 //       such that all threads in [x, x->skip] have the same condition and
777 //       lock type (MuSameCondition() is true for all pairs in [x, x->skip]).
778 // In addition, if x->skip is  valid, (x->may_skip || x->skip == null)
779 //
780 // By the spec of MuSameCondition(), it is not necessary when removing the
781 // first runnable thread y from the front a Mutex queue to adjust the skip
782 // field of another thread x because if x->skip==y, x->skip must (have) become
783 // invalid before y is removed.  The function TryRemove can remove a specified
784 // thread from an arbitrary position in the queue whether runnable or not, so
785 // it fixes up skip fields that would otherwise be left dangling.
786 // The statement
787 //     if (x->may_skip && MuSameCondition(x, x->next)) { x->skip = x->next; }
788 // maintains the invariant provided x is not the last waiter in a Mutex queue
789 // The statement
790 //          if (x->skip != null) { x->skip = x->skip->skip; }
791 // maintains the invariant.
792 
793 // Returns the last thread y in a mutex waiter queue such that all threads in
794 // [x, y] inclusive share the same condition.  Sets skip fields of some threads
795 // in that range to optimize future evaluation of Skip() on x values in
796 // the range.  Requires thread x is in a mutex waiter queue.
797 // The locking is unusual.  Skip() is called under these conditions:
798 //   - spinlock is held in call from Enqueue(), with maybe_unlocking == false
799 //   - Mutex is held in call from UnlockSlow() by last unlocker, with
800 //     maybe_unlocking == true
801 //   - both Mutex and spinlock are held in call from DequeueAllWakeable() (from
802 //     UnlockSlow()) and TryRemove()
803 // These cases are mutually exclusive, so Skip() never runs concurrently
804 // with itself on the same Mutex.   The skip chain is used in these other places
805 // that cannot occur concurrently:
806 //   - FixSkip() (from TryRemove()) - spinlock and Mutex are held)
807 //   - Dequeue() (with spinlock and Mutex held)
808 //   - UnlockSlow() (with spinlock and Mutex held)
809 // A more complex case is Enqueue()
810 //   - Enqueue() (with spinlock held and maybe_unlocking == false)
811 //               This is the first case in which Skip is called, above.
812 //   - Enqueue() (without spinlock held; but queue is empty and being freshly
813 //                formed)
814 //   - Enqueue() (with spinlock held and maybe_unlocking == true)
815 // The first case has mutual exclusion, and the second isolation through
816 // working on an otherwise unreachable data structure.
817 // In the last case, Enqueue() is required to change no skip/next pointers
818 // except those in the added node and the former "head" node.  This implies
819 // that the new node is added after head, and so must be the new head or the
820 // new front of the queue.
Skip(PerThreadSynch * x)821 static PerThreadSynch *Skip(PerThreadSynch *x) {
822   PerThreadSynch *x0 = nullptr;
823   PerThreadSynch *x1 = x;
824   PerThreadSynch *x2 = x->skip;
825   if (x2 != nullptr) {
826     // Each iteration attempts to advance sequence (x0,x1,x2) to next sequence
827     // such that   x1 == x0->skip && x2 == x1->skip
828     while ((x0 = x1, x1 = x2, x2 = x2->skip) != nullptr) {
829       x0->skip = x2;      // short-circuit skip from x0 to x2
830     }
831     x->skip = x1;         // short-circuit skip from x to result
832   }
833   return x1;
834 }
835 
836 // "ancestor" appears before "to_be_removed" in the same Mutex waiter queue.
837 // The latter is going to be removed out of order, because of a timeout.
838 // Check whether "ancestor" has a skip field pointing to "to_be_removed",
839 // and fix it if it does.
FixSkip(PerThreadSynch * ancestor,PerThreadSynch * to_be_removed)840 static void FixSkip(PerThreadSynch *ancestor, PerThreadSynch *to_be_removed) {
841   if (ancestor->skip == to_be_removed) {  // ancestor->skip left dangling
842     if (to_be_removed->skip != nullptr) {
843       ancestor->skip = to_be_removed->skip;  // can skip past to_be_removed
844     } else if (ancestor->next != to_be_removed) {  // they are not adjacent
845       ancestor->skip = ancestor->next;             // can skip one past ancestor
846     } else {
847       ancestor->skip = nullptr;  // can't skip at all
848     }
849   }
850 }
851 
852 static void CondVarEnqueue(SynchWaitParams *waitp);
853 
854 // Enqueue thread "waitp->thread" on a waiter queue.
855 // Called with mutex spinlock held if head != nullptr
856 // If head==nullptr and waitp->cv_word==nullptr, then Enqueue() is
857 // idempotent; it alters no state associated with the existing (empty)
858 // queue.
859 //
860 // If waitp->cv_word == nullptr, queue the thread at either the front or
861 // the end (according to its priority) of the circular mutex waiter queue whose
862 // head is "head", and return the new head.  mu is the previous mutex state,
863 // which contains the reader count (perhaps adjusted for the operation in
864 // progress) if the list was empty and a read lock held, and the holder hint if
865 // the list was empty and a write lock held.  (flags & kMuIsCond) indicates
866 // whether this thread was transferred from a CondVar or is waiting for a
867 // non-trivial condition.  In this case, Enqueue() never returns nullptr
868 //
869 // If waitp->cv_word != nullptr, CondVarEnqueue() is called, and "head" is
870 // returned. This mechanism is used by CondVar to queue a thread on the
871 // condition variable queue instead of the mutex queue in implementing Wait().
872 // In this case, Enqueue() can return nullptr (if head==nullptr).
Enqueue(PerThreadSynch * head,SynchWaitParams * waitp,intptr_t mu,int flags)873 static PerThreadSynch *Enqueue(PerThreadSynch *head,
874                                SynchWaitParams *waitp, intptr_t mu, int flags) {
875   // If we have been given a cv_word, call CondVarEnqueue() and return
876   // the previous head of the Mutex waiter queue.
877   if (waitp->cv_word != nullptr) {
878     CondVarEnqueue(waitp);
879     return head;
880   }
881 
882   PerThreadSynch *s = waitp->thread;
883   ABSL_RAW_CHECK(
884       s->waitp == nullptr ||    // normal case
885           s->waitp == waitp ||  // Fer()---transfer from condition variable
886           s->suppress_fatal_errors,
887       "detected illegal recursion into Mutex code");
888   s->waitp = waitp;
889   s->skip = nullptr;             // maintain skip invariant (see above)
890   s->may_skip = true;            // always true on entering queue
891   s->wake = false;               // not being woken
892   s->cond_waiter = ((flags & kMuIsCond) != 0);
893   if (head == nullptr) {         // s is the only waiter
894     s->next = s;                 // it's the only entry in the cycle
895     s->readers = mu;             // reader count is from mu word
896     s->maybe_unlocking = false;  // no one is searching an empty list
897     head = s;                    // s is new head
898   } else {
899     PerThreadSynch *enqueue_after = nullptr;  // we'll put s after this element
900 #ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
901     int64_t now_cycles = base_internal::CycleClock::Now();
902     if (s->next_priority_read_cycles < now_cycles) {
903       // Every so often, update our idea of the thread's priority.
904       // pthread_getschedparam() is 5% of the block/wakeup time;
905       // base_internal::CycleClock::Now() is 0.5%.
906       int policy;
907       struct sched_param param;
908       const int err = pthread_getschedparam(pthread_self(), &policy, &param);
909       if (err != 0) {
910         ABSL_RAW_LOG(ERROR, "pthread_getschedparam failed: %d", err);
911       } else {
912         s->priority = param.sched_priority;
913         s->next_priority_read_cycles =
914             now_cycles +
915             static_cast<int64_t>(base_internal::CycleClock::Frequency());
916       }
917     }
918     if (s->priority > head->priority) {  // s's priority is above head's
919       // try to put s in priority-fifo order, or failing that at the front.
920       if (!head->maybe_unlocking) {
921         // No unlocker can be scanning the queue, so we can insert between
922         // skip-chains, and within a skip-chain if it has the same condition as
923         // s.  We insert in priority-fifo order, examining the end of every
924         // skip-chain, plus every element with the same condition as s.
925         PerThreadSynch *advance_to = head;    // next value of enqueue_after
926         PerThreadSynch *cur;                  // successor of enqueue_after
927         do {
928           enqueue_after = advance_to;
929           cur = enqueue_after->next;  // this advance ensures progress
930           advance_to = Skip(cur);   // normally, advance to end of skip chain
931                                     // (side-effect: optimizes skip chain)
932           if (advance_to != cur && s->priority > advance_to->priority &&
933               MuSameCondition(s, cur)) {
934             // but this skip chain is not a singleton, s has higher priority
935             // than its tail and has the same condition as the chain,
936             // so we can insert within the skip-chain
937             advance_to = cur;         // advance by just one
938           }
939         } while (s->priority <= advance_to->priority);
940               // termination guaranteed because s->priority > head->priority
941               // and head is the end of a skip chain
942       } else if (waitp->how == kExclusive &&
943                  Condition::GuaranteedEqual(waitp->cond, nullptr)) {
944         // An unlocker could be scanning the queue, but we know it will recheck
945         // the queue front for writers that have no condition, which is what s
946         // is, so an insert at front is safe.
947         enqueue_after = head;       // add after head, at front
948       }
949     }
950 #endif
951     if (enqueue_after != nullptr) {
952       s->next = enqueue_after->next;
953       enqueue_after->next = s;
954 
955       // enqueue_after can be: head, Skip(...), or cur.
956       // The first two imply enqueue_after->skip == nullptr, and
957       // the last is used only if MuSameCondition(s, cur).
958       // We require this because clearing enqueue_after->skip
959       // is impossible; enqueue_after's predecessors might also
960       // incorrectly skip over s if we were to allow other
961       // insertion points.
962       ABSL_RAW_CHECK(
963           enqueue_after->skip == nullptr || MuSameCondition(enqueue_after, s),
964           "Mutex Enqueue failure");
965 
966       if (enqueue_after != head && enqueue_after->may_skip &&
967           MuSameCondition(enqueue_after, enqueue_after->next)) {
968         // enqueue_after can skip to its new successor, s
969         enqueue_after->skip = enqueue_after->next;
970       }
971       if (MuSameCondition(s, s->next)) {  // s->may_skip is known to be true
972         s->skip = s->next;                // s may skip to its successor
973       }
974     } else {   // enqueue not done any other way, so
975                // we're inserting s at the back
976       // s will become new head; copy data from head into it
977       s->next = head->next;        // add s after head
978       head->next = s;
979       s->readers = head->readers;  // reader count is from previous head
980       s->maybe_unlocking = head->maybe_unlocking;  // same for unlock hint
981       if (head->may_skip && MuSameCondition(head, s)) {
982         // head now has successor; may skip
983         head->skip = s;
984       }
985       head = s;  // s is new head
986     }
987   }
988   s->state.store(PerThreadSynch::kQueued, std::memory_order_relaxed);
989   return head;
990 }
991 
992 // Dequeue the successor pw->next of thread pw from the Mutex waiter queue
993 // whose last element is head.  The new head element is returned, or null
994 // if the list is made empty.
995 // Dequeue is called with both spinlock and Mutex held.
Dequeue(PerThreadSynch * head,PerThreadSynch * pw)996 static PerThreadSynch *Dequeue(PerThreadSynch *head, PerThreadSynch *pw) {
997   PerThreadSynch *w = pw->next;
998   pw->next = w->next;         // snip w out of list
999   if (head == w) {            // we removed the head
1000     head = (pw == w) ? nullptr : pw;  // either emptied list, or pw is new head
1001   } else if (pw != head && MuSameCondition(pw, pw->next)) {
1002     // pw can skip to its new successor
1003     if (pw->next->skip !=
1004         nullptr) {  // either skip to its successors skip target
1005       pw->skip = pw->next->skip;
1006     } else {                   // or to pw's successor
1007       pw->skip = pw->next;
1008     }
1009   }
1010   return head;
1011 }
1012 
1013 // Traverse the elements [ pw->next, h] of the circular list whose last element
1014 // is head.
1015 // Remove all elements with wake==true and place them in the
1016 // singly-linked list wake_list in the order found.   Assumes that
1017 // there is only one such element if the element has how == kExclusive.
1018 // Return the new head.
DequeueAllWakeable(PerThreadSynch * head,PerThreadSynch * pw,PerThreadSynch ** wake_tail)1019 static PerThreadSynch *DequeueAllWakeable(PerThreadSynch *head,
1020                                           PerThreadSynch *pw,
1021                                           PerThreadSynch **wake_tail) {
1022   PerThreadSynch *orig_h = head;
1023   PerThreadSynch *w = pw->next;
1024   bool skipped = false;
1025   do {
1026     if (w->wake) {                    // remove this element
1027       ABSL_RAW_CHECK(pw->skip == nullptr, "bad skip in DequeueAllWakeable");
1028       // we're removing pw's successor so either pw->skip is zero or we should
1029       // already have removed pw since if pw->skip!=null, pw has the same
1030       // condition as w.
1031       head = Dequeue(head, pw);
1032       w->next = *wake_tail;           // keep list terminated
1033       *wake_tail = w;                 // add w to wake_list;
1034       wake_tail = &w->next;           // next addition to end
1035       if (w->waitp->how == kExclusive) {  // wake at most 1 writer
1036         break;
1037       }
1038     } else {                // not waking this one; skip
1039       pw = Skip(w);       // skip as much as possible
1040       skipped = true;
1041     }
1042     w = pw->next;
1043     // We want to stop processing after we've considered the original head,
1044     // orig_h.  We can't test for w==orig_h in the loop because w may skip over
1045     // it; we are guaranteed only that w's predecessor will not skip over
1046     // orig_h.  When we've considered orig_h, either we've processed it and
1047     // removed it (so orig_h != head), or we considered it and skipped it (so
1048     // skipped==true && pw == head because skipping from head always skips by
1049     // just one, leaving pw pointing at head).  So we want to
1050     // continue the loop with the negation of that expression.
1051   } while (orig_h == head && (pw != head || !skipped));
1052   return head;
1053 }
1054 
1055 // Try to remove thread s from the list of waiters on this mutex.
1056 // Does nothing if s is not on the waiter list.
TryRemove(PerThreadSynch * s)1057 void Mutex::TryRemove(PerThreadSynch *s) {
1058   intptr_t v = mu_.load(std::memory_order_relaxed);
1059   // acquire spinlock & lock
1060   if ((v & (kMuWait | kMuSpin | kMuWriter | kMuReader)) == kMuWait &&
1061       mu_.compare_exchange_strong(v, v | kMuSpin | kMuWriter,
1062                                   std::memory_order_acquire,
1063                                   std::memory_order_relaxed)) {
1064     PerThreadSynch *h = GetPerThreadSynch(v);
1065     if (h != nullptr) {
1066       PerThreadSynch *pw = h;   // pw is w's predecessor
1067       PerThreadSynch *w;
1068       if ((w = pw->next) != s) {  // search for thread,
1069         do {                      // processing at least one element
1070           if (!MuSameCondition(s, w)) {  // seeking different condition
1071             pw = Skip(w);                // so skip all that won't match
1072             // we don't have to worry about dangling skip fields
1073             // in the threads we skipped; none can point to s
1074             // because their condition differs from s
1075           } else {          // seeking same condition
1076             FixSkip(w, s);  // fix up any skip pointer from w to s
1077             pw = w;
1078           }
1079           // don't search further if we found the thread, or we're about to
1080           // process the first thread again.
1081         } while ((w = pw->next) != s && pw != h);
1082       }
1083       if (w == s) {                 // found thread; remove it
1084         // pw->skip may be non-zero here; the loop above ensured that
1085         // no ancestor of s can skip to s, so removal is safe anyway.
1086         h = Dequeue(h, pw);
1087         s->next = nullptr;
1088         s->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
1089       }
1090     }
1091     intptr_t nv;
1092     do {                        // release spinlock and lock
1093       v = mu_.load(std::memory_order_relaxed);
1094       nv = v & (kMuDesig | kMuEvent);
1095       if (h != nullptr) {
1096         nv |= kMuWait | reinterpret_cast<intptr_t>(h);
1097         h->readers = 0;            // we hold writer lock
1098         h->maybe_unlocking = false;  // finished unlocking
1099       }
1100     } while (!mu_.compare_exchange_weak(v, nv,
1101                                         std::memory_order_release,
1102                                         std::memory_order_relaxed));
1103   }
1104 }
1105 
1106 // Wait until thread "s", which must be the current thread, is removed from the
1107 // this mutex's waiter queue.  If "s->waitp->timeout" has a timeout, wake up
1108 // if the wait extends past the absolute time specified, even if "s" is still
1109 // on the mutex queue.  In this case, remove "s" from the queue and return
1110 // true, otherwise return false.
Block(PerThreadSynch * s)1111 ABSL_XRAY_LOG_ARGS(1) void Mutex::Block(PerThreadSynch *s) {
1112   while (s->state.load(std::memory_order_acquire) == PerThreadSynch::kQueued) {
1113     if (!DecrementSynchSem(this, s, s->waitp->timeout)) {
1114       // After a timeout, we go into a spin loop until we remove ourselves
1115       // from the queue, or someone else removes us.  We can't be sure to be
1116       // able to remove ourselves in a single lock acquisition because this
1117       // mutex may be held, and the holder has the right to read the centre
1118       // of the waiter queue without holding the spinlock.
1119       this->TryRemove(s);
1120       int c = 0;
1121       while (s->next != nullptr) {
1122         c = Delay(c, GENTLE);
1123         this->TryRemove(s);
1124       }
1125       if (kDebugMode) {
1126         // This ensures that we test the case that TryRemove() is called when s
1127         // is not on the queue.
1128         this->TryRemove(s);
1129       }
1130       s->waitp->timeout = KernelTimeout::Never();      // timeout is satisfied
1131       s->waitp->cond = nullptr;  // condition no longer relevant for wakeups
1132     }
1133   }
1134   ABSL_RAW_CHECK(s->waitp != nullptr || s->suppress_fatal_errors,
1135                  "detected illegal recursion in Mutex code");
1136   s->waitp = nullptr;
1137 }
1138 
1139 // Wake thread w, and return the next thread in the list.
Wakeup(PerThreadSynch * w)1140 PerThreadSynch *Mutex::Wakeup(PerThreadSynch *w) {
1141   PerThreadSynch *next = w->next;
1142   w->next = nullptr;
1143   w->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
1144   IncrementSynchSem(this, w);
1145 
1146   return next;
1147 }
1148 
GetGraphIdLocked(Mutex * mu)1149 static GraphId GetGraphIdLocked(Mutex *mu)
1150     ABSL_EXCLUSIVE_LOCKS_REQUIRED(deadlock_graph_mu) {
1151   if (!deadlock_graph) {  // (re)create the deadlock graph.
1152     deadlock_graph =
1153         new (base_internal::LowLevelAlloc::Alloc(sizeof(*deadlock_graph)))
1154             GraphCycles;
1155   }
1156   return deadlock_graph->GetId(mu);
1157 }
1158 
GetGraphId(Mutex * mu)1159 static GraphId GetGraphId(Mutex *mu) ABSL_LOCKS_EXCLUDED(deadlock_graph_mu) {
1160   deadlock_graph_mu.Lock();
1161   GraphId id = GetGraphIdLocked(mu);
1162   deadlock_graph_mu.Unlock();
1163   return id;
1164 }
1165 
1166 // Record a lock acquisition.  This is used in debug mode for deadlock
1167 // detection.  The held_locks pointer points to the relevant data
1168 // structure for each case.
LockEnter(Mutex * mu,GraphId id,SynchLocksHeld * held_locks)1169 static void LockEnter(Mutex* mu, GraphId id, SynchLocksHeld *held_locks) {
1170   int n = held_locks->n;
1171   int i = 0;
1172   while (i != n && held_locks->locks[i].id != id) {
1173     i++;
1174   }
1175   if (i == n) {
1176     if (n == ABSL_ARRAYSIZE(held_locks->locks)) {
1177       held_locks->overflow = true;  // lost some data
1178     } else {                        // we have room for lock
1179       held_locks->locks[i].mu = mu;
1180       held_locks->locks[i].count = 1;
1181       held_locks->locks[i].id = id;
1182       held_locks->n = n + 1;
1183     }
1184   } else {
1185     held_locks->locks[i].count++;
1186   }
1187 }
1188 
1189 // Record a lock release.  Each call to LockEnter(mu, id, x) should be
1190 // eventually followed by a call to LockLeave(mu, id, x) by the same thread.
1191 // It does not process the event if is not needed when deadlock detection is
1192 // disabled.
LockLeave(Mutex * mu,GraphId id,SynchLocksHeld * held_locks)1193 static void LockLeave(Mutex* mu, GraphId id, SynchLocksHeld *held_locks) {
1194   int n = held_locks->n;
1195   int i = 0;
1196   while (i != n && held_locks->locks[i].id != id) {
1197     i++;
1198   }
1199   if (i == n) {
1200     if (!held_locks->overflow) {
1201       // The deadlock id may have been reassigned after ForgetDeadlockInfo,
1202       // but in that case mu should still be present.
1203       i = 0;
1204       while (i != n && held_locks->locks[i].mu != mu) {
1205         i++;
1206       }
1207       if (i == n) {  // mu missing means releasing unheld lock
1208         SynchEvent *mu_events = GetSynchEvent(mu);
1209         ABSL_RAW_LOG(FATAL,
1210                      "thread releasing lock it does not hold: %p %s; "
1211                      ,
1212                      static_cast<void *>(mu),
1213                      mu_events == nullptr ? "" : mu_events->name);
1214       }
1215     }
1216   } else if (held_locks->locks[i].count == 1) {
1217     held_locks->n = n - 1;
1218     held_locks->locks[i] = held_locks->locks[n - 1];
1219     held_locks->locks[n - 1].id = InvalidGraphId();
1220     held_locks->locks[n - 1].mu =
1221         nullptr;  // clear mu to please the leak detector.
1222   } else {
1223     assert(held_locks->locks[i].count > 0);
1224     held_locks->locks[i].count--;
1225   }
1226 }
1227 
1228 // Call LockEnter() if in debug mode and deadlock detection is enabled.
DebugOnlyLockEnter(Mutex * mu)1229 static inline void DebugOnlyLockEnter(Mutex *mu) {
1230   if (kDebugMode) {
1231     if (synch_deadlock_detection.load(std::memory_order_acquire) !=
1232         OnDeadlockCycle::kIgnore) {
1233       LockEnter(mu, GetGraphId(mu), Synch_GetAllLocks());
1234     }
1235   }
1236 }
1237 
1238 // Call LockEnter() if in debug mode and deadlock detection is enabled.
DebugOnlyLockEnter(Mutex * mu,GraphId id)1239 static inline void DebugOnlyLockEnter(Mutex *mu, GraphId id) {
1240   if (kDebugMode) {
1241     if (synch_deadlock_detection.load(std::memory_order_acquire) !=
1242         OnDeadlockCycle::kIgnore) {
1243       LockEnter(mu, id, Synch_GetAllLocks());
1244     }
1245   }
1246 }
1247 
1248 // Call LockLeave() if in debug mode and deadlock detection is enabled.
DebugOnlyLockLeave(Mutex * mu)1249 static inline void DebugOnlyLockLeave(Mutex *mu) {
1250   if (kDebugMode) {
1251     if (synch_deadlock_detection.load(std::memory_order_acquire) !=
1252         OnDeadlockCycle::kIgnore) {
1253       LockLeave(mu, GetGraphId(mu), Synch_GetAllLocks());
1254     }
1255   }
1256 }
1257 
StackString(void ** pcs,int n,char * buf,int maxlen,bool symbolize)1258 static char *StackString(void **pcs, int n, char *buf, int maxlen,
1259                          bool symbolize) {
1260   static const int kSymLen = 200;
1261   char sym[kSymLen];
1262   int len = 0;
1263   for (int i = 0; i != n; i++) {
1264     if (symbolize) {
1265       if (!symbolizer(pcs[i], sym, kSymLen)) {
1266         sym[0] = '\0';
1267       }
1268       snprintf(buf + len, maxlen - len, "%s\t@ %p %s\n",
1269                (i == 0 ? "\n" : ""),
1270                pcs[i], sym);
1271     } else {
1272       snprintf(buf + len, maxlen - len, " %p", pcs[i]);
1273     }
1274     len += strlen(&buf[len]);
1275   }
1276   return buf;
1277 }
1278 
CurrentStackString(char * buf,int maxlen,bool symbolize)1279 static char *CurrentStackString(char *buf, int maxlen, bool symbolize) {
1280   void *pcs[40];
1281   return StackString(pcs, absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 2), buf,
1282                      maxlen, symbolize);
1283 }
1284 
1285 namespace {
1286 enum { kMaxDeadlockPathLen = 10 };  // maximum length of a deadlock cycle;
1287                                     // a path this long would be remarkable
1288 // Buffers required to report a deadlock.
1289 // We do not allocate them on stack to avoid large stack frame.
1290 struct DeadlockReportBuffers {
1291   char buf[6100];
1292   GraphId path[kMaxDeadlockPathLen];
1293 };
1294 
1295 struct ScopedDeadlockReportBuffers {
ScopedDeadlockReportBuffersabsl::__anon50fe7d610911::ScopedDeadlockReportBuffers1296   ScopedDeadlockReportBuffers() {
1297     b = reinterpret_cast<DeadlockReportBuffers *>(
1298         base_internal::LowLevelAlloc::Alloc(sizeof(*b)));
1299   }
~ScopedDeadlockReportBuffersabsl::__anon50fe7d610911::ScopedDeadlockReportBuffers1300   ~ScopedDeadlockReportBuffers() { base_internal::LowLevelAlloc::Free(b); }
1301   DeadlockReportBuffers *b;
1302 };
1303 
1304 // Helper to pass to GraphCycles::UpdateStackTrace.
GetStack(void ** stack,int max_depth)1305 int GetStack(void** stack, int max_depth) {
1306   return absl::GetStackTrace(stack, max_depth, 3);
1307 }
1308 }  // anonymous namespace
1309 
1310 // Called in debug mode when a thread is about to acquire a lock in a way that
1311 // may block.
DeadlockCheck(Mutex * mu)1312 static GraphId DeadlockCheck(Mutex *mu) {
1313   if (synch_deadlock_detection.load(std::memory_order_acquire) ==
1314       OnDeadlockCycle::kIgnore) {
1315     return InvalidGraphId();
1316   }
1317 
1318   SynchLocksHeld *all_locks = Synch_GetAllLocks();
1319 
1320   absl::base_internal::SpinLockHolder lock(&deadlock_graph_mu);
1321   const GraphId mu_id = GetGraphIdLocked(mu);
1322 
1323   if (all_locks->n == 0) {
1324     // There are no other locks held. Return now so that we don't need to
1325     // call GetSynchEvent(). This way we do not record the stack trace
1326     // for this Mutex. It's ok, since if this Mutex is involved in a deadlock,
1327     // it can't always be the first lock acquired by a thread.
1328     return mu_id;
1329   }
1330 
1331   // We prefer to keep stack traces that show a thread holding and acquiring
1332   // as many locks as possible.  This increases the chances that a given edge
1333   // in the acquires-before graph will be represented in the stack traces
1334   // recorded for the locks.
1335   deadlock_graph->UpdateStackTrace(mu_id, all_locks->n + 1, GetStack);
1336 
1337   // For each other mutex already held by this thread:
1338   for (int i = 0; i != all_locks->n; i++) {
1339     const GraphId other_node_id = all_locks->locks[i].id;
1340     const Mutex *other =
1341         static_cast<const Mutex *>(deadlock_graph->Ptr(other_node_id));
1342     if (other == nullptr) {
1343       // Ignore stale lock
1344       continue;
1345     }
1346 
1347     // Add the acquired-before edge to the graph.
1348     if (!deadlock_graph->InsertEdge(other_node_id, mu_id)) {
1349       ScopedDeadlockReportBuffers scoped_buffers;
1350       DeadlockReportBuffers *b = scoped_buffers.b;
1351       static int number_of_reported_deadlocks = 0;
1352       number_of_reported_deadlocks++;
1353       // Symbolize only 2 first deadlock report to avoid huge slowdowns.
1354       bool symbolize = number_of_reported_deadlocks <= 2;
1355       ABSL_RAW_LOG(ERROR, "Potential Mutex deadlock: %s",
1356                    CurrentStackString(b->buf, sizeof (b->buf), symbolize));
1357       int len = 0;
1358       for (int j = 0; j != all_locks->n; j++) {
1359         void* pr = deadlock_graph->Ptr(all_locks->locks[j].id);
1360         if (pr != nullptr) {
1361           snprintf(b->buf + len, sizeof (b->buf) - len, " %p", pr);
1362           len += static_cast<int>(strlen(&b->buf[len]));
1363         }
1364       }
1365       ABSL_RAW_LOG(ERROR, "Acquiring %p    Mutexes held: %s",
1366                    static_cast<void *>(mu), b->buf);
1367       ABSL_RAW_LOG(ERROR, "Cycle: ");
1368       int path_len = deadlock_graph->FindPath(
1369           mu_id, other_node_id, ABSL_ARRAYSIZE(b->path), b->path);
1370       for (int j = 0; j != path_len; j++) {
1371         GraphId id = b->path[j];
1372         Mutex *path_mu = static_cast<Mutex *>(deadlock_graph->Ptr(id));
1373         if (path_mu == nullptr) continue;
1374         void** stack;
1375         int depth = deadlock_graph->GetStackTrace(id, &stack);
1376         snprintf(b->buf, sizeof(b->buf),
1377                  "mutex@%p stack: ", static_cast<void *>(path_mu));
1378         StackString(stack, depth, b->buf + strlen(b->buf),
1379                     static_cast<int>(sizeof(b->buf) - strlen(b->buf)),
1380                     symbolize);
1381         ABSL_RAW_LOG(ERROR, "%s", b->buf);
1382       }
1383       if (synch_deadlock_detection.load(std::memory_order_acquire) ==
1384           OnDeadlockCycle::kAbort) {
1385         deadlock_graph_mu.Unlock();  // avoid deadlock in fatal sighandler
1386         ABSL_RAW_LOG(FATAL, "dying due to potential deadlock");
1387         return mu_id;
1388       }
1389       break;   // report at most one potential deadlock per acquisition
1390     }
1391   }
1392 
1393   return mu_id;
1394 }
1395 
1396 // Invoke DeadlockCheck() iff we're in debug mode and
1397 // deadlock checking has been enabled.
DebugOnlyDeadlockCheck(Mutex * mu)1398 static inline GraphId DebugOnlyDeadlockCheck(Mutex *mu) {
1399   if (kDebugMode && synch_deadlock_detection.load(std::memory_order_acquire) !=
1400                         OnDeadlockCycle::kIgnore) {
1401     return DeadlockCheck(mu);
1402   } else {
1403     return InvalidGraphId();
1404   }
1405 }
1406 
ForgetDeadlockInfo()1407 void Mutex::ForgetDeadlockInfo() {
1408   if (kDebugMode && synch_deadlock_detection.load(std::memory_order_acquire) !=
1409                         OnDeadlockCycle::kIgnore) {
1410     deadlock_graph_mu.Lock();
1411     if (deadlock_graph != nullptr) {
1412       deadlock_graph->RemoveNode(this);
1413     }
1414     deadlock_graph_mu.Unlock();
1415   }
1416 }
1417 
AssertNotHeld() const1418 void Mutex::AssertNotHeld() const {
1419   // We have the data to allow this check only if in debug mode and deadlock
1420   // detection is enabled.
1421   if (kDebugMode &&
1422       (mu_.load(std::memory_order_relaxed) & (kMuWriter | kMuReader)) != 0 &&
1423       synch_deadlock_detection.load(std::memory_order_acquire) !=
1424           OnDeadlockCycle::kIgnore) {
1425     GraphId id = GetGraphId(const_cast<Mutex *>(this));
1426     SynchLocksHeld *locks = Synch_GetAllLocks();
1427     for (int i = 0; i != locks->n; i++) {
1428       if (locks->locks[i].id == id) {
1429         SynchEvent *mu_events = GetSynchEvent(this);
1430         ABSL_RAW_LOG(FATAL, "thread should not hold mutex %p %s",
1431                      static_cast<const void *>(this),
1432                      (mu_events == nullptr ? "" : mu_events->name));
1433       }
1434     }
1435   }
1436 }
1437 
1438 // Attempt to acquire *mu, and return whether successful.  The implementation
1439 // may spin for a short while if the lock cannot be acquired immediately.
TryAcquireWithSpinning(std::atomic<intptr_t> * mu)1440 static bool TryAcquireWithSpinning(std::atomic<intptr_t>* mu) {
1441   int c = mutex_globals.spinloop_iterations;
1442   int result = -1;  // result of operation:  0=false, 1=true, -1=unknown
1443 
1444   do {  // do/while somewhat faster on AMD
1445     intptr_t v = mu->load(std::memory_order_relaxed);
1446     if ((v & (kMuReader|kMuEvent)) != 0) {  // a reader or tracing -> give up
1447       result = 0;
1448     } else if (((v & kMuWriter) == 0) &&  // no holder -> try to acquire
1449                mu->compare_exchange_strong(v, kMuWriter | v,
1450                                            std::memory_order_acquire,
1451                                            std::memory_order_relaxed)) {
1452       result = 1;
1453     }
1454   } while (result == -1 && --c > 0);
1455   return result == 1;
1456 }
1457 
Lock()1458 ABSL_XRAY_LOG_ARGS(1) void Mutex::Lock() {
1459   ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
1460   GraphId id = DebugOnlyDeadlockCheck(this);
1461   intptr_t v = mu_.load(std::memory_order_relaxed);
1462   // try fast acquire, then spin loop
1463   if ((v & (kMuWriter | kMuReader | kMuEvent)) != 0 ||
1464       !mu_.compare_exchange_strong(v, kMuWriter | v,
1465                                    std::memory_order_acquire,
1466                                    std::memory_order_relaxed)) {
1467     // try spin acquire, then slow loop
1468     if (!TryAcquireWithSpinning(&this->mu_)) {
1469       this->LockSlow(kExclusive, nullptr, 0);
1470     }
1471   }
1472   DebugOnlyLockEnter(this, id);
1473   ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
1474 }
1475 
ReaderLock()1476 ABSL_XRAY_LOG_ARGS(1) void Mutex::ReaderLock() {
1477   ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
1478   GraphId id = DebugOnlyDeadlockCheck(this);
1479   intptr_t v = mu_.load(std::memory_order_relaxed);
1480   // try fast acquire, then slow loop
1481   if ((v & (kMuWriter | kMuWait | kMuEvent)) != 0 ||
1482       !mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
1483                                    std::memory_order_acquire,
1484                                    std::memory_order_relaxed)) {
1485     this->LockSlow(kShared, nullptr, 0);
1486   }
1487   DebugOnlyLockEnter(this, id);
1488   ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
1489 }
1490 
LockWhen(const Condition & cond)1491 void Mutex::LockWhen(const Condition &cond) {
1492   ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
1493   GraphId id = DebugOnlyDeadlockCheck(this);
1494   this->LockSlow(kExclusive, &cond, 0);
1495   DebugOnlyLockEnter(this, id);
1496   ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
1497 }
1498 
LockWhenWithTimeout(const Condition & cond,absl::Duration timeout)1499 bool Mutex::LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) {
1500   return LockWhenWithDeadline(cond, DeadlineFromTimeout(timeout));
1501 }
1502 
LockWhenWithDeadline(const Condition & cond,absl::Time deadline)1503 bool Mutex::LockWhenWithDeadline(const Condition &cond, absl::Time deadline) {
1504   ABSL_TSAN_MUTEX_PRE_LOCK(this, 0);
1505   GraphId id = DebugOnlyDeadlockCheck(this);
1506   bool res = LockSlowWithDeadline(kExclusive, &cond,
1507                                   KernelTimeout(deadline), 0);
1508   DebugOnlyLockEnter(this, id);
1509   ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0);
1510   return res;
1511 }
1512 
ReaderLockWhen(const Condition & cond)1513 void Mutex::ReaderLockWhen(const Condition &cond) {
1514   ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
1515   GraphId id = DebugOnlyDeadlockCheck(this);
1516   this->LockSlow(kShared, &cond, 0);
1517   DebugOnlyLockEnter(this, id);
1518   ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
1519 }
1520 
ReaderLockWhenWithTimeout(const Condition & cond,absl::Duration timeout)1521 bool Mutex::ReaderLockWhenWithTimeout(const Condition &cond,
1522                                       absl::Duration timeout) {
1523   return ReaderLockWhenWithDeadline(cond, DeadlineFromTimeout(timeout));
1524 }
1525 
ReaderLockWhenWithDeadline(const Condition & cond,absl::Time deadline)1526 bool Mutex::ReaderLockWhenWithDeadline(const Condition &cond,
1527                                        absl::Time deadline) {
1528   ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_read_lock);
1529   GraphId id = DebugOnlyDeadlockCheck(this);
1530   bool res = LockSlowWithDeadline(kShared, &cond, KernelTimeout(deadline), 0);
1531   DebugOnlyLockEnter(this, id);
1532   ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_read_lock, 0);
1533   return res;
1534 }
1535 
Await(const Condition & cond)1536 void Mutex::Await(const Condition &cond) {
1537   if (cond.Eval()) {    // condition already true; nothing to do
1538     if (kDebugMode) {
1539       this->AssertReaderHeld();
1540     }
1541   } else {              // normal case
1542     ABSL_RAW_CHECK(this->AwaitCommon(cond, KernelTimeout::Never()),
1543                    "condition untrue on return from Await");
1544   }
1545 }
1546 
AwaitWithTimeout(const Condition & cond,absl::Duration timeout)1547 bool Mutex::AwaitWithTimeout(const Condition &cond, absl::Duration timeout) {
1548   return AwaitWithDeadline(cond, DeadlineFromTimeout(timeout));
1549 }
1550 
AwaitWithDeadline(const Condition & cond,absl::Time deadline)1551 bool Mutex::AwaitWithDeadline(const Condition &cond, absl::Time deadline) {
1552   if (cond.Eval()) {      // condition already true; nothing to do
1553     if (kDebugMode) {
1554       this->AssertReaderHeld();
1555     }
1556     return true;
1557   }
1558 
1559   KernelTimeout t{deadline};
1560   bool res = this->AwaitCommon(cond, t);
1561   ABSL_RAW_CHECK(res || t.has_timeout(),
1562                  "condition untrue on return from Await");
1563   return res;
1564 }
1565 
AwaitCommon(const Condition & cond,KernelTimeout t)1566 bool Mutex::AwaitCommon(const Condition &cond, KernelTimeout t) {
1567   this->AssertReaderHeld();
1568   MuHow how =
1569       (mu_.load(std::memory_order_relaxed) & kMuWriter) ? kExclusive : kShared;
1570   ABSL_TSAN_MUTEX_PRE_UNLOCK(this, TsanFlags(how));
1571   SynchWaitParams waitp(
1572       how, &cond, t, nullptr /*no cvmu*/, Synch_GetPerThreadAnnotated(this),
1573       nullptr /*no cv_word*/);
1574   int flags = kMuHasBlocked;
1575   if (!Condition::GuaranteedEqual(&cond, nullptr)) {
1576     flags |= kMuIsCond;
1577   }
1578   this->UnlockSlow(&waitp);
1579   this->Block(waitp.thread);
1580   ABSL_TSAN_MUTEX_POST_UNLOCK(this, TsanFlags(how));
1581   ABSL_TSAN_MUTEX_PRE_LOCK(this, TsanFlags(how));
1582   this->LockSlowLoop(&waitp, flags);
1583   bool res = waitp.cond != nullptr ||  // => cond known true from LockSlowLoop
1584              EvalConditionAnnotated(&cond, this, true, false, how == kShared);
1585   ABSL_TSAN_MUTEX_POST_LOCK(this, TsanFlags(how), 0);
1586   return res;
1587 }
1588 
TryLock()1589 ABSL_XRAY_LOG_ARGS(1) bool Mutex::TryLock() {
1590   ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock);
1591   intptr_t v = mu_.load(std::memory_order_relaxed);
1592   if ((v & (kMuWriter | kMuReader | kMuEvent)) == 0 &&  // try fast acquire
1593       mu_.compare_exchange_strong(v, kMuWriter | v,
1594                                   std::memory_order_acquire,
1595                                   std::memory_order_relaxed)) {
1596     DebugOnlyLockEnter(this);
1597     ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0);
1598     return true;
1599   }
1600   if ((v & kMuEvent) != 0) {              // we're recording events
1601     if ((v & kExclusive->slow_need_zero) == 0 &&  // try fast acquire
1602         mu_.compare_exchange_strong(
1603             v, (kExclusive->fast_or | v) + kExclusive->fast_add,
1604             std::memory_order_acquire, std::memory_order_relaxed)) {
1605       DebugOnlyLockEnter(this);
1606       PostSynchEvent(this, SYNCH_EV_TRYLOCK_SUCCESS);
1607       ABSL_TSAN_MUTEX_POST_LOCK(this, __tsan_mutex_try_lock, 0);
1608       return true;
1609     } else {
1610       PostSynchEvent(this, SYNCH_EV_TRYLOCK_FAILED);
1611     }
1612   }
1613   ABSL_TSAN_MUTEX_POST_LOCK(
1614       this, __tsan_mutex_try_lock | __tsan_mutex_try_lock_failed, 0);
1615   return false;
1616 }
1617 
ReaderTryLock()1618 ABSL_XRAY_LOG_ARGS(1) bool Mutex::ReaderTryLock() {
1619   ABSL_TSAN_MUTEX_PRE_LOCK(this,
1620                            __tsan_mutex_read_lock | __tsan_mutex_try_lock);
1621   intptr_t v = mu_.load(std::memory_order_relaxed);
1622   // The while-loops (here and below) iterate only if the mutex word keeps
1623   // changing (typically because the reader count changes) under the CAS.  We
1624   // limit the number of attempts to avoid having to think about livelock.
1625   int loop_limit = 5;
1626   while ((v & (kMuWriter|kMuWait|kMuEvent)) == 0 && loop_limit != 0) {
1627     if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
1628                                     std::memory_order_acquire,
1629                                     std::memory_order_relaxed)) {
1630       DebugOnlyLockEnter(this);
1631       ABSL_TSAN_MUTEX_POST_LOCK(
1632           this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0);
1633       return true;
1634     }
1635     loop_limit--;
1636     v = mu_.load(std::memory_order_relaxed);
1637   }
1638   if ((v & kMuEvent) != 0) {   // we're recording events
1639     loop_limit = 5;
1640     while ((v & kShared->slow_need_zero) == 0 && loop_limit != 0) {
1641       if (mu_.compare_exchange_strong(v, (kMuReader | v) + kMuOne,
1642                                       std::memory_order_acquire,
1643                                       std::memory_order_relaxed)) {
1644         DebugOnlyLockEnter(this);
1645         PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_SUCCESS);
1646         ABSL_TSAN_MUTEX_POST_LOCK(
1647             this, __tsan_mutex_read_lock | __tsan_mutex_try_lock, 0);
1648         return true;
1649       }
1650       loop_limit--;
1651       v = mu_.load(std::memory_order_relaxed);
1652     }
1653     if ((v & kMuEvent) != 0) {
1654       PostSynchEvent(this, SYNCH_EV_READERTRYLOCK_FAILED);
1655     }
1656   }
1657   ABSL_TSAN_MUTEX_POST_LOCK(this,
1658                             __tsan_mutex_read_lock | __tsan_mutex_try_lock |
1659                                 __tsan_mutex_try_lock_failed,
1660                             0);
1661   return false;
1662 }
1663 
Unlock()1664 ABSL_XRAY_LOG_ARGS(1) void Mutex::Unlock() {
1665   ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0);
1666   DebugOnlyLockLeave(this);
1667   intptr_t v = mu_.load(std::memory_order_relaxed);
1668 
1669   if (kDebugMode && ((v & (kMuWriter | kMuReader)) != kMuWriter)) {
1670     ABSL_RAW_LOG(FATAL, "Mutex unlocked when destroyed or not locked: v=0x%x",
1671                  static_cast<unsigned>(v));
1672   }
1673 
1674   // should_try_cas is whether we'll try a compare-and-swap immediately.
1675   // NOTE: optimized out when kDebugMode is false.
1676   bool should_try_cas = ((v & (kMuEvent | kMuWriter)) == kMuWriter &&
1677                           (v & (kMuWait | kMuDesig)) != kMuWait);
1678   // But, we can use an alternate computation of it, that compilers
1679   // currently don't find on their own.  When that changes, this function
1680   // can be simplified.
1681   intptr_t x = (v ^ (kMuWriter | kMuWait)) & (kMuWriter | kMuEvent);
1682   intptr_t y = (v ^ (kMuWriter | kMuWait)) & (kMuWait | kMuDesig);
1683   // Claim: "x == 0 && y > 0" is equal to should_try_cas.
1684   // Also, because kMuWriter and kMuEvent exceed kMuDesig and kMuWait,
1685   // all possible non-zero values for x exceed all possible values for y.
1686   // Therefore, (x == 0 && y > 0) == (x < y).
1687   if (kDebugMode && should_try_cas != (x < y)) {
1688     // We would usually use PRIdPTR here, but is not correctly implemented
1689     // within the android toolchain.
1690     ABSL_RAW_LOG(FATAL, "internal logic error %llx %llx %llx\n",
1691                  static_cast<long long>(v), static_cast<long long>(x),
1692                  static_cast<long long>(y));
1693   }
1694   if (x < y &&
1695       mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter),
1696                                   std::memory_order_release,
1697                                   std::memory_order_relaxed)) {
1698     // fast writer release (writer with no waiters or with designated waker)
1699   } else {
1700     this->UnlockSlow(nullptr /*no waitp*/);  // take slow path
1701   }
1702   ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0);
1703 }
1704 
1705 // Requires v to represent a reader-locked state.
ExactlyOneReader(intptr_t v)1706 static bool ExactlyOneReader(intptr_t v) {
1707   assert((v & (kMuWriter|kMuReader)) == kMuReader);
1708   assert((v & kMuHigh) != 0);
1709   // The more straightforward "(v & kMuHigh) == kMuOne" also works, but
1710   // on some architectures the following generates slightly smaller code.
1711   // It may be faster too.
1712   constexpr intptr_t kMuMultipleWaitersMask = kMuHigh ^ kMuOne;
1713   return (v & kMuMultipleWaitersMask) == 0;
1714 }
1715 
ReaderUnlock()1716 ABSL_XRAY_LOG_ARGS(1) void Mutex::ReaderUnlock() {
1717   ABSL_TSAN_MUTEX_PRE_UNLOCK(this, __tsan_mutex_read_lock);
1718   DebugOnlyLockLeave(this);
1719   intptr_t v = mu_.load(std::memory_order_relaxed);
1720   assert((v & (kMuWriter|kMuReader)) == kMuReader);
1721   if ((v & (kMuReader|kMuWait|kMuEvent)) == kMuReader) {
1722     // fast reader release (reader with no waiters)
1723     intptr_t clear = ExactlyOneReader(v) ? kMuReader|kMuOne : kMuOne;
1724     if (mu_.compare_exchange_strong(v, v - clear,
1725                                     std::memory_order_release,
1726                                     std::memory_order_relaxed)) {
1727       ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock);
1728       return;
1729     }
1730   }
1731   this->UnlockSlow(nullptr /*no waitp*/);  // take slow path
1732   ABSL_TSAN_MUTEX_POST_UNLOCK(this, __tsan_mutex_read_lock);
1733 }
1734 
1735 // The zap_desig_waker bitmask is used to clear the designated waker flag in
1736 // the mutex if this thread has blocked, and therefore may be the designated
1737 // waker.
1738 static const intptr_t zap_desig_waker[] = {
1739     ~static_cast<intptr_t>(0),  // not blocked
1740     ~static_cast<intptr_t>(
1741         kMuDesig)  // blocked; turn off the designated waker bit
1742 };
1743 
1744 // The ignore_waiting_writers bitmask is used to ignore the existence
1745 // of waiting writers if a reader that has already blocked once
1746 // wakes up.
1747 static const intptr_t ignore_waiting_writers[] = {
1748     ~static_cast<intptr_t>(0),  // not blocked
1749     ~static_cast<intptr_t>(
1750         kMuWrWait)  // blocked; pretend there are no waiting writers
1751 };
1752 
1753 // Internal version of LockWhen().  See LockSlowWithDeadline()
LockSlow(MuHow how,const Condition * cond,int flags)1754 void Mutex::LockSlow(MuHow how, const Condition *cond, int flags) {
1755   ABSL_RAW_CHECK(
1756       this->LockSlowWithDeadline(how, cond, KernelTimeout::Never(), flags),
1757       "condition untrue on return from LockSlow");
1758 }
1759 
1760 // Compute cond->Eval() and tell race detectors that we do it under mutex mu.
EvalConditionAnnotated(const Condition * cond,Mutex * mu,bool locking,bool trylock,bool read_lock)1761 static inline bool EvalConditionAnnotated(const Condition *cond, Mutex *mu,
1762                                           bool locking, bool trylock,
1763                                           bool read_lock) {
1764   // Delicate annotation dance.
1765   // We are currently inside of read/write lock/unlock operation.
1766   // All memory accesses are ignored inside of mutex operations + for unlock
1767   // operation tsan considers that we've already released the mutex.
1768   bool res = false;
1769 #ifdef THREAD_SANITIZER
1770   const int flags = read_lock ? __tsan_mutex_read_lock : 0;
1771   const int tryflags = flags | (trylock ? __tsan_mutex_try_lock : 0);
1772 #endif
1773   if (locking) {
1774     // For lock we pretend that we have finished the operation,
1775     // evaluate the predicate, then unlock the mutex and start locking it again
1776     // to match the annotation at the end of outer lock operation.
1777     // Note: we can't simply do POST_LOCK, Eval, PRE_LOCK, because then tsan
1778     // will think the lock acquisition is recursive which will trigger
1779     // deadlock detector.
1780     ABSL_TSAN_MUTEX_POST_LOCK(mu, tryflags, 0);
1781     res = cond->Eval();
1782     // There is no "try" version of Unlock, so use flags instead of tryflags.
1783     ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, flags);
1784     ABSL_TSAN_MUTEX_POST_UNLOCK(mu, flags);
1785     ABSL_TSAN_MUTEX_PRE_LOCK(mu, tryflags);
1786   } else {
1787     // Similarly, for unlock we pretend that we have unlocked the mutex,
1788     // lock the mutex, evaluate the predicate, and start unlocking it again
1789     // to match the annotation at the end of outer unlock operation.
1790     ABSL_TSAN_MUTEX_POST_UNLOCK(mu, flags);
1791     ABSL_TSAN_MUTEX_PRE_LOCK(mu, flags);
1792     ABSL_TSAN_MUTEX_POST_LOCK(mu, flags, 0);
1793     res = cond->Eval();
1794     ABSL_TSAN_MUTEX_PRE_UNLOCK(mu, flags);
1795   }
1796   // Prevent unused param warnings in non-TSAN builds.
1797   static_cast<void>(mu);
1798   static_cast<void>(trylock);
1799   static_cast<void>(read_lock);
1800   return res;
1801 }
1802 
1803 // Compute cond->Eval() hiding it from race detectors.
1804 // We are hiding it because inside of UnlockSlow we can evaluate a predicate
1805 // that was just added by a concurrent Lock operation; Lock adds the predicate
1806 // to the internal Mutex list without actually acquiring the Mutex
1807 // (it only acquires the internal spinlock, which is rightfully invisible for
1808 // tsan). As the result there is no tsan-visible synchronization between the
1809 // addition and this thread. So if we would enable race detection here,
1810 // it would race with the predicate initialization.
EvalConditionIgnored(Mutex * mu,const Condition * cond)1811 static inline bool EvalConditionIgnored(Mutex *mu, const Condition *cond) {
1812   // Memory accesses are already ignored inside of lock/unlock operations,
1813   // but synchronization operations are also ignored. When we evaluate the
1814   // predicate we must ignore only memory accesses but not synchronization,
1815   // because missed synchronization can lead to false reports later.
1816   // So we "divert" (which un-ignores both memory accesses and synchronization)
1817   // and then separately turn on ignores of memory accesses.
1818   ABSL_TSAN_MUTEX_PRE_DIVERT(mu, 0);
1819   ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
1820   bool res = cond->Eval();
1821   ANNOTATE_IGNORE_READS_AND_WRITES_END();
1822   ABSL_TSAN_MUTEX_POST_DIVERT(mu, 0);
1823   static_cast<void>(mu);  // Prevent unused param warning in non-TSAN builds.
1824   return res;
1825 }
1826 
1827 // Internal equivalent of *LockWhenWithDeadline(), where
1828 //   "t" represents the absolute timeout; !t.has_timeout() means "forever".
1829 //   "how" is "kShared" (for ReaderLockWhen) or "kExclusive" (for LockWhen)
1830 // In flags, bits are ored together:
1831 // - kMuHasBlocked indicates that the client has already blocked on the call so
1832 //   the designated waker bit must be cleared and waiting writers should not
1833 //   obstruct this call
1834 // - kMuIsCond indicates that this is a conditional acquire (condition variable,
1835 //   Await,  LockWhen) so contention profiling should be suppressed.
LockSlowWithDeadline(MuHow how,const Condition * cond,KernelTimeout t,int flags)1836 bool Mutex::LockSlowWithDeadline(MuHow how, const Condition *cond,
1837                                  KernelTimeout t, int flags) {
1838   intptr_t v = mu_.load(std::memory_order_relaxed);
1839   bool unlock = false;
1840   if ((v & how->fast_need_zero) == 0 &&  // try fast acquire
1841       mu_.compare_exchange_strong(
1842           v, (how->fast_or | (v & zap_desig_waker[flags & kMuHasBlocked])) +
1843                  how->fast_add,
1844           std::memory_order_acquire, std::memory_order_relaxed)) {
1845     if (cond == nullptr ||
1846         EvalConditionAnnotated(cond, this, true, false, how == kShared)) {
1847       return true;
1848     }
1849     unlock = true;
1850   }
1851   SynchWaitParams waitp(
1852       how, cond, t, nullptr /*no cvmu*/, Synch_GetPerThreadAnnotated(this),
1853       nullptr /*no cv_word*/);
1854   if (!Condition::GuaranteedEqual(cond, nullptr)) {
1855     flags |= kMuIsCond;
1856   }
1857   if (unlock) {
1858     this->UnlockSlow(&waitp);
1859     this->Block(waitp.thread);
1860     flags |= kMuHasBlocked;
1861   }
1862   this->LockSlowLoop(&waitp, flags);
1863   return waitp.cond != nullptr ||  // => cond known true from LockSlowLoop
1864          cond == nullptr ||
1865          EvalConditionAnnotated(cond, this, true, false, how == kShared);
1866 }
1867 
1868 // RAW_CHECK_FMT() takes a condition, a printf-style format string, and
1869 // the printf-style argument list.   The format string must be a literal.
1870 // Arguments after the first are not evaluated unless the condition is true.
1871 #define RAW_CHECK_FMT(cond, ...)                                   \
1872   do {                                                             \
1873     if (ABSL_PREDICT_FALSE(!(cond))) {                             \
1874       ABSL_RAW_LOG(FATAL, "Check " #cond " failed: " __VA_ARGS__); \
1875     }                                                              \
1876   } while (0)
1877 
CheckForMutexCorruption(intptr_t v,const char * label)1878 static void CheckForMutexCorruption(intptr_t v, const char* label) {
1879   // Test for either of two situations that should not occur in v:
1880   //   kMuWriter and kMuReader
1881   //   kMuWrWait and !kMuWait
1882   const uintptr_t w = v ^ kMuWait;
1883   // By flipping that bit, we can now test for:
1884   //   kMuWriter and kMuReader in w
1885   //   kMuWrWait and kMuWait in w
1886   // We've chosen these two pairs of values to be so that they will overlap,
1887   // respectively, when the word is left shifted by three.  This allows us to
1888   // save a branch in the common (correct) case of them not being coincident.
1889   static_assert(kMuReader << 3 == kMuWriter, "must match");
1890   static_assert(kMuWait << 3 == kMuWrWait, "must match");
1891   if (ABSL_PREDICT_TRUE((w & (w << 3) & (kMuWriter | kMuWrWait)) == 0)) return;
1892   RAW_CHECK_FMT((v & (kMuWriter | kMuReader)) != (kMuWriter | kMuReader),
1893                 "%s: Mutex corrupt: both reader and writer lock held: %p",
1894                 label, reinterpret_cast<void *>(v));
1895   RAW_CHECK_FMT((v & (kMuWait | kMuWrWait)) != kMuWrWait,
1896                 "%s: Mutex corrupt: waiting writer with no waiters: %p",
1897                 label, reinterpret_cast<void *>(v));
1898   assert(false);
1899 }
1900 
LockSlowLoop(SynchWaitParams * waitp,int flags)1901 void Mutex::LockSlowLoop(SynchWaitParams *waitp, int flags) {
1902   int c = 0;
1903   intptr_t v = mu_.load(std::memory_order_relaxed);
1904   if ((v & kMuEvent) != 0) {
1905     PostSynchEvent(this,
1906          waitp->how == kExclusive?  SYNCH_EV_LOCK: SYNCH_EV_READERLOCK);
1907   }
1908   ABSL_RAW_CHECK(
1909       waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
1910       "detected illegal recursion into Mutex code");
1911   for (;;) {
1912     v = mu_.load(std::memory_order_relaxed);
1913     CheckForMutexCorruption(v, "Lock");
1914     if ((v & waitp->how->slow_need_zero) == 0) {
1915       if (mu_.compare_exchange_strong(
1916               v, (waitp->how->fast_or |
1917                   (v & zap_desig_waker[flags & kMuHasBlocked])) +
1918                      waitp->how->fast_add,
1919               std::memory_order_acquire, std::memory_order_relaxed)) {
1920         if (waitp->cond == nullptr ||
1921             EvalConditionAnnotated(waitp->cond, this, true, false,
1922                                    waitp->how == kShared)) {
1923           break;  // we timed out, or condition true, so return
1924         }
1925         this->UnlockSlow(waitp);  // got lock but condition false
1926         this->Block(waitp->thread);
1927         flags |= kMuHasBlocked;
1928         c = 0;
1929       }
1930     } else {                      // need to access waiter list
1931       bool dowait = false;
1932       if ((v & (kMuSpin|kMuWait)) == 0) {   // no waiters
1933         // This thread tries to become the one and only waiter.
1934         PerThreadSynch *new_h = Enqueue(nullptr, waitp, v, flags);
1935         intptr_t nv = (v & zap_desig_waker[flags & kMuHasBlocked] & kMuLow) |
1936                       kMuWait;
1937         ABSL_RAW_CHECK(new_h != nullptr, "Enqueue to empty list failed");
1938         if (waitp->how == kExclusive && (v & kMuReader) != 0) {
1939           nv |= kMuWrWait;
1940         }
1941         if (mu_.compare_exchange_strong(
1942                 v, reinterpret_cast<intptr_t>(new_h) | nv,
1943                 std::memory_order_release, std::memory_order_relaxed)) {
1944           dowait = true;
1945         } else {            // attempted Enqueue() failed
1946           // zero out the waitp field set by Enqueue()
1947           waitp->thread->waitp = nullptr;
1948         }
1949       } else if ((v & waitp->how->slow_inc_need_zero &
1950                   ignore_waiting_writers[flags & kMuHasBlocked]) == 0) {
1951         // This is a reader that needs to increment the reader count,
1952         // but the count is currently held in the last waiter.
1953         if (mu_.compare_exchange_strong(
1954                 v, (v & zap_desig_waker[flags & kMuHasBlocked]) | kMuSpin |
1955                        kMuReader,
1956                 std::memory_order_acquire, std::memory_order_relaxed)) {
1957           PerThreadSynch *h = GetPerThreadSynch(v);
1958           h->readers += kMuOne;       // inc reader count in waiter
1959           do {                        // release spinlock
1960             v = mu_.load(std::memory_order_relaxed);
1961           } while (!mu_.compare_exchange_weak(v, (v & ~kMuSpin) | kMuReader,
1962                                               std::memory_order_release,
1963                                               std::memory_order_relaxed));
1964           if (waitp->cond == nullptr ||
1965               EvalConditionAnnotated(waitp->cond, this, true, false,
1966                                      waitp->how == kShared)) {
1967             break;  // we timed out, or condition true, so return
1968           }
1969           this->UnlockSlow(waitp);           // got lock but condition false
1970           this->Block(waitp->thread);
1971           flags |= kMuHasBlocked;
1972           c = 0;
1973         }
1974       } else if ((v & kMuSpin) == 0 &&  // attempt to queue ourselves
1975                  mu_.compare_exchange_strong(
1976                      v, (v & zap_desig_waker[flags & kMuHasBlocked]) | kMuSpin |
1977                             kMuWait,
1978                      std::memory_order_acquire, std::memory_order_relaxed)) {
1979         PerThreadSynch *h = GetPerThreadSynch(v);
1980         PerThreadSynch *new_h = Enqueue(h, waitp, v, flags);
1981         intptr_t wr_wait = 0;
1982         ABSL_RAW_CHECK(new_h != nullptr, "Enqueue to list failed");
1983         if (waitp->how == kExclusive && (v & kMuReader) != 0) {
1984           wr_wait = kMuWrWait;      // give priority to a waiting writer
1985         }
1986         do {                        // release spinlock
1987           v = mu_.load(std::memory_order_relaxed);
1988         } while (!mu_.compare_exchange_weak(
1989             v, (v & (kMuLow & ~kMuSpin)) | kMuWait | wr_wait |
1990             reinterpret_cast<intptr_t>(new_h),
1991             std::memory_order_release, std::memory_order_relaxed));
1992         dowait = true;
1993       }
1994       if (dowait) {
1995         this->Block(waitp->thread);  // wait until removed from list or timeout
1996         flags |= kMuHasBlocked;
1997         c = 0;
1998       }
1999     }
2000     ABSL_RAW_CHECK(
2001         waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
2002         "detected illegal recursion into Mutex code");
2003     c = Delay(c, GENTLE);          // delay, then try again
2004   }
2005   ABSL_RAW_CHECK(
2006       waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors,
2007       "detected illegal recursion into Mutex code");
2008   if ((v & kMuEvent) != 0) {
2009     PostSynchEvent(this,
2010                    waitp->how == kExclusive? SYNCH_EV_LOCK_RETURNING :
2011                                       SYNCH_EV_READERLOCK_RETURNING);
2012   }
2013 }
2014 
2015 // Unlock this mutex, which is held by the current thread.
2016 // If waitp is non-zero, it must be the wait parameters for the current thread
2017 // which holds the lock but is not runnable because its condition is false
2018 // or it is in the process of blocking on a condition variable; it must requeue
2019 // itself on the mutex/condvar to wait for its condition to become true.
UnlockSlow(SynchWaitParams * waitp)2020 void Mutex::UnlockSlow(SynchWaitParams *waitp) {
2021   intptr_t v = mu_.load(std::memory_order_relaxed);
2022   this->AssertReaderHeld();
2023   CheckForMutexCorruption(v, "Unlock");
2024   if ((v & kMuEvent) != 0) {
2025     PostSynchEvent(this,
2026                 (v & kMuWriter) != 0? SYNCH_EV_UNLOCK: SYNCH_EV_READERUNLOCK);
2027   }
2028   int c = 0;
2029   // the waiter under consideration to wake, or zero
2030   PerThreadSynch *w = nullptr;
2031   // the predecessor to w or zero
2032   PerThreadSynch *pw = nullptr;
2033   // head of the list searched previously, or zero
2034   PerThreadSynch *old_h = nullptr;
2035   // a condition that's known to be false.
2036   const Condition *known_false = nullptr;
2037   PerThreadSynch *wake_list = kPerThreadSynchNull;   // list of threads to wake
2038   intptr_t wr_wait = 0;        // set to kMuWrWait if we wake a reader and a
2039                                // later writer could have acquired the lock
2040                                // (starvation avoidance)
2041   ABSL_RAW_CHECK(waitp == nullptr || waitp->thread->waitp == nullptr ||
2042                      waitp->thread->suppress_fatal_errors,
2043                  "detected illegal recursion into Mutex code");
2044   // This loop finds threads wake_list to wakeup if any, and removes them from
2045   // the list of waiters.  In addition, it places waitp.thread on the queue of
2046   // waiters if waitp is non-zero.
2047   for (;;) {
2048     v = mu_.load(std::memory_order_relaxed);
2049     if ((v & kMuWriter) != 0 && (v & (kMuWait | kMuDesig)) != kMuWait &&
2050         waitp == nullptr) {
2051       // fast writer release (writer with no waiters or with designated waker)
2052       if (mu_.compare_exchange_strong(v, v & ~(kMuWrWait | kMuWriter),
2053                                       std::memory_order_release,
2054                                       std::memory_order_relaxed)) {
2055         return;
2056       }
2057     } else if ((v & (kMuReader | kMuWait)) == kMuReader && waitp == nullptr) {
2058       // fast reader release (reader with no waiters)
2059       intptr_t clear = ExactlyOneReader(v) ? kMuReader | kMuOne : kMuOne;
2060       if (mu_.compare_exchange_strong(v, v - clear,
2061                                       std::memory_order_release,
2062                                       std::memory_order_relaxed)) {
2063         return;
2064       }
2065     } else if ((v & kMuSpin) == 0 &&  // attempt to get spinlock
2066                mu_.compare_exchange_strong(v, v | kMuSpin,
2067                                            std::memory_order_acquire,
2068                                            std::memory_order_relaxed)) {
2069       if ((v & kMuWait) == 0) {       // no one to wake
2070         intptr_t nv;
2071         bool do_enqueue = true;  // always Enqueue() the first time
2072         ABSL_RAW_CHECK(waitp != nullptr,
2073                        "UnlockSlow is confused");  // about to sleep
2074         do {    // must loop to release spinlock as reader count may change
2075           v = mu_.load(std::memory_order_relaxed);
2076           // decrement reader count if there are readers
2077           intptr_t new_readers = (v >= kMuOne)?  v - kMuOne : v;
2078           PerThreadSynch *new_h = nullptr;
2079           if (do_enqueue) {
2080             // If we are enqueuing on a CondVar (waitp->cv_word != nullptr) then
2081             // we must not retry here.  The initial attempt will always have
2082             // succeeded, further attempts would enqueue us against *this due to
2083             // Fer() handling.
2084             do_enqueue = (waitp->cv_word == nullptr);
2085             new_h = Enqueue(nullptr, waitp, new_readers, kMuIsCond);
2086           }
2087           intptr_t clear = kMuWrWait | kMuWriter;  // by default clear write bit
2088           if ((v & kMuWriter) == 0 && ExactlyOneReader(v)) {  // last reader
2089             clear = kMuWrWait | kMuReader;                    // clear read bit
2090           }
2091           nv = (v & kMuLow & ~clear & ~kMuSpin);
2092           if (new_h != nullptr) {
2093             nv |= kMuWait | reinterpret_cast<intptr_t>(new_h);
2094           } else {  // new_h could be nullptr if we queued ourselves on a
2095                     // CondVar
2096             // In that case, we must place the reader count back in the mutex
2097             // word, as Enqueue() did not store it in the new waiter.
2098             nv |= new_readers & kMuHigh;
2099           }
2100           // release spinlock & our lock; retry if reader-count changed
2101           // (writer count cannot change since we hold lock)
2102         } while (!mu_.compare_exchange_weak(v, nv,
2103                                             std::memory_order_release,
2104                                             std::memory_order_relaxed));
2105         break;
2106       }
2107 
2108       // There are waiters.
2109       // Set h to the head of the circular waiter list.
2110       PerThreadSynch *h = GetPerThreadSynch(v);
2111       if ((v & kMuReader) != 0 && (h->readers & kMuHigh) > kMuOne) {
2112         // a reader but not the last
2113         h->readers -= kMuOne;  // release our lock
2114         intptr_t nv = v;       // normally just release spinlock
2115         if (waitp != nullptr) {  // but waitp!=nullptr => must queue ourselves
2116           PerThreadSynch *new_h = Enqueue(h, waitp, v, kMuIsCond);
2117           ABSL_RAW_CHECK(new_h != nullptr,
2118                          "waiters disappeared during Enqueue()!");
2119           nv &= kMuLow;
2120           nv |= kMuWait | reinterpret_cast<intptr_t>(new_h);
2121         }
2122         mu_.store(nv, std::memory_order_release);  // release spinlock
2123         // can release with a store because there were waiters
2124         break;
2125       }
2126 
2127       // Either we didn't search before, or we marked the queue
2128       // as "maybe_unlocking" and no one else should have changed it.
2129       ABSL_RAW_CHECK(old_h == nullptr || h->maybe_unlocking,
2130                      "Mutex queue changed beneath us");
2131 
2132       // The lock is becoming free, and there's a waiter
2133       if (old_h != nullptr &&
2134           !old_h->may_skip) {                  // we used old_h as a terminator
2135         old_h->may_skip = true;                // allow old_h to skip once more
2136         ABSL_RAW_CHECK(old_h->skip == nullptr, "illegal skip from head");
2137         if (h != old_h && MuSameCondition(old_h, old_h->next)) {
2138           old_h->skip = old_h->next;  // old_h not head & can skip to successor
2139         }
2140       }
2141       if (h->next->waitp->how == kExclusive &&
2142           Condition::GuaranteedEqual(h->next->waitp->cond, nullptr)) {
2143         // easy case: writer with no condition; no need to search
2144         pw = h;                       // wake w, the successor of h (=pw)
2145         w = h->next;
2146         w->wake = true;
2147         // We are waking up a writer.  This writer may be racing against
2148         // an already awake reader for the lock.  We want the
2149         // writer to usually win this race,
2150         // because if it doesn't, we can potentially keep taking a reader
2151         // perpetually and writers will starve.  Worse than
2152         // that, this can also starve other readers if kMuWrWait gets set
2153         // later.
2154         wr_wait = kMuWrWait;
2155       } else if (w != nullptr && (w->waitp->how == kExclusive || h == old_h)) {
2156         // we found a waiter w to wake on a previous iteration and either it's
2157         // a writer, or we've searched the entire list so we have all the
2158         // readers.
2159         if (pw == nullptr) {  // if w's predecessor is unknown, it must be h
2160           pw = h;
2161         }
2162       } else {
2163         // At this point we don't know all the waiters to wake, and the first
2164         // waiter has a condition or is a reader.  We avoid searching over
2165         // waiters we've searched on previous iterations by starting at
2166         // old_h if it's set.  If old_h==h, there's no one to wakeup at all.
2167         if (old_h == h) {      // we've searched before, and nothing's new
2168                                // so there's no one to wake.
2169           intptr_t nv = (v & ~(kMuReader|kMuWriter|kMuWrWait));
2170           h->readers = 0;
2171           h->maybe_unlocking = false;   // finished unlocking
2172           if (waitp != nullptr) {       // we must queue ourselves and sleep
2173             PerThreadSynch *new_h = Enqueue(h, waitp, v, kMuIsCond);
2174             nv &= kMuLow;
2175             if (new_h != nullptr) {
2176               nv |= kMuWait | reinterpret_cast<intptr_t>(new_h);
2177             }  // else new_h could be nullptr if we queued ourselves on a
2178                // CondVar
2179           }
2180           // release spinlock & lock
2181           // can release with a store because there were waiters
2182           mu_.store(nv, std::memory_order_release);
2183           break;
2184         }
2185 
2186         // set up to walk the list
2187         PerThreadSynch *w_walk;   // current waiter during list walk
2188         PerThreadSynch *pw_walk;  // previous waiter during list walk
2189         if (old_h != nullptr) {  // we've searched up to old_h before
2190           pw_walk = old_h;
2191           w_walk = old_h->next;
2192         } else {            // no prior search, start at beginning
2193           pw_walk =
2194               nullptr;  // h->next's predecessor may change; don't record it
2195           w_walk = h->next;
2196         }
2197 
2198         h->may_skip = false;  // ensure we never skip past h in future searches
2199                               // even if other waiters are queued after it.
2200         ABSL_RAW_CHECK(h->skip == nullptr, "illegal skip from head");
2201 
2202         h->maybe_unlocking = true;  // we're about to scan the waiter list
2203                                     // without the spinlock held.
2204                                     // Enqueue must be conservative about
2205                                     // priority queuing.
2206 
2207         // We must release the spinlock to evaluate the conditions.
2208         mu_.store(v, std::memory_order_release);  // release just spinlock
2209         // can release with a store because there were waiters
2210 
2211         // h is the last waiter queued, and w_walk the first unsearched waiter.
2212         // Without the spinlock, the locations mu_ and h->next may now change
2213         // underneath us, but since we hold the lock itself, the only legal
2214         // change is to add waiters between h and w_walk.  Therefore, it's safe
2215         // to walk the path from w_walk to h inclusive. (TryRemove() can remove
2216         // a waiter anywhere, but it acquires both the spinlock and the Mutex)
2217 
2218         old_h = h;        // remember we searched to here
2219 
2220         // Walk the path upto and including h looking for waiters we can wake.
2221         while (pw_walk != h) {
2222           w_walk->wake = false;
2223           if (w_walk->waitp->cond ==
2224                   nullptr ||  // no condition => vacuously true OR
2225               (w_walk->waitp->cond != known_false &&
2226                // this thread's condition is not known false, AND
2227                //  is in fact true
2228                EvalConditionIgnored(this, w_walk->waitp->cond))) {
2229             if (w == nullptr) {
2230               w_walk->wake = true;    // can wake this waiter
2231               w = w_walk;
2232               pw = pw_walk;
2233               if (w_walk->waitp->how == kExclusive) {
2234                 wr_wait = kMuWrWait;
2235                 break;                // bail if waking this writer
2236               }
2237             } else if (w_walk->waitp->how == kShared) {  // wake if a reader
2238               w_walk->wake = true;
2239             } else {   // writer with true condition
2240               wr_wait = kMuWrWait;
2241             }
2242           } else {                  // can't wake; condition false
2243             known_false = w_walk->waitp->cond;  // remember last false condition
2244           }
2245           if (w_walk->wake) {   // we're waking reader w_walk
2246             pw_walk = w_walk;   // don't skip similar waiters
2247           } else {              // not waking; skip as much as possible
2248             pw_walk = Skip(w_walk);
2249           }
2250           // If pw_walk == h, then load of pw_walk->next can race with
2251           // concurrent write in Enqueue(). However, at the same time
2252           // we do not need to do the load, because we will bail out
2253           // from the loop anyway.
2254           if (pw_walk != h) {
2255             w_walk = pw_walk->next;
2256           }
2257         }
2258 
2259         continue;  // restart for(;;)-loop to wakeup w or to find more waiters
2260       }
2261       ABSL_RAW_CHECK(pw->next == w, "pw not w's predecessor");
2262       // The first (and perhaps only) waiter we've chosen to wake is w, whose
2263       // predecessor is pw.  If w is a reader, we must wake all the other
2264       // waiters with wake==true as well.  We may also need to queue
2265       // ourselves if waitp != null.  The spinlock and the lock are still
2266       // held.
2267 
2268       // This traverses the list in [ pw->next, h ], where h is the head,
2269       // removing all elements with wake==true and placing them in the
2270       // singly-linked list wake_list.  Returns the new head.
2271       h = DequeueAllWakeable(h, pw, &wake_list);
2272 
2273       intptr_t nv = (v & kMuEvent) | kMuDesig;
2274                                              // assume no waiters left,
2275                                              // set kMuDesig for INV1a
2276 
2277       if (waitp != nullptr) {  // we must queue ourselves and sleep
2278         h = Enqueue(h, waitp, v, kMuIsCond);
2279         // h is new last waiter; could be null if we queued ourselves on a
2280         // CondVar
2281       }
2282 
2283       ABSL_RAW_CHECK(wake_list != kPerThreadSynchNull,
2284                      "unexpected empty wake list");
2285 
2286       if (h != nullptr) {  // there are waiters left
2287         h->readers = 0;
2288         h->maybe_unlocking = false;     // finished unlocking
2289         nv |= wr_wait | kMuWait | reinterpret_cast<intptr_t>(h);
2290       }
2291 
2292       // release both spinlock & lock
2293       // can release with a store because there were waiters
2294       mu_.store(nv, std::memory_order_release);
2295       break;  // out of for(;;)-loop
2296     }
2297     c = Delay(c, AGGRESSIVE);  // aggressive here; no one can proceed till we do
2298   }                            // end of for(;;)-loop
2299 
2300   if (wake_list != kPerThreadSynchNull) {
2301     int64_t enqueue_timestamp = wake_list->waitp->contention_start_cycles;
2302     bool cond_waiter = wake_list->cond_waiter;
2303     do {
2304       wake_list = Wakeup(wake_list);              // wake waiters
2305     } while (wake_list != kPerThreadSynchNull);
2306     if (!cond_waiter) {
2307       // Sample lock contention events only if the (first) waiter was trying to
2308       // acquire the lock, not waiting on a condition variable or Condition.
2309       int64_t wait_cycles = base_internal::CycleClock::Now() - enqueue_timestamp;
2310       mutex_tracer("slow release", this, wait_cycles);
2311       ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0);
2312       submit_profile_data(enqueue_timestamp);
2313       ABSL_TSAN_MUTEX_POST_DIVERT(this, 0);
2314     }
2315   }
2316 }
2317 
2318 // Used by CondVar implementation to reacquire mutex after waking from
2319 // condition variable.  This routine is used instead of Lock() because the
2320 // waiting thread may have been moved from the condition variable queue to the
2321 // mutex queue without a wakeup, by Trans().  In that case, when the thread is
2322 // finally woken, the woken thread will believe it has been woken from the
2323 // condition variable (i.e. its PC will be in when in the CondVar code), when
2324 // in fact it has just been woken from the mutex.  Thus, it must enter the slow
2325 // path of the mutex in the same state as if it had just woken from the mutex.
2326 // That is, it must ensure to clear kMuDesig (INV1b).
Trans(MuHow how)2327 void Mutex::Trans(MuHow how) {
2328   this->LockSlow(how, nullptr, kMuHasBlocked | kMuIsCond);
2329 }
2330 
2331 // Used by CondVar implementation to effectively wake thread w from the
2332 // condition variable.  If this mutex is free, we simply wake the thread.
2333 // It will later acquire the mutex with high probability.  Otherwise, we
2334 // enqueue thread w on this mutex.
Fer(PerThreadSynch * w)2335 void Mutex::Fer(PerThreadSynch *w) {
2336   int c = 0;
2337   ABSL_RAW_CHECK(w->waitp->cond == nullptr,
2338                  "Mutex::Fer while waiting on Condition");
2339   ABSL_RAW_CHECK(!w->waitp->timeout.has_timeout(),
2340                  "Mutex::Fer while in timed wait");
2341   ABSL_RAW_CHECK(w->waitp->cv_word == nullptr,
2342                  "Mutex::Fer with pending CondVar queueing");
2343   for (;;) {
2344     intptr_t v = mu_.load(std::memory_order_relaxed);
2345     // Note: must not queue if the mutex is unlocked (nobody will wake it).
2346     // For example, we can have only kMuWait (conditional) or maybe
2347     // kMuWait|kMuWrWait.
2348     // conflicting != 0 implies that the waking thread cannot currently take
2349     // the mutex, which in turn implies that someone else has it and can wake
2350     // us if we queue.
2351     const intptr_t conflicting =
2352         kMuWriter | (w->waitp->how == kShared ? 0 : kMuReader);
2353     if ((v & conflicting) == 0) {
2354       w->next = nullptr;
2355       w->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
2356       IncrementSynchSem(this, w);
2357       return;
2358     } else {
2359       if ((v & (kMuSpin|kMuWait)) == 0) {       // no waiters
2360         // This thread tries to become the one and only waiter.
2361         PerThreadSynch *new_h = Enqueue(nullptr, w->waitp, v, kMuIsCond);
2362         ABSL_RAW_CHECK(new_h != nullptr,
2363                        "Enqueue failed");  // we must queue ourselves
2364         if (mu_.compare_exchange_strong(
2365                 v, reinterpret_cast<intptr_t>(new_h) | (v & kMuLow) | kMuWait,
2366                 std::memory_order_release, std::memory_order_relaxed)) {
2367           return;
2368         }
2369       } else if ((v & kMuSpin) == 0 &&
2370                  mu_.compare_exchange_strong(v, v | kMuSpin | kMuWait)) {
2371         PerThreadSynch *h = GetPerThreadSynch(v);
2372         PerThreadSynch *new_h = Enqueue(h, w->waitp, v, kMuIsCond);
2373         ABSL_RAW_CHECK(new_h != nullptr,
2374                        "Enqueue failed");  // we must queue ourselves
2375         do {
2376           v = mu_.load(std::memory_order_relaxed);
2377         } while (!mu_.compare_exchange_weak(
2378             v,
2379             (v & kMuLow & ~kMuSpin) | kMuWait |
2380                 reinterpret_cast<intptr_t>(new_h),
2381             std::memory_order_release, std::memory_order_relaxed));
2382         return;
2383       }
2384     }
2385     c = Delay(c, GENTLE);
2386   }
2387 }
2388 
AssertHeld() const2389 void Mutex::AssertHeld() const {
2390   if ((mu_.load(std::memory_order_relaxed) & kMuWriter) == 0) {
2391     SynchEvent *e = GetSynchEvent(this);
2392     ABSL_RAW_LOG(FATAL, "thread should hold write lock on Mutex %p %s",
2393                  static_cast<const void *>(this),
2394                  (e == nullptr ? "" : e->name));
2395   }
2396 }
2397 
AssertReaderHeld() const2398 void Mutex::AssertReaderHeld() const {
2399   if ((mu_.load(std::memory_order_relaxed) & (kMuReader | kMuWriter)) == 0) {
2400     SynchEvent *e = GetSynchEvent(this);
2401     ABSL_RAW_LOG(
2402         FATAL, "thread should hold at least a read lock on Mutex %p %s",
2403         static_cast<const void *>(this), (e == nullptr ? "" : e->name));
2404   }
2405 }
2406 
2407 // -------------------------------- condition variables
2408 static const intptr_t kCvSpin = 0x0001L;   // spinlock protects waiter list
2409 static const intptr_t kCvEvent = 0x0002L;  // record events
2410 
2411 static const intptr_t kCvLow = 0x0003L;  // low order bits of CV
2412 
2413 // Hack to make constant values available to gdb pretty printer
2414 enum { kGdbCvSpin = kCvSpin, kGdbCvEvent = kCvEvent, kGdbCvLow = kCvLow, };
2415 
2416 static_assert(PerThreadSynch::kAlignment > kCvLow,
2417               "PerThreadSynch::kAlignment must be greater than kCvLow");
2418 
EnableDebugLog(const char * name)2419 void CondVar::EnableDebugLog(const char *name) {
2420   SynchEvent *e = EnsureSynchEvent(&this->cv_, name, kCvEvent, kCvSpin);
2421   e->log = true;
2422   UnrefSynchEvent(e);
2423 }
2424 
~CondVar()2425 CondVar::~CondVar() {
2426   if ((cv_.load(std::memory_order_relaxed) & kCvEvent) != 0) {
2427     ForgetSynchEvent(&this->cv_, kCvEvent, kCvSpin);
2428   }
2429 }
2430 
2431 
2432 // Remove thread s from the list of waiters on this condition variable.
Remove(PerThreadSynch * s)2433 void CondVar::Remove(PerThreadSynch *s) {
2434   intptr_t v;
2435   int c = 0;
2436   for (v = cv_.load(std::memory_order_relaxed);;
2437        v = cv_.load(std::memory_order_relaxed)) {
2438     if ((v & kCvSpin) == 0 &&  // attempt to acquire spinlock
2439         cv_.compare_exchange_strong(v, v | kCvSpin,
2440                                     std::memory_order_acquire,
2441                                     std::memory_order_relaxed)) {
2442       PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow);
2443       if (h != nullptr) {
2444         PerThreadSynch *w = h;
2445         while (w->next != s && w->next != h) {  // search for thread
2446           w = w->next;
2447         }
2448         if (w->next == s) {           // found thread; remove it
2449           w->next = s->next;
2450           if (h == s) {
2451             h = (w == s) ? nullptr : w;
2452           }
2453           s->next = nullptr;
2454           s->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
2455         }
2456       }
2457                                       // release spinlock
2458       cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h),
2459                 std::memory_order_release);
2460       return;
2461     } else {
2462       c = Delay(c, GENTLE);            // try again after a delay
2463     }
2464   }
2465 }
2466 
2467 // Queue thread waitp->thread on condition variable word cv_word using
2468 // wait parameters waitp.
2469 // We split this into a separate routine, rather than simply doing it as part
2470 // of WaitCommon().  If we were to queue ourselves on the condition variable
2471 // before calling Mutex::UnlockSlow(), the Mutex code might be re-entered (via
2472 // the logging code, or via a Condition function) and might potentially attempt
2473 // to block this thread.  That would be a problem if the thread were already on
2474 // a the condition variable waiter queue.  Thus, we use the waitp->cv_word
2475 // to tell the unlock code to call CondVarEnqueue() to queue the thread on the
2476 // condition variable queue just before the mutex is to be unlocked, and (most
2477 // importantly) after any call to an external routine that might re-enter the
2478 // mutex code.
CondVarEnqueue(SynchWaitParams * waitp)2479 static void CondVarEnqueue(SynchWaitParams *waitp) {
2480   // This thread might be transferred to the Mutex queue by Fer() when
2481   // we are woken.  To make sure that is what happens, Enqueue() doesn't
2482   // call CondVarEnqueue() again but instead uses its normal code.  We
2483   // must do this before we queue ourselves so that cv_word will be null
2484   // when seen by the dequeuer, who may wish immediately to requeue
2485   // this thread on another queue.
2486   std::atomic<intptr_t> *cv_word = waitp->cv_word;
2487   waitp->cv_word = nullptr;
2488 
2489   intptr_t v = cv_word->load(std::memory_order_relaxed);
2490   int c = 0;
2491   while ((v & kCvSpin) != 0 ||  // acquire spinlock
2492          !cv_word->compare_exchange_weak(v, v | kCvSpin,
2493                                          std::memory_order_acquire,
2494                                          std::memory_order_relaxed)) {
2495     c = Delay(c, GENTLE);
2496     v = cv_word->load(std::memory_order_relaxed);
2497   }
2498   ABSL_RAW_CHECK(waitp->thread->waitp == nullptr, "waiting when shouldn't be");
2499   waitp->thread->waitp = waitp;      // prepare ourselves for waiting
2500   PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow);
2501   if (h == nullptr) {  // add this thread to waiter list
2502     waitp->thread->next = waitp->thread;
2503   } else {
2504     waitp->thread->next = h->next;
2505     h->next = waitp->thread;
2506   }
2507   waitp->thread->state.store(PerThreadSynch::kQueued,
2508                              std::memory_order_relaxed);
2509   cv_word->store((v & kCvEvent) | reinterpret_cast<intptr_t>(waitp->thread),
2510                  std::memory_order_release);
2511 }
2512 
WaitCommon(Mutex * mutex,KernelTimeout t)2513 bool CondVar::WaitCommon(Mutex *mutex, KernelTimeout t) {
2514   bool rc = false;          // return value; true iff we timed-out
2515 
2516   intptr_t mutex_v = mutex->mu_.load(std::memory_order_relaxed);
2517   Mutex::MuHow mutex_how = ((mutex_v & kMuWriter) != 0) ? kExclusive : kShared;
2518   ABSL_TSAN_MUTEX_PRE_UNLOCK(mutex, TsanFlags(mutex_how));
2519 
2520   // maybe trace this call
2521   intptr_t v = cv_.load(std::memory_order_relaxed);
2522   cond_var_tracer("Wait", this);
2523   if ((v & kCvEvent) != 0) {
2524     PostSynchEvent(this, SYNCH_EV_WAIT);
2525   }
2526 
2527   // Release mu and wait on condition variable.
2528   SynchWaitParams waitp(mutex_how, nullptr, t, mutex,
2529                         Synch_GetPerThreadAnnotated(mutex), &cv_);
2530   // UnlockSlow() will call CondVarEnqueue() just before releasing the
2531   // Mutex, thus queuing this thread on the condition variable.  See
2532   // CondVarEnqueue() for the reasons.
2533   mutex->UnlockSlow(&waitp);
2534 
2535   // wait for signal
2536   while (waitp.thread->state.load(std::memory_order_acquire) ==
2537          PerThreadSynch::kQueued) {
2538     if (!Mutex::DecrementSynchSem(mutex, waitp.thread, t)) {
2539       this->Remove(waitp.thread);
2540       rc = true;
2541     }
2542   }
2543 
2544   ABSL_RAW_CHECK(waitp.thread->waitp != nullptr, "not waiting when should be");
2545   waitp.thread->waitp = nullptr;  // cleanup
2546 
2547   // maybe trace this call
2548   cond_var_tracer("Unwait", this);
2549   if ((v & kCvEvent) != 0) {
2550     PostSynchEvent(this, SYNCH_EV_WAIT_RETURNING);
2551   }
2552 
2553   // From synchronization point of view Wait is unlock of the mutex followed
2554   // by lock of the mutex. We've annotated start of unlock in the beginning
2555   // of the function. Now, finish unlock and annotate lock of the mutex.
2556   // (Trans is effectively lock).
2557   ABSL_TSAN_MUTEX_POST_UNLOCK(mutex, TsanFlags(mutex_how));
2558   ABSL_TSAN_MUTEX_PRE_LOCK(mutex, TsanFlags(mutex_how));
2559   mutex->Trans(mutex_how);  // Reacquire mutex
2560   ABSL_TSAN_MUTEX_POST_LOCK(mutex, TsanFlags(mutex_how), 0);
2561   return rc;
2562 }
2563 
WaitWithTimeout(Mutex * mu,absl::Duration timeout)2564 bool CondVar::WaitWithTimeout(Mutex *mu, absl::Duration timeout) {
2565   return WaitWithDeadline(mu, DeadlineFromTimeout(timeout));
2566 }
2567 
WaitWithDeadline(Mutex * mu,absl::Time deadline)2568 bool CondVar::WaitWithDeadline(Mutex *mu, absl::Time deadline) {
2569   return WaitCommon(mu, KernelTimeout(deadline));
2570 }
2571 
Wait(Mutex * mu)2572 void CondVar::Wait(Mutex *mu) {
2573   WaitCommon(mu, KernelTimeout::Never());
2574 }
2575 
2576 // Wake thread w
2577 // If it was a timed wait, w will be waiting on w->cv
2578 // Otherwise, if it was not a Mutex mutex, w will be waiting on w->sem
2579 // Otherwise, w is transferred to the Mutex mutex via Mutex::Fer().
Wakeup(PerThreadSynch * w)2580 void CondVar::Wakeup(PerThreadSynch *w) {
2581   if (w->waitp->timeout.has_timeout() || w->waitp->cvmu == nullptr) {
2582     // The waiting thread only needs to observe "w->state == kAvailable" to be
2583     // released, we must cache "cvmu" before clearing "next".
2584     Mutex *mu = w->waitp->cvmu;
2585     w->next = nullptr;
2586     w->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
2587     Mutex::IncrementSynchSem(mu, w);
2588   } else {
2589     w->waitp->cvmu->Fer(w);
2590   }
2591 }
2592 
Signal()2593 void CondVar::Signal() {
2594   ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
2595   intptr_t v;
2596   int c = 0;
2597   for (v = cv_.load(std::memory_order_relaxed); v != 0;
2598        v = cv_.load(std::memory_order_relaxed)) {
2599     if ((v & kCvSpin) == 0 &&  // attempt to acquire spinlock
2600         cv_.compare_exchange_strong(v, v | kCvSpin,
2601                                     std::memory_order_acquire,
2602                                     std::memory_order_relaxed)) {
2603       PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow);
2604       PerThreadSynch *w = nullptr;
2605       if (h != nullptr) {  // remove first waiter
2606         w = h->next;
2607         if (w == h) {
2608           h = nullptr;
2609         } else {
2610           h->next = w->next;
2611         }
2612       }
2613                                       // release spinlock
2614       cv_.store((v & kCvEvent) | reinterpret_cast<intptr_t>(h),
2615                 std::memory_order_release);
2616       if (w != nullptr) {
2617         CondVar::Wakeup(w);                // wake waiter, if there was one
2618         cond_var_tracer("Signal wakeup", this);
2619       }
2620       if ((v & kCvEvent) != 0) {
2621         PostSynchEvent(this, SYNCH_EV_SIGNAL);
2622       }
2623       ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
2624       return;
2625     } else {
2626       c = Delay(c, GENTLE);
2627     }
2628   }
2629   ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
2630 }
2631 
SignalAll()2632 void CondVar::SignalAll () {
2633   ABSL_TSAN_MUTEX_PRE_SIGNAL(nullptr, 0);
2634   intptr_t v;
2635   int c = 0;
2636   for (v = cv_.load(std::memory_order_relaxed); v != 0;
2637        v = cv_.load(std::memory_order_relaxed)) {
2638     // empty the list if spinlock free
2639     // We do this by simply setting the list to empty using
2640     // compare and swap.   We then have the entire list in our hands,
2641     // which cannot be changing since we grabbed it while no one
2642     // held the lock.
2643     if ((v & kCvSpin) == 0 &&
2644         cv_.compare_exchange_strong(v, v & kCvEvent, std::memory_order_acquire,
2645                                     std::memory_order_relaxed)) {
2646       PerThreadSynch *h = reinterpret_cast<PerThreadSynch *>(v & ~kCvLow);
2647       if (h != nullptr) {
2648         PerThreadSynch *w;
2649         PerThreadSynch *n = h->next;
2650         do {                          // for every thread, wake it up
2651           w = n;
2652           n = n->next;
2653           CondVar::Wakeup(w);
2654         } while (w != h);
2655         cond_var_tracer("SignalAll wakeup", this);
2656       }
2657       if ((v & kCvEvent) != 0) {
2658         PostSynchEvent(this, SYNCH_EV_SIGNALALL);
2659       }
2660       ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
2661       return;
2662     } else {
2663       c = Delay(c, GENTLE);           // try again after a delay
2664     }
2665   }
2666   ABSL_TSAN_MUTEX_POST_SIGNAL(nullptr, 0);
2667 }
2668 
Release()2669 void ReleasableMutexLock::Release() {
2670   ABSL_RAW_CHECK(this->mu_ != nullptr,
2671                  "ReleasableMutexLock::Release may only be called once");
2672   this->mu_->Unlock();
2673   this->mu_ = nullptr;
2674 }
2675 
2676 #ifdef THREAD_SANITIZER
2677 extern "C" void __tsan_read1(void *addr);
2678 #else
2679 #define __tsan_read1(addr)  // do nothing if TSan not enabled
2680 #endif
2681 
2682 // A function that just returns its argument, dereferenced
Dereference(void * arg)2683 static bool Dereference(void *arg) {
2684   // ThreadSanitizer does not instrument this file for memory accesses.
2685   // This function dereferences a user variable that can participate
2686   // in a data race, so we need to manually tell TSan about this memory access.
2687   __tsan_read1(arg);
2688   return *(static_cast<bool *>(arg));
2689 }
2690 
Condition()2691 Condition::Condition() {}   // null constructor, used for kTrue only
2692 const Condition Condition::kTrue;
2693 
Condition(bool (* func)(void *),void * arg)2694 Condition::Condition(bool (*func)(void *), void *arg)
2695     : eval_(&CallVoidPtrFunction),
2696       function_(func),
2697       method_(nullptr),
2698       arg_(arg) {}
2699 
CallVoidPtrFunction(const Condition * c)2700 bool Condition::CallVoidPtrFunction(const Condition *c) {
2701   return (*c->function_)(c->arg_);
2702 }
2703 
Condition(const bool * cond)2704 Condition::Condition(const bool *cond)
2705     : eval_(CallVoidPtrFunction),
2706       function_(Dereference),
2707       method_(nullptr),
2708       // const_cast is safe since Dereference does not modify arg
2709       arg_(const_cast<bool *>(cond)) {}
2710 
Eval() const2711 bool Condition::Eval() const {
2712   // eval_ == null for kTrue
2713   return (this->eval_ == nullptr) || (*this->eval_)(this);
2714 }
2715 
GuaranteedEqual(const Condition * a,const Condition * b)2716 bool Condition::GuaranteedEqual(const Condition *a, const Condition *b) {
2717   if (a == nullptr) {
2718     return b == nullptr || b->eval_ == nullptr;
2719   }
2720   if (b == nullptr || b->eval_ == nullptr) {
2721     return a->eval_ == nullptr;
2722   }
2723   return a->eval_ == b->eval_ && a->function_ == b->function_ &&
2724          a->arg_ == b->arg_ && a->method_ == b->method_;
2725 }
2726 
2727 ABSL_NAMESPACE_END
2728 }  // namespace absl
2729