tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mutex_test.cc (65805B)


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