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 #endif
20 
21 #include <algorithm>
22 #include <atomic>
23 #include <cstdlib>
24 #include <functional>
25 #include <memory>
26 #include <random>
27 #include <string>
28 #include <thread>  // NOLINT(build/c++11)
29 #include <type_traits>
30 #include <vector>
31 
32 #include "gtest/gtest.h"
33 #include "absl/base/attributes.h"
34 #include "absl/base/config.h"
35 #include "absl/base/internal/raw_logging.h"
36 #include "absl/base/internal/sysinfo.h"
37 #include "absl/memory/memory.h"
38 #include "absl/synchronization/internal/thread_pool.h"
39 #include "absl/time/clock.h"
40 #include "absl/time/time.h"
41 
42 namespace {
43 
44 // TODO(dmauro): Replace with a commandline flag.
45 static constexpr bool kExtendedTest = false;
46 
CreatePool(int threads)47 std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
48     int threads) {
49   return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads);
50 }
51 
52 std::unique_ptr<absl::synchronization_internal::ThreadPool>
CreateDefaultPool()53 CreateDefaultPool() {
54   return CreatePool(kExtendedTest ? 32 : 10);
55 }
56 
57 // Hack to schedule a function to run on a thread pool thread after a
58 // duration has elapsed.
ScheduleAfter(absl::synchronization_internal::ThreadPool * tp,absl::Duration after,const std::function<void ()> & func)59 static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
60                           absl::Duration after,
61                           const std::function<void()> &func) {
62   tp->Schedule([func, after] {
63     absl::SleepFor(after);
64     func();
65   });
66 }
67 
68 struct TestContext {
69   int iterations;
70   int threads;
71   int g0;  // global 0
72   int g1;  // global 1
73   absl::Mutex mu;
74   absl::CondVar cv;
75 };
76 
77 // To test whether the invariant check call occurs
78 static std::atomic<bool> invariant_checked;
79 
GetInvariantChecked()80 static bool GetInvariantChecked() {
81   return invariant_checked.load(std::memory_order_relaxed);
82 }
83 
SetInvariantChecked(bool new_value)84 static void SetInvariantChecked(bool new_value) {
85   invariant_checked.store(new_value, std::memory_order_relaxed);
86 }
87 
CheckSumG0G1(void * v)88 static void CheckSumG0G1(void *v) {
89   TestContext *cxt = static_cast<TestContext *>(v);
90   ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1");
91   SetInvariantChecked(true);
92 }
93 
TestMu(TestContext * cxt,int c)94 static void TestMu(TestContext *cxt, int c) {
95   for (int i = 0; i != cxt->iterations; i++) {
96     absl::MutexLock l(&cxt->mu);
97     int a = cxt->g0 + 1;
98     cxt->g0 = a;
99     cxt->g1--;
100   }
101 }
102 
TestTry(TestContext * cxt,int c)103 static void TestTry(TestContext *cxt, int c) {
104   for (int i = 0; i != cxt->iterations; i++) {
105     do {
106       std::this_thread::yield();
107     } while (!cxt->mu.TryLock());
108     int a = cxt->g0 + 1;
109     cxt->g0 = a;
110     cxt->g1--;
111     cxt->mu.Unlock();
112   }
113 }
114 
TestR20ms(TestContext * cxt,int c)115 static void TestR20ms(TestContext *cxt, int c) {
116   for (int i = 0; i != cxt->iterations; i++) {
117     absl::ReaderMutexLock l(&cxt->mu);
118     absl::SleepFor(absl::Milliseconds(20));
119     cxt->mu.AssertReaderHeld();
120   }
121 }
122 
TestRW(TestContext * cxt,int c)123 static void TestRW(TestContext *cxt, int c) {
124   if ((c & 1) == 0) {
125     for (int i = 0; i != cxt->iterations; i++) {
126       absl::WriterMutexLock l(&cxt->mu);
127       cxt->g0++;
128       cxt->g1--;
129       cxt->mu.AssertHeld();
130       cxt->mu.AssertReaderHeld();
131     }
132   } else {
133     for (int i = 0; i != cxt->iterations; i++) {
134       absl::ReaderMutexLock l(&cxt->mu);
135       ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW");
136       cxt->mu.AssertReaderHeld();
137     }
138   }
139 }
140 
141 struct MyContext {
142   int target;
143   TestContext *cxt;
144   bool MyTurn();
145 };
146 
MyTurn()147 bool MyContext::MyTurn() {
148   TestContext *cxt = this->cxt;
149   return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
150 }
151 
TestAwait(TestContext * cxt,int c)152 static void TestAwait(TestContext *cxt, int c) {
153   MyContext mc;
154   mc.target = c;
155   mc.cxt = cxt;
156   absl::MutexLock l(&cxt->mu);
157   cxt->mu.AssertHeld();
158   while (cxt->g0 < cxt->iterations) {
159     cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
160     ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait");
161     cxt->mu.AssertHeld();
162     if (cxt->g0 < cxt->iterations) {
163       int a = cxt->g0 + 1;
164       cxt->g0 = a;
165       mc.target += cxt->threads;
166     }
167   }
168 }
169 
TestSignalAll(TestContext * cxt,int c)170 static void TestSignalAll(TestContext *cxt, int c) {
171   int target = c;
172   absl::MutexLock l(&cxt->mu);
173   cxt->mu.AssertHeld();
174   while (cxt->g0 < cxt->iterations) {
175     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
176       cxt->cv.Wait(&cxt->mu);
177     }
178     if (cxt->g0 < cxt->iterations) {
179       int a = cxt->g0 + 1;
180       cxt->g0 = a;
181       cxt->cv.SignalAll();
182       target += cxt->threads;
183     }
184   }
185 }
186 
TestSignal(TestContext * cxt,int c)187 static void TestSignal(TestContext *cxt, int c) {
188   ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads");
189   int target = c;
190   absl::MutexLock l(&cxt->mu);
191   cxt->mu.AssertHeld();
192   while (cxt->g0 < cxt->iterations) {
193     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
194       cxt->cv.Wait(&cxt->mu);
195     }
196     if (cxt->g0 < cxt->iterations) {
197       int a = cxt->g0 + 1;
198       cxt->g0 = a;
199       cxt->cv.Signal();
200       target += cxt->threads;
201     }
202   }
203 }
204 
TestCVTimeout(TestContext * cxt,int c)205 static void TestCVTimeout(TestContext *cxt, int c) {
206   int target = c;
207   absl::MutexLock l(&cxt->mu);
208   cxt->mu.AssertHeld();
209   while (cxt->g0 < cxt->iterations) {
210     while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
211       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
212     }
213     if (cxt->g0 < cxt->iterations) {
214       int a = cxt->g0 + 1;
215       cxt->g0 = a;
216       cxt->cv.SignalAll();
217       target += cxt->threads;
218     }
219   }
220 }
221 
G0GE2(TestContext * cxt)222 static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }
223 
TestTime(TestContext * cxt,int c,bool use_cv)224 static void TestTime(TestContext *cxt, int c, bool use_cv) {
225   ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration");
226   ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads");
227   const bool kFalse = false;
228   absl::Condition false_cond(&kFalse);
229   absl::Condition g0ge2(G0GE2, cxt);
230   if (c == 0) {
231     absl::MutexLock l(&cxt->mu);
232 
233     absl::Time start = absl::Now();
234     if (use_cv) {
235       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
236     } else {
237       ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
238                      "TestTime failed");
239     }
240     absl::Duration elapsed = absl::Now() - start;
241     ABSL_RAW_CHECK(
242         absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
243         "TestTime failed");
244     ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed");
245 
246     start = absl::Now();
247     if (use_cv) {
248       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
249     } else {
250       ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
251                      "TestTime failed");
252     }
253     elapsed = absl::Now() - start;
254     ABSL_RAW_CHECK(
255         absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
256         "TestTime failed");
257     cxt->g0++;
258     if (use_cv) {
259       cxt->cv.Signal();
260     }
261 
262     start = absl::Now();
263     if (use_cv) {
264       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
265     } else {
266       ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)),
267                      "TestTime failed");
268     }
269     elapsed = absl::Now() - start;
270     ABSL_RAW_CHECK(
271         absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0),
272         "TestTime failed");
273     ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed");
274 
275     start = absl::Now();
276     if (use_cv) {
277       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
278     } else {
279       ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
280                      "TestTime failed");
281     }
282     elapsed = absl::Now() - start;
283     ABSL_RAW_CHECK(
284         absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
285         "TestTime failed");
286     if (use_cv) {
287       cxt->cv.SignalAll();
288     }
289 
290     start = absl::Now();
291     if (use_cv) {
292       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
293     } else {
294       ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
295                      "TestTime failed");
296     }
297     elapsed = absl::Now() - start;
298     ABSL_RAW_CHECK(
299         absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
300         "TestTime failed");
301     ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed");
302 
303   } else if (c == 1) {
304     absl::MutexLock l(&cxt->mu);
305     const absl::Time start = absl::Now();
306     if (use_cv) {
307       cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
308     } else {
309       ABSL_RAW_CHECK(
310           !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)),
311           "TestTime failed");
312     }
313     const absl::Duration elapsed = absl::Now() - start;
314     ABSL_RAW_CHECK(
315         absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9),
316         "TestTime failed");
317     cxt->g0++;
318   } else if (c == 2) {
319     absl::MutexLock l(&cxt->mu);
320     if (use_cv) {
321       while (cxt->g0 < 2) {
322         cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
323       }
324     } else {
325       ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)),
326                      "TestTime failed");
327     }
328     cxt->g0++;
329   } else {
330     absl::MutexLock l(&cxt->mu);
331     if (use_cv) {
332       while (cxt->g0 < 2) {
333         cxt->cv.Wait(&cxt->mu);
334       }
335     } else {
336       cxt->mu.Await(g0ge2);
337     }
338     cxt->g0++;
339   }
340 }
341 
TestMuTime(TestContext * cxt,int c)342 static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); }
343 
TestCVTime(TestContext * cxt,int c)344 static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }
345 
EndTest(int * c0,int * c1,absl::Mutex * mu,absl::CondVar * cv,const std::function<void (int)> & cb)346 static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
347                     const std::function<void(int)> &cb) {
348   mu->Lock();
349   int c = (*c0)++;
350   mu->Unlock();
351   cb(c);
352   absl::MutexLock l(mu);
353   (*c1)++;
354   cv->Signal();
355 }
356 
357 // Code common to RunTest() and RunTestWithInvariantDebugging().
RunTestCommon(TestContext * cxt,void (* test)(TestContext * cxt,int),int threads,int iterations,int operations)358 static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
359                          int threads, int iterations, int operations) {
360   absl::Mutex mu2;
361   absl::CondVar cv2;
362   int c0 = 0;
363   int c1 = 0;
364   cxt->g0 = 0;
365   cxt->g1 = 0;
366   cxt->iterations = iterations;
367   cxt->threads = threads;
368   absl::synchronization_internal::ThreadPool tp(threads);
369   for (int i = 0; i != threads; i++) {
370     tp.Schedule(std::bind(
371         &EndTest, &c0, &c1, &mu2, &cv2,
372         std::function<void(int)>(std::bind(test, cxt, std::placeholders::_1))));
373   }
374   mu2.Lock();
375   while (c1 != threads) {
376     cv2.Wait(&mu2);
377   }
378   mu2.Unlock();
379   return cxt->g0;
380 }
381 
382 // Basis for the parameterized tests configured below.
RunTest(void (* test)(TestContext * cxt,int),int threads,int iterations,int operations)383 static int RunTest(void (*test)(TestContext *cxt, int), int threads,
384                    int iterations, int operations) {
385   TestContext cxt;
386   return RunTestCommon(&cxt, test, threads, iterations, operations);
387 }
388 
389 // Like RunTest(), but sets an invariant on the tested Mutex and
390 // verifies that the invariant check happened. The invariant function
391 // will be passed the TestContext* as its arg and must call
392 // SetInvariantChecked(true);
393 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
RunTestWithInvariantDebugging(void (* test)(TestContext * cxt,int),int threads,int iterations,int operations,void (* invariant)(void *))394 static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
395                                          int threads, int iterations,
396                                          int operations,
397                                          void (*invariant)(void *)) {
398   absl::EnableMutexInvariantDebugging(true);
399   SetInvariantChecked(false);
400   TestContext cxt;
401   cxt.mu.EnableInvariantDebugging(invariant, &cxt);
402   int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
403   ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
404   absl::EnableMutexInvariantDebugging(false);  // Restore.
405   return ret;
406 }
407 #endif
408 
409 // --------------------------------------------------------
410 // Test for fix of bug in TryRemove()
411 struct TimeoutBugStruct {
412   absl::Mutex mu;
413   bool a;
414   int a_waiter_count;
415 };
416 
WaitForA(TimeoutBugStruct * x)417 static void WaitForA(TimeoutBugStruct *x) {
418   x->mu.LockWhen(absl::Condition(&x->a));
419   x->a_waiter_count--;
420   x->mu.Unlock();
421 }
422 
NoAWaiters(TimeoutBugStruct * x)423 static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }
424 
425 // Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in
426 // another thread.
TEST(Mutex,CondVarWaitSignalsAwait)427 TEST(Mutex, CondVarWaitSignalsAwait) {
428   // Use a struct so the lock annotations apply.
429   struct {
430     absl::Mutex barrier_mu;
431     bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
432 
433     absl::Mutex release_mu;
434     bool release ABSL_GUARDED_BY(release_mu) = false;
435     absl::CondVar released_cv;
436   } state;
437 
438   auto pool = CreateDefaultPool();
439 
440   // Thread A.  Sets barrier, waits for release using Mutex::Await, then
441   // signals released_cv.
442   pool->Schedule([&state] {
443     state.release_mu.Lock();
444 
445     state.barrier_mu.Lock();
446     state.barrier = true;
447     state.barrier_mu.Unlock();
448 
449     state.release_mu.Await(absl::Condition(&state.release));
450     state.released_cv.Signal();
451     state.release_mu.Unlock();
452   });
453 
454   state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
455   state.barrier_mu.Unlock();
456   state.release_mu.Lock();
457   // Thread A is now blocked on release by way of Mutex::Await().
458 
459   // Set release.  Calling released_cv.Wait() should un-block thread A,
460   // which will signal released_cv.  If not, the test will hang.
461   state.release = true;
462   state.released_cv.Wait(&state.release_mu);
463   state.release_mu.Unlock();
464 }
465 
466 // Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
467 // mutex.Await() in another thread.
TEST(Mutex,CondVarWaitWithTimeoutSignalsAwait)468 TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
469   // Use a struct so the lock annotations apply.
470   struct {
471     absl::Mutex barrier_mu;
472     bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
473 
474     absl::Mutex release_mu;
475     bool release ABSL_GUARDED_BY(release_mu) = false;
476     absl::CondVar released_cv;
477   } state;
478 
479   auto pool = CreateDefaultPool();
480 
481   // Thread A.  Sets barrier, waits for release using Mutex::Await, then
482   // signals released_cv.
483   pool->Schedule([&state] {
484     state.release_mu.Lock();
485 
486     state.barrier_mu.Lock();
487     state.barrier = true;
488     state.barrier_mu.Unlock();
489 
490     state.release_mu.Await(absl::Condition(&state.release));
491     state.released_cv.Signal();
492     state.release_mu.Unlock();
493   });
494 
495   state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
496   state.barrier_mu.Unlock();
497   state.release_mu.Lock();
498   // Thread A is now blocked on release by way of Mutex::Await().
499 
500   // Set release.  Calling released_cv.Wait() should un-block thread A,
501   // which will signal released_cv.  If not, the test will hang.
502   state.release = true;
503   EXPECT_TRUE(
504       !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10)))
505       << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
506          "unblock the absl::Mutex::Await call in another thread.";
507 
508   state.release_mu.Unlock();
509 }
510 
511 // Test for regression of a bug in loop of TryRemove()
TEST(Mutex,MutexTimeoutBug)512 TEST(Mutex, MutexTimeoutBug) {
513   auto tp = CreateDefaultPool();
514 
515   TimeoutBugStruct x;
516   x.a = false;
517   x.a_waiter_count = 2;
518   tp->Schedule(std::bind(&WaitForA, &x));
519   tp->Schedule(std::bind(&WaitForA, &x));
520   absl::SleepFor(absl::Seconds(1));  // Allow first two threads to hang.
521   // The skip field of the second will point to the first because there are
522   // only two.
523 
524   // Now cause a thread waiting on an always-false to time out
525   // This would deadlock when the bug was present.
526   bool always_false = false;
527   x.mu.LockWhenWithTimeout(absl::Condition(&always_false),
528                            absl::Milliseconds(500));
529 
530   // if we get here, the bug is not present.   Cleanup the state.
531 
532   x.a = true;                                    // wakeup the two waiters on A
533   x.mu.Await(absl::Condition(&NoAWaiters, &x));  // wait for them to exit
534   x.mu.Unlock();
535 }
536 
537 struct CondVarWaitDeadlock : testing::TestWithParam<int> {
538   absl::Mutex mu;
539   absl::CondVar cv;
540   bool cond1 = false;
541   bool cond2 = false;
542   bool read_lock1;
543   bool read_lock2;
544   bool signal_unlocked;
545 
CondVarWaitDeadlock__anond497c4540111::CondVarWaitDeadlock546   CondVarWaitDeadlock() {
547     read_lock1 = GetParam() & (1 << 0);
548     read_lock2 = GetParam() & (1 << 1);
549     signal_unlocked = GetParam() & (1 << 2);
550   }
551 
Waiter1__anond497c4540111::CondVarWaitDeadlock552   void Waiter1() {
553     if (read_lock1) {
554       mu.ReaderLock();
555       while (!cond1) {
556         cv.Wait(&mu);
557       }
558       mu.ReaderUnlock();
559     } else {
560       mu.Lock();
561       while (!cond1) {
562         cv.Wait(&mu);
563       }
564       mu.Unlock();
565     }
566   }
567 
Waiter2__anond497c4540111::CondVarWaitDeadlock568   void Waiter2() {
569     if (read_lock2) {
570       mu.ReaderLockWhen(absl::Condition(&cond2));
571       mu.ReaderUnlock();
572     } else {
573       mu.LockWhen(absl::Condition(&cond2));
574       mu.Unlock();
575     }
576   }
577 };
578 
579 // Test for a deadlock bug in Mutex::Fer().
580 // The sequence of events that lead to the deadlock is:
581 // 1. waiter1 blocks on cv in read mode (mu bits = 0).
582 // 2. waiter2 blocks on mu in either mode (mu bits = kMuWait).
583 // 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait).
584 // 4. main thread signals on cv and this eventually calls Mutex::Fer().
585 // Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked).
586 // Before the bug fix Fer neither woke waiter1 nor queued it on mutex,
587 // which resulted in deadlock.
TEST_P(CondVarWaitDeadlock,Test)588 TEST_P(CondVarWaitDeadlock, Test) {
589   auto waiter1 = CreatePool(1);
590   auto waiter2 = CreatePool(1);
591   waiter1->Schedule([this] { this->Waiter1(); });
592   waiter2->Schedule([this] { this->Waiter2(); });
593 
594   // Wait while threads block (best-effort is fine).
595   absl::SleepFor(absl::Milliseconds(100));
596 
597   // Wake condwaiter.
598   mu.Lock();
599   cond1 = true;
600   if (signal_unlocked) {
601     mu.Unlock();
602     cv.Signal();
603   } else {
604     cv.Signal();
605     mu.Unlock();
606   }
607   waiter1.reset();  // "join" waiter1
608 
609   // Wake waiter.
610   mu.Lock();
611   cond2 = true;
612   mu.Unlock();
613   waiter2.reset();  // "join" waiter2
614 }
615 
616 INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
617                          ::testing::Range(0, 8),
618                          ::testing::PrintToStringParamName());
619 
620 // --------------------------------------------------------
621 // Test for fix of bug in DequeueAllWakeable()
622 // Bug was that if there was more than one waiting reader
623 // and all should be woken, the most recently blocked one
624 // would not be.
625 
626 struct DequeueAllWakeableBugStruct {
627   absl::Mutex mu;
628   absl::Mutex mu2;       // protects all fields below
629   int unfinished_count;  // count of unfinished readers; under mu2
630   bool done1;            // unfinished_count == 0; under mu2
631   int finished_count;    // count of finished readers, under mu2
632   bool done2;            // finished_count == 0; under mu2
633 };
634 
635 // Test for regression of a bug in loop of DequeueAllWakeable()
AcquireAsReader(DequeueAllWakeableBugStruct * x)636 static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
637   x->mu.ReaderLock();
638   x->mu2.Lock();
639   x->unfinished_count--;
640   x->done1 = (x->unfinished_count == 0);
641   x->mu2.Unlock();
642   // make sure that both readers acquired mu before we release it.
643   absl::SleepFor(absl::Seconds(2));
644   x->mu.ReaderUnlock();
645 
646   x->mu2.Lock();
647   x->finished_count--;
648   x->done2 = (x->finished_count == 0);
649   x->mu2.Unlock();
650 }
651 
652 // Test for regression of a bug in loop of DequeueAllWakeable()
TEST(Mutex,MutexReaderWakeupBug)653 TEST(Mutex, MutexReaderWakeupBug) {
654   auto tp = CreateDefaultPool();
655 
656   DequeueAllWakeableBugStruct x;
657   x.unfinished_count = 2;
658   x.done1 = false;
659   x.finished_count = 2;
660   x.done2 = false;
661   x.mu.Lock();  // acquire mu exclusively
662   // queue two thread that will block on reader locks on x.mu
663   tp->Schedule(std::bind(&AcquireAsReader, &x));
664   tp->Schedule(std::bind(&AcquireAsReader, &x));
665   absl::SleepFor(absl::Seconds(1));  // give time for reader threads to block
666   x.mu.Unlock();                     // wake them up
667 
668   // both readers should finish promptly
669   EXPECT_TRUE(
670       x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
671   x.mu2.Unlock();
672 
673   EXPECT_TRUE(
674       x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
675   x.mu2.Unlock();
676 }
677 
678 struct LockWhenTestStruct {
679   absl::Mutex mu1;
680   bool cond = false;
681 
682   absl::Mutex mu2;
683   bool waiting = false;
684 };
685 
LockWhenTestIsCond(LockWhenTestStruct * s)686 static bool LockWhenTestIsCond(LockWhenTestStruct *s) {
687   s->mu2.Lock();
688   s->waiting = true;
689   s->mu2.Unlock();
690   return s->cond;
691 }
692 
LockWhenTestWaitForIsCond(LockWhenTestStruct * s)693 static void LockWhenTestWaitForIsCond(LockWhenTestStruct *s) {
694   s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
695   s->mu1.Unlock();
696 }
697 
TEST(Mutex,LockWhen)698 TEST(Mutex, LockWhen) {
699   LockWhenTestStruct s;
700 
701   std::thread t(LockWhenTestWaitForIsCond, &s);
702   s.mu2.LockWhen(absl::Condition(&s.waiting));
703   s.mu2.Unlock();
704 
705   s.mu1.Lock();
706   s.cond = true;
707   s.mu1.Unlock();
708 
709   t.join();
710 }
711 
TEST(Mutex,LockWhenGuard)712 TEST(Mutex, LockWhenGuard) {
713   absl::Mutex mu;
714   int n = 30;
715   bool done = false;
716 
717   // We don't inline the lambda because the conversion is ambiguous in MSVC.
718   bool (*cond_eq_10)(int *) = [](int *p) { return *p == 10; };
719   bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; };
720 
721   std::thread t1([&mu, &n, &done, cond_eq_10]() {
722     absl::ReaderMutexLock lock(&mu, absl::Condition(cond_eq_10, &n));
723     done = true;
724   });
725 
726   std::thread t2[10];
727   for (std::thread &t : t2) {
728     t = std::thread([&mu, &n, cond_lt_10]() {
729       absl::WriterMutexLock lock(&mu, absl::Condition(cond_lt_10, &n));
730       ++n;
731     });
732   }
733 
734   {
735     absl::MutexLock lock(&mu);
736     n = 0;
737   }
738 
739   for (std::thread &t : t2) t.join();
740   t1.join();
741 
742   EXPECT_TRUE(done);
743   EXPECT_EQ(n, 10);
744 }
745 
746 // --------------------------------------------------------
747 // The following test requires Mutex::ReaderLock to be a real shared
748 // lock, which is not the case in all builds.
749 #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
750 
751 // Test for fix of bug in UnlockSlow() that incorrectly decremented the reader
752 // count when putting a thread to sleep waiting for a false condition when the
753 // lock was not held.
754 
755 // For this bug to strike, we make a thread wait on a free mutex with no
756 // waiters by causing its wakeup condition to be false.   Then the
757 // next two acquirers must be readers.   The bug causes the lock
758 // to be released when one reader unlocks, rather than both.
759 
760 struct ReaderDecrementBugStruct {
761   bool cond;  // to delay first thread (under mu)
762   int done;   // reference count (under mu)
763   absl::Mutex mu;
764 
765   bool waiting_on_cond;   // under mu2
766   bool have_reader_lock;  // under mu2
767   bool complete;          // under mu2
768   absl::Mutex mu2;        // > mu
769 };
770 
771 // L >= mu, L < mu_waiting_on_cond
IsCond(void * v)772 static bool IsCond(void *v) {
773   ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
774   x->mu2.Lock();
775   x->waiting_on_cond = true;
776   x->mu2.Unlock();
777   return x->cond;
778 }
779 
780 // L >= mu
AllDone(void * v)781 static bool AllDone(void *v) {
782   ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
783   return x->done == 0;
784 }
785 
786 // L={}
WaitForCond(ReaderDecrementBugStruct * x)787 static void WaitForCond(ReaderDecrementBugStruct *x) {
788   absl::Mutex dummy;
789   absl::MutexLock l(&dummy);
790   x->mu.LockWhen(absl::Condition(&IsCond, x));
791   x->done--;
792   x->mu.Unlock();
793 }
794 
795 // L={}
GetReadLock(ReaderDecrementBugStruct * x)796 static void GetReadLock(ReaderDecrementBugStruct *x) {
797   x->mu.ReaderLock();
798   x->mu2.Lock();
799   x->have_reader_lock = true;
800   x->mu2.Await(absl::Condition(&x->complete));
801   x->mu2.Unlock();
802   x->mu.ReaderUnlock();
803   x->mu.Lock();
804   x->done--;
805   x->mu.Unlock();
806 }
807 
808 // Test for reader counter being decremented incorrectly by waiter
809 // with false condition.
TEST(Mutex,MutexReaderDecrementBug)810 TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
811   ReaderDecrementBugStruct x;
812   x.cond = false;
813   x.waiting_on_cond = false;
814   x.have_reader_lock = false;
815   x.complete = false;
816   x.done = 2;  // initial ref count
817 
818   // Run WaitForCond() and wait for it to sleep
819   std::thread thread1(WaitForCond, &x);
820   x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
821   x.mu2.Unlock();
822 
823   // Run GetReadLock(), and wait for it to get the read lock
824   std::thread thread2(GetReadLock, &x);
825   x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
826   x.mu2.Unlock();
827 
828   // Get the reader lock ourselves, and release it.
829   x.mu.ReaderLock();
830   x.mu.ReaderUnlock();
831 
832   // The lock should be held in read mode by GetReadLock().
833   // If we have the bug, the lock will be free.
834   x.mu.AssertReaderHeld();
835 
836   // Wake up all the threads.
837   x.mu2.Lock();
838   x.complete = true;
839   x.mu2.Unlock();
840 
841   // TODO(delesley): turn on analysis once lock upgrading is supported.
842   // (This call upgrades the lock from shared to exclusive.)
843   x.mu.Lock();
844   x.cond = true;
845   x.mu.Await(absl::Condition(&AllDone, &x));
846   x.mu.Unlock();
847 
848   thread1.join();
849   thread2.join();
850 }
851 #endif  // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE
852 
853 // Test that we correctly handle the situation when a lock is
854 // held and then destroyed (w/o unlocking).
855 #ifdef ABSL_HAVE_THREAD_SANITIZER
856 // TSAN reports errors when locked Mutexes are destroyed.
TEST(Mutex,DISABLED_LockedMutexDestructionBug)857 TEST(Mutex, DISABLED_LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
858 #else
859 TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
860 #endif
861   for (int i = 0; i != 10; i++) {
862     // Create, lock and destroy 10 locks.
863     const int kNumLocks = 10;
864     auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks);
865     for (int j = 0; j != kNumLocks; j++) {
866       if ((j % 2) == 0) {
867         mu[j].WriterLock();
868       } else {
869         mu[j].ReaderLock();
870       }
871     }
872   }
873 }
874 
875 struct True {
876   template <class... Args>
877   bool operator()(Args...) const {
878     return true;
879   }
880 };
881 
882 struct DerivedTrue : True {};
883 
884 TEST(Mutex, FunctorCondition) {
885   {  // Variadic
886     True f;
887     EXPECT_TRUE(absl::Condition(&f).Eval());
888   }
889 
890   {  // Inherited
891     DerivedTrue g;
892     EXPECT_TRUE(absl::Condition(&g).Eval());
893   }
894 
895   {  // lambda
896     int value = 3;
897     auto is_zero = [&value] { return value == 0; };
898     absl::Condition c(&is_zero);
899     EXPECT_FALSE(c.Eval());
900     value = 0;
901     EXPECT_TRUE(c.Eval());
902   }
903 
904   {  // bind
905     int value = 0;
906     auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
907     absl::Condition c(&is_positive);
908     EXPECT_FALSE(c.Eval());
909     value = 1;
910     EXPECT_TRUE(c.Eval());
911   }
912 
913   {  // std::function
914     int value = 3;
915     std::function<bool()> is_zero = [&value] { return value == 0; };
916     absl::Condition c(&is_zero);
917     EXPECT_FALSE(c.Eval());
918     value = 0;
919     EXPECT_TRUE(c.Eval());
920   }
921 }
922 
923 // --------------------------------------------------------
924 // Test for bug with pattern of readers using a condvar.  The bug was that if a
925 // reader went to sleep on a condition variable while one or more other readers
926 // held the lock, but there were no waiters, the reader count (held in the
927 // mutex word) would be lost.  (This is because Enqueue() had at one time
928 // always placed the thread on the Mutex queue.  Later (CL 4075610), to
929 // tolerate re-entry into Mutex from a Condition predicate, Enqueue() was
930 // changed so that it could also place a thread on a condition-variable.  This
931 // introduced the case where Enqueue() returned with an empty queue, and this
932 // case was handled incorrectly in one place.)
933 
934 static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
935                                      int *running) {
936   std::random_device dev;
937   std::mt19937 gen(dev());
938   std::uniform_int_distribution<int> random_millis(0, 15);
939   mu->ReaderLock();
940   while (*running == 3) {
941     absl::SleepFor(absl::Milliseconds(random_millis(gen)));
942     cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
943   }
944   mu->ReaderUnlock();
945   mu->Lock();
946   (*running)--;
947   mu->Unlock();
948 }
949 
950 static bool IntIsZero(int *x) { return *x == 0; }
951 
952 // Test for reader waiting condition variable when there are other readers
953 // but no waiters.
954 TEST(Mutex, TestReaderOnCondVar) {
955   auto tp = CreateDefaultPool();
956   absl::Mutex mu;
957   absl::CondVar cv;
958   int running = 3;
959   tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
960   tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
961   absl::SleepFor(absl::Seconds(2));
962   mu.Lock();
963   running--;
964   mu.Await(absl::Condition(&IntIsZero, &running));
965   mu.Unlock();
966 }
967 
968 // --------------------------------------------------------
969 struct AcquireFromConditionStruct {
970   absl::Mutex mu0;   // protects value, done
971   int value;         // times condition function is called; under mu0,
972   bool done;         // done with test?  under mu0
973   absl::Mutex mu1;   // used to attempt to mess up state of mu0
974   absl::CondVar cv;  // so the condition function can be invoked from
975                      // CondVar::Wait().
976 };
977 
978 static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
979   x->value++;  // count times this function is called
980 
981   if (x->value == 2 || x->value == 3) {
982     // On the second and third invocation of this function, sleep for 100ms,
983     // but with the side-effect of altering the state of a Mutex other than
984     // than one for which this is a condition.  The spec now explicitly allows
985     // this side effect; previously it did not.  it was illegal.
986     bool always_false = false;
987     x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
988                                absl::Milliseconds(100));
989     x->mu1.Unlock();
990   }
991   ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time");
992 
993   // We arrange for the condition to return true on only the 2nd and 3rd calls.
994   return x->value == 2 || x->value == 3;
995 }
996 
997 static void WaitForCond2(AcquireFromConditionStruct *x) {
998   // wait for cond0 to become true
999   x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
1000   x->done = true;
1001   x->mu0.Unlock();
1002 }
1003 
1004 // Test for Condition whose function acquires other Mutexes
1005 TEST(Mutex, AcquireFromCondition) {
1006   auto tp = CreateDefaultPool();
1007 
1008   AcquireFromConditionStruct x;
1009   x.value = 0;
1010   x.done = false;
1011   tp->Schedule(
1012       std::bind(&WaitForCond2, &x));  // run WaitForCond2() in a thread T
1013   // T will hang because the first invocation of ConditionWithAcquire() will
1014   // return false.
1015   absl::SleepFor(absl::Milliseconds(500));  // allow T time to hang
1016 
1017   x.mu0.Lock();
1018   x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500));  // wake T
1019   // T will be woken because the Wait() will call ConditionWithAcquire()
1020   // for the second time, and it will return true.
1021 
1022   x.mu0.Unlock();
1023 
1024   // T will then acquire the lock and recheck its own condition.
1025   // It will find the condition true, as this is the third invocation,
1026   // but the use of another Mutex by the calling function will
1027   // cause the old mutex implementation to think that the outer
1028   // LockWhen() has timed out because the inner LockWhenWithTimeout() did.
1029   // T will then check the condition a fourth time because it finds a
1030   // timeout occurred.  This should not happen in the new
1031   // implementation that allows the Condition function to use Mutexes.
1032 
1033   // It should also succeed, even though the Condition function
1034   // is being invoked from CondVar::Wait, and thus this thread
1035   // is conceptually waiting both on the condition variable, and on mu2.
1036 
1037   x.mu0.LockWhen(absl::Condition(&x.done));
1038   x.mu0.Unlock();
1039 }
1040 
1041 TEST(Mutex, DeadlockDetector) {
1042   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1043 
1044   // check that we can call ForgetDeadlockInfo() on a lock with the lock held
1045   absl::Mutex m1;
1046   absl::Mutex m2;
1047   absl::Mutex m3;
1048   absl::Mutex m4;
1049 
1050   m1.Lock();  // m1 gets ID1
1051   m2.Lock();  // m2 gets ID2
1052   m3.Lock();  // m3 gets ID3
1053   m3.Unlock();
1054   m2.Unlock();
1055   // m1 still held
1056   m1.ForgetDeadlockInfo();  // m1 loses ID
1057   m2.Lock();                // m2 gets ID2
1058   m3.Lock();                // m3 gets ID3
1059   m4.Lock();                // m4 gets ID4
1060   m3.Unlock();
1061   m2.Unlock();
1062   m4.Unlock();
1063   m1.Unlock();
1064 }
1065 
1066 // Bazel has a test "warning" file that programs can write to if the
1067 // test should pass with a warning.  This class disables the warning
1068 // file until it goes out of scope.
1069 class ScopedDisableBazelTestWarnings {
1070  public:
1071   ScopedDisableBazelTestWarnings() {
1072 #ifdef _WIN32
1073     char file[MAX_PATH];
1074     if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
1075       warnings_output_file_ = file;
1076       SetEnvironmentVariableA(kVarName, nullptr);
1077     }
1078 #else
1079     const char *file = getenv(kVarName);
1080     if (file != nullptr) {
1081       warnings_output_file_ = file;
1082       unsetenv(kVarName);
1083     }
1084 #endif
1085   }
1086 
1087   ~ScopedDisableBazelTestWarnings() {
1088     if (!warnings_output_file_.empty()) {
1089 #ifdef _WIN32
1090       SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
1091 #else
1092       setenv(kVarName, warnings_output_file_.c_str(), 0);
1093 #endif
1094     }
1095   }
1096 
1097  private:
1098   static const char kVarName[];
1099   std::string warnings_output_file_;
1100 };
1101 const char ScopedDisableBazelTestWarnings::kVarName[] =
1102     "TEST_WARNINGS_OUTPUT_FILE";
1103 
1104 #ifdef ABSL_HAVE_THREAD_SANITIZER
1105 // This test intentionally creates deadlocks to test the deadlock detector.
1106 TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
1107 #else
1108 TEST(Mutex, DeadlockDetectorBazelWarning) {
1109 #endif
1110   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);
1111 
1112   // Cause deadlock detection to detect something, if it's
1113   // compiled in and enabled.  But turn off the bazel warning.
1114   ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
1115 
1116   absl::Mutex mu0;
1117   absl::Mutex mu1;
1118   bool got_mu0 = mu0.TryLock();
1119   mu1.Lock();  // acquire mu1 while holding mu0
1120   if (got_mu0) {
1121     mu0.Unlock();
1122   }
1123   if (mu0.TryLock()) {  // try lock shouldn't cause deadlock detector to fire
1124     mu0.Unlock();
1125   }
1126   mu0.Lock();  // acquire mu0 while holding mu1; should get one deadlock
1127                // report here
1128   mu0.Unlock();
1129   mu1.Unlock();
1130 
1131   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1132 }
1133 
1134 // This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the
1135 // annotation-based static thread-safety analysis is not currently
1136 // predicate-aware and cannot tell if the two for-loops that acquire and
1137 // release the locks have the same predicates.
1138 TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1139   // Stress test: Here we create a large number of locks and use all of them.
1140   // If a deadlock detector keeps a full graph of lock acquisition order,
1141   // it will likely be too slow for this test to pass.
1142   const int n_locks = 1 << 17;
1143   auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks);
1144   for (int i = 0; i < n_locks; i++) {
1145     int end = std::min(n_locks, i + 5);
1146     // acquire and then release locks i, i+1, ..., i+4
1147     for (int j = i; j < end; j++) {
1148       array_of_locks[j].Lock();
1149     }
1150     for (int j = i; j < end; j++) {
1151       array_of_locks[j].Unlock();
1152     }
1153   }
1154 }
1155 
1156 #ifdef ABSL_HAVE_THREAD_SANITIZER
1157 // TSAN reports errors when locked Mutexes are destroyed.
1158 TEST(Mutex, DISABLED_DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1159 #else
1160 TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1161 #endif
1162   // Test a scenario where a cached deadlock graph node id in the
1163   // list of held locks is not invalidated when the corresponding
1164   // mutex is deleted.
1165   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1166   // Mutex that will be destroyed while being held
1167   absl::Mutex *a = new absl::Mutex;
1168   // Other mutexes needed by test
1169   absl::Mutex b, c;
1170 
1171   // Hold mutex.
1172   a->Lock();
1173 
1174   // Force deadlock id assignment by acquiring another lock.
1175   b.Lock();
1176   b.Unlock();
1177 
1178   // Delete the mutex. The Mutex destructor tries to remove held locks,
1179   // but the attempt isn't foolproof.  It can fail if:
1180   //   (a) Deadlock detection is currently disabled.
1181   //   (b) The destruction is from another thread.
1182   // We exploit (a) by temporarily disabling deadlock detection.
1183   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
1184   delete a;
1185   absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
1186 
1187   // Now acquire another lock which will force a deadlock id assignment.
1188   // We should end up getting assigned the same deadlock id that was
1189   // freed up when "a" was deleted, which will cause a spurious deadlock
1190   // report if the held lock entry for "a" was not invalidated.
1191   c.Lock();
1192   c.Unlock();
1193 }
1194 
1195 // --------------------------------------------------------
1196 // Test for timeouts/deadlines on condition waits that are specified using
1197 // absl::Duration and absl::Time.  For each waiting function we test with
1198 // a timeout/deadline that has already expired/passed, one that is infinite
1199 // and so never expires/passes, and one that will expire/pass in the near
1200 // future.
1201 
1202 static absl::Duration TimeoutTestAllowedSchedulingDelay() {
1203   // Note: we use a function here because Microsoft Visual Studio fails to
1204   // properly initialize constexpr static absl::Duration variables.
1205   return absl::Milliseconds(150);
1206 }
1207 
1208 // Returns true if `actual_delay` is close enough to `expected_delay` to pass
1209 // the timeouts/deadlines test.  Otherwise, logs warnings and returns false.
1210 ABSL_MUST_USE_RESULT
1211 static bool DelayIsWithinBounds(absl::Duration expected_delay,
1212                                 absl::Duration actual_delay) {
1213   bool pass = true;
1214   // Do not allow the observed delay to be less than expected.  This may occur
1215   // in practice due to clock skew or when the synchronization primitives use a
1216   // different clock than absl::Now(), but these cases should be handled by the
1217   // the retry mechanism in each TimeoutTest.
1218   if (actual_delay < expected_delay) {
1219     ABSL_RAW_LOG(WARNING,
1220                  "Actual delay %s was too short, expected %s (difference %s)",
1221                  absl::FormatDuration(actual_delay).c_str(),
1222                  absl::FormatDuration(expected_delay).c_str(),
1223                  absl::FormatDuration(actual_delay - expected_delay).c_str());
1224     pass = false;
1225   }
1226   // If the expected delay is <= zero then allow a small error tolerance, since
1227   // we do not expect context switches to occur during test execution.
1228   // Otherwise, thread scheduling delays may be substantial in rare cases, so
1229   // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
1230   absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
1231                                  ? absl::Milliseconds(10)
1232                                  : TimeoutTestAllowedSchedulingDelay();
1233   if (actual_delay > expected_delay + tolerance) {
1234     ABSL_RAW_LOG(WARNING,
1235                  "Actual delay %s was too long, expected %s (difference %s)",
1236                  absl::FormatDuration(actual_delay).c_str(),
1237                  absl::FormatDuration(expected_delay).c_str(),
1238                  absl::FormatDuration(actual_delay - expected_delay).c_str());
1239     pass = false;
1240   }
1241   return pass;
1242 }
1243 
1244 // Parameters for TimeoutTest, below.
1245 struct TimeoutTestParam {
1246   // The file and line number (used for logging purposes only).
1247   const char *from_file;
1248   int from_line;
1249 
1250   // Should the absolute deadline API based on absl::Time be tested?  If false,
1251   // the relative deadline API based on absl::Duration is tested.
1252   bool use_absolute_deadline;
1253 
1254   // The deadline/timeout used when calling the API being tested
1255   // (e.g. Mutex::LockWhenWithDeadline).
1256   absl::Duration wait_timeout;
1257 
1258   // The delay before the condition will be set true by the test code.  If zero
1259   // or negative, the condition is set true immediately (before calling the API
1260   // being tested).  Otherwise, if infinite, the condition is never set true.
1261   // Otherwise a closure is scheduled for the future that sets the condition
1262   // true.
1263   absl::Duration satisfy_condition_delay;
1264 
1265   // The expected result of the condition after the call to the API being
1266   // tested. Generally `true` means the condition was true when the API returns,
1267   // `false` indicates an expected timeout.
1268   bool expected_result;
1269 
1270   // The expected delay before the API under test returns.  This is inherently
1271   // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
1272   // test keeps trying indefinitely until this constraint passes.
1273   absl::Duration expected_delay;
1274 };
1275 
1276 // Print a `TimeoutTestParam` to a debug log.
1277 std::ostream &operator<<(std::ostream &os, const TimeoutTestParam &param) {
1278   return os << "from: " << param.from_file << ":" << param.from_line
1279             << " use_absolute_deadline: "
1280             << (param.use_absolute_deadline ? "true" : "false")
1281             << " wait_timeout: " << param.wait_timeout
1282             << " satisfy_condition_delay: " << param.satisfy_condition_delay
1283             << " expected_result: "
1284             << (param.expected_result ? "true" : "false")
1285             << " expected_delay: " << param.expected_delay;
1286 }
1287 
1288 std::string FormatString(const TimeoutTestParam &param) {
1289   std::ostringstream os;
1290   os << param;
1291   return os.str();
1292 }
1293 
1294 // Like `thread::Executor::ScheduleAt` except:
1295 // a) Delays zero or negative are executed immediately in the current thread.
1296 // b) Infinite delays are never scheduled.
1297 // c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
1298 static void RunAfterDelay(absl::Duration delay,
1299                           absl::synchronization_internal::ThreadPool *pool,
1300                           const std::function<void()> &callback) {
1301   if (delay <= absl::ZeroDuration()) {
1302     callback();  // immediate
1303   } else if (delay != absl::InfiniteDuration()) {
1304     ScheduleAfter(pool, delay, callback);
1305   }
1306 }
1307 
1308 class TimeoutTest : public ::testing::Test,
1309                     public ::testing::WithParamInterface<TimeoutTestParam> {};
1310 
1311 std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
1312   // The `finite` delay is a finite, relatively short, delay.  We make it larger
1313   // than our allowed scheduling delay (slop factor) to avoid confusion when
1314   // diagnosing test failures.  The other constants here have clear meanings.
1315   const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
1316   const absl::Duration never = absl::InfiniteDuration();
1317   const absl::Duration negative = -absl::InfiniteDuration();
1318   const absl::Duration immediate = absl::ZeroDuration();
1319 
1320   // Every test case is run twice; once using the absolute deadline API and once
1321   // using the relative timeout API.
1322   std::vector<TimeoutTestParam> values;
1323   for (bool use_absolute_deadline : {false, true}) {
1324     // Tests with a negative timeout (deadline in the past), which should
1325     // immediately return current state of the condition.
1326 
1327     // The condition is already true:
1328     values.push_back(TimeoutTestParam{
1329         __FILE__, __LINE__, use_absolute_deadline,
1330         negative,   // wait_timeout
1331         immediate,  // satisfy_condition_delay
1332         true,       // expected_result
1333         immediate,  // expected_delay
1334     });
1335 
1336     // The condition becomes true, but the timeout has already expired:
1337     values.push_back(TimeoutTestParam{
1338         __FILE__, __LINE__, use_absolute_deadline,
1339         negative,  // wait_timeout
1340         finite,    // satisfy_condition_delay
1341         false,     // expected_result
1342         immediate  // expected_delay
1343     });
1344 
1345     // The condition never becomes true:
1346     values.push_back(TimeoutTestParam{
1347         __FILE__, __LINE__, use_absolute_deadline,
1348         negative,  // wait_timeout
1349         never,     // satisfy_condition_delay
1350         false,     // expected_result
1351         immediate  // expected_delay
1352     });
1353 
1354     // Tests with an infinite timeout (deadline in the infinite future), which
1355     // should only return when the condition becomes true.
1356 
1357     // The condition is already true:
1358     values.push_back(TimeoutTestParam{
1359         __FILE__, __LINE__, use_absolute_deadline,
1360         never,      // wait_timeout
1361         immediate,  // satisfy_condition_delay
1362         true,       // expected_result
1363         immediate   // expected_delay
1364     });
1365 
1366     // The condition becomes true before the (infinite) expiry:
1367     values.push_back(TimeoutTestParam{
1368         __FILE__, __LINE__, use_absolute_deadline,
1369         never,   // wait_timeout
1370         finite,  // satisfy_condition_delay
1371         true,    // expected_result
1372         finite,  // expected_delay
1373     });
1374 
1375     // Tests with a (small) finite timeout (deadline soon), with the condition
1376     // becoming true both before and after its expiry.
1377 
1378     // The condition is already true:
1379     values.push_back(TimeoutTestParam{
1380         __FILE__, __LINE__, use_absolute_deadline,
1381         never,      // wait_timeout
1382         immediate,  // satisfy_condition_delay
1383         true,       // expected_result
1384         immediate   // expected_delay
1385     });
1386 
1387     // The condition becomes true before the expiry:
1388     values.push_back(TimeoutTestParam{
1389         __FILE__, __LINE__, use_absolute_deadline,
1390         finite * 2,  // wait_timeout
1391         finite,      // satisfy_condition_delay
1392         true,        // expected_result
1393         finite       // expected_delay
1394     });
1395 
1396     // The condition becomes true, but the timeout has already expired:
1397     values.push_back(TimeoutTestParam{
1398         __FILE__, __LINE__, use_absolute_deadline,
1399         finite,      // wait_timeout
1400         finite * 2,  // satisfy_condition_delay
1401         false,       // expected_result
1402         finite       // expected_delay
1403     });
1404 
1405     // The condition never becomes true:
1406     values.push_back(TimeoutTestParam{
1407         __FILE__, __LINE__, use_absolute_deadline,
1408         finite,  // wait_timeout
1409         never,   // satisfy_condition_delay
1410         false,   // expected_result
1411         finite   // expected_delay
1412     });
1413   }
1414   return values;
1415 }
1416 
1417 // Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
1418 INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
1419                          testing::ValuesIn(MakeTimeoutTestParamValues()));
1420 
1421 TEST_P(TimeoutTest, Await) {
1422   const TimeoutTestParam params = GetParam();
1423   ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1424 
1425   // Because this test asserts bounds on scheduling delays it is flaky.  To
1426   // compensate it loops forever until it passes.  Failures express as test
1427   // timeouts, in which case the test log can be used to diagnose the issue.
1428   for (int attempt = 1;; ++attempt) {
1429     ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1430 
1431     absl::Mutex mu;
1432     bool value = false;  // condition value (under mu)
1433 
1434     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1435         CreateDefaultPool();
1436     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1437       absl::MutexLock l(&mu);
1438       value = true;
1439     });
1440 
1441     absl::MutexLock lock(&mu);
1442     absl::Time start_time = absl::Now();
1443     absl::Condition cond(&value);
1444     bool result =
1445         params.use_absolute_deadline
1446             ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
1447             : mu.AwaitWithTimeout(cond, params.wait_timeout);
1448     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1449       EXPECT_EQ(params.expected_result, result);
1450       break;
1451     }
1452   }
1453 }
1454 
1455 TEST_P(TimeoutTest, LockWhen) {
1456   const TimeoutTestParam params = GetParam();
1457   ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1458 
1459   // Because this test asserts bounds on scheduling delays it is flaky.  To
1460   // compensate it loops forever until it passes.  Failures express as test
1461   // timeouts, in which case the test log can be used to diagnose the issue.
1462   for (int attempt = 1;; ++attempt) {
1463     ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1464 
1465     absl::Mutex mu;
1466     bool value = false;  // condition value (under mu)
1467 
1468     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1469         CreateDefaultPool();
1470     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1471       absl::MutexLock l(&mu);
1472       value = true;
1473     });
1474 
1475     absl::Time start_time = absl::Now();
1476     absl::Condition cond(&value);
1477     bool result =
1478         params.use_absolute_deadline
1479             ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
1480             : mu.LockWhenWithTimeout(cond, params.wait_timeout);
1481     mu.Unlock();
1482 
1483     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1484       EXPECT_EQ(params.expected_result, result);
1485       break;
1486     }
1487   }
1488 }
1489 
1490 TEST_P(TimeoutTest, ReaderLockWhen) {
1491   const TimeoutTestParam params = GetParam();
1492   ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1493 
1494   // Because this test asserts bounds on scheduling delays it is flaky.  To
1495   // compensate it loops forever until it passes.  Failures express as test
1496   // timeouts, in which case the test log can be used to diagnose the issue.
1497   for (int attempt = 0;; ++attempt) {
1498     ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1499 
1500     absl::Mutex mu;
1501     bool value = false;  // condition value (under mu)
1502 
1503     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1504         CreateDefaultPool();
1505     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1506       absl::MutexLock l(&mu);
1507       value = true;
1508     });
1509 
1510     absl::Time start_time = absl::Now();
1511     bool result =
1512         params.use_absolute_deadline
1513             ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
1514                                             start_time + params.wait_timeout)
1515             : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
1516                                            params.wait_timeout);
1517     mu.ReaderUnlock();
1518 
1519     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1520       EXPECT_EQ(params.expected_result, result);
1521       break;
1522     }
1523   }
1524 }
1525 
1526 TEST_P(TimeoutTest, Wait) {
1527   const TimeoutTestParam params = GetParam();
1528   ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1529 
1530   // Because this test asserts bounds on scheduling delays it is flaky.  To
1531   // compensate it loops forever until it passes.  Failures express as test
1532   // timeouts, in which case the test log can be used to diagnose the issue.
1533   for (int attempt = 0;; ++attempt) {
1534     ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1535 
1536     absl::Mutex mu;
1537     bool value = false;  // condition value (under mu)
1538     absl::CondVar cv;    // signals a change of `value`
1539 
1540     std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1541         CreateDefaultPool();
1542     RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1543       absl::MutexLock l(&mu);
1544       value = true;
1545       cv.Signal();
1546     });
1547 
1548     absl::MutexLock lock(&mu);
1549     absl::Time start_time = absl::Now();
1550     absl::Duration timeout = params.wait_timeout;
1551     absl::Time deadline = start_time + timeout;
1552     while (!value) {
1553       if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
1554                                        : cv.WaitWithTimeout(&mu, timeout)) {
1555         break;  // deadline/timeout exceeded
1556       }
1557       timeout = deadline - absl::Now();  // recompute
1558     }
1559     bool result = value;  // note: `mu` is still held
1560 
1561     if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1562       EXPECT_EQ(params.expected_result, result);
1563       break;
1564     }
1565   }
1566 }
1567 
1568 TEST(Mutex, Logging) {
1569   // Allow user to look at logging output
1570   absl::Mutex logged_mutex;
1571   logged_mutex.EnableDebugLog("fido_mutex");
1572   absl::CondVar logged_cv;
1573   logged_cv.EnableDebugLog("rover_cv");
1574   logged_mutex.Lock();
1575   logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
1576   logged_mutex.Unlock();
1577   logged_mutex.ReaderLock();
1578   logged_mutex.ReaderUnlock();
1579   logged_mutex.Lock();
1580   logged_mutex.Unlock();
1581   logged_cv.Signal();
1582   logged_cv.SignalAll();
1583 }
1584 
1585 // --------------------------------------------------------
1586 
1587 // Generate the vector of thread counts for tests parameterized on thread count.
1588 static std::vector<int> AllThreadCountValues() {
1589   if (kExtendedTest) {
1590     return {2, 4, 8, 10, 16, 20, 24, 30, 32};
1591   }
1592   return {2, 4, 10};
1593 }
1594 
1595 // A test fixture parameterized by thread count.
1596 class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {};
1597 
1598 // Instantiate the above with AllThreadCountOptions().
1599 INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
1600                          ::testing::ValuesIn(AllThreadCountValues()),
1601                          ::testing::PrintToStringParamName());
1602 
1603 // Reduces iterations by some factor for slow platforms
1604 // (determined empirically).
1605 static int ScaleIterations(int x) {
1606   // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation
1607   // of Mutex that uses either std::mutex or pthread_mutex_t. Use
1608   // these as keys to determine the slow implementation.
1609 #if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
1610   return x / 10;
1611 #else
1612   return x;
1613 #endif
1614 }
1615 
1616 TEST_P(MutexVariableThreadCountTest, Mutex) {
1617   int threads = GetParam();
1618   int iterations = ScaleIterations(10000000) / threads;
1619   int operations = threads * iterations;
1620   EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
1621 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1622   iterations = std::min(iterations, 10);
1623   operations = threads * iterations;
1624   EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
1625                                           operations, CheckSumG0G1),
1626             operations);
1627 #endif
1628 }
1629 
1630 TEST_P(MutexVariableThreadCountTest, Try) {
1631   int threads = GetParam();
1632   int iterations = 1000000 / threads;
1633   int operations = iterations * threads;
1634   EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
1635 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1636   iterations = std::min(iterations, 10);
1637   operations = threads * iterations;
1638   EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
1639                                           operations, CheckSumG0G1),
1640             operations);
1641 #endif
1642 }
1643 
1644 TEST_P(MutexVariableThreadCountTest, R20ms) {
1645   int threads = GetParam();
1646   int iterations = 100;
1647   int operations = iterations * threads;
1648   EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
1649 }
1650 
1651 TEST_P(MutexVariableThreadCountTest, RW) {
1652   int threads = GetParam();
1653   int iterations = ScaleIterations(20000000) / threads;
1654   int operations = iterations * threads;
1655   EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
1656 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1657   iterations = std::min(iterations, 10);
1658   operations = threads * iterations;
1659   EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
1660                                           operations, CheckSumG0G1),
1661             operations / 2);
1662 #endif
1663 }
1664 
1665 TEST_P(MutexVariableThreadCountTest, Await) {
1666   int threads = GetParam();
1667   int iterations = ScaleIterations(500000);
1668   int operations = iterations;
1669   EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
1670 }
1671 
1672 TEST_P(MutexVariableThreadCountTest, SignalAll) {
1673   int threads = GetParam();
1674   int iterations = 200000 / threads;
1675   int operations = iterations;
1676   EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
1677             operations);
1678 }
1679 
1680 TEST(Mutex, Signal) {
1681   int threads = 2;  // TestSignal must use two threads
1682   int iterations = 200000;
1683   int operations = iterations;
1684   EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
1685 }
1686 
1687 TEST(Mutex, Timed) {
1688   int threads = 10;  // Use a fixed thread count of 10
1689   int iterations = 1000;
1690   int operations = iterations;
1691   EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
1692             operations);
1693 }
1694 
1695 TEST(Mutex, CVTime) {
1696   int threads = 10;  // Use a fixed thread count of 10
1697   int iterations = 1;
1698   EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1), threads * iterations);
1699 }
1700 
1701 TEST(Mutex, MuTime) {
1702   int threads = 10;  // Use a fixed thread count of 10
1703   int iterations = 1;
1704   EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
1705 }
1706 
1707 TEST(Mutex, SignalExitedThread) {
1708   // The test may expose a race when Mutex::Unlock signals a thread
1709   // that has already exited.
1710 #if defined(__wasm__) || defined(__asmjs__)
1711   constexpr int kThreads = 1;  // OOMs under WASM
1712 #else
1713   constexpr int kThreads = 100;
1714 #endif
1715   std::vector<std::thread> top;
1716   for (unsigned i = 0; i < 2 * std::thread::hardware_concurrency(); i++) {
1717     top.emplace_back([&]() {
1718       for (int i = 0; i < kThreads; i++) {
1719         absl::Mutex mu;
1720         std::thread t([&]() {
1721           mu.Lock();
1722           mu.Unlock();
1723         });
1724         mu.Lock();
1725         mu.Unlock();
1726         t.join();
1727       }
1728     });
1729   }
1730   for (auto &th : top) th.join();
1731 }
1732 
1733 }  // namespace
1734