// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/synchronization/mutex.h"

#ifdef _WIN32
#include <windows.h>
#endif

#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <functional>
#include <memory>
#include <mutex>  // NOLINT(build/c++11)
#include <random>
#include <shared_mutex>  // NOLINT(build/c++14)
#include <string>
#include <thread>  // NOLINT(build/c++11)
#include <type_traits>
#include <vector>

#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/random/random.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"

#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
#include <pthread.h>
#include <string.h>
#endif

namespace {

// TODO(dmauro): Replace with a commandline flag.
static constexpr bool kExtendedTest = false;

std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
    int threads) {
  return std::make_unique<absl::synchronization_internal::ThreadPool>(threads);
}

std::unique_ptr<absl::synchronization_internal::ThreadPool>
CreateDefaultPool() {
  return CreatePool(kExtendedTest ? 32 : 10);
}

// Hack to schedule a function to run on a thread pool thread after a
// duration has elapsed.
static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
                          absl::Duration after,
                          const std::function<void()> &func) {
  tp->Schedule([func, after] {
    absl::SleepFor(after);
    func();
  });
}

struct ScopedInvariantDebugging {
  ScopedInvariantDebugging() { absl::EnableMutexInvariantDebugging(true); }
  ~ScopedInvariantDebugging() { absl::EnableMutexInvariantDebugging(false); }
};

struct TestContext {
  int iterations;
  int threads;
  int g0;  // global 0
  int g1;  // global 1
  absl::Mutex mu;
  absl::CondVar cv;
};

// To test whether the invariant check call occurs
static std::atomic<bool> invariant_checked;

static bool GetInvariantChecked() {
  return invariant_checked.load(std::memory_order_relaxed);
}

static void SetInvariantChecked(bool new_value) {
  invariant_checked.store(new_value, std::memory_order_relaxed);
}

static void CheckSumG0G1(void *v) {
  TestContext *cxt = static_cast<TestContext *>(v);
  CHECK_EQ(cxt->g0, -cxt->g1) << "Error in CheckSumG0G1";
  SetInvariantChecked(true);
}

static void TestMu(TestContext *cxt, int c) {
  for (int i = 0; i != cxt->iterations; i++) {
    absl::MutexLock l(cxt->mu);
    int a = cxt->g0 + 1;
    cxt->g0 = a;
    cxt->g1--;
  }
}

static void TestTry(TestContext *cxt, int c) {
  for (int i = 0; i != cxt->iterations; i++) {
    do {
      std::this_thread::yield();
    } while (!cxt->mu.try_lock());
    int a = cxt->g0 + 1;
    cxt->g0 = a;
    cxt->g1--;
    cxt->mu.unlock();
  }
}

static void TestR20ms(TestContext *cxt, int c) {
  for (int i = 0; i != cxt->iterations; i++) {
    absl::ReaderMutexLock l(cxt->mu);
    absl::SleepFor(absl::Milliseconds(20));
    cxt->mu.AssertReaderHeld();
  }
}

static void TestRW(TestContext *cxt, int c) {
  if ((c & 1) == 0) {
    for (int i = 0; i != cxt->iterations; i++) {
      absl::WriterMutexLock l(cxt->mu);
      cxt->g0++;
      cxt->g1--;
      cxt->mu.AssertHeld();
      cxt->mu.AssertReaderHeld();
    }
  } else {
    for (int i = 0; i != cxt->iterations; i++) {
      absl::ReaderMutexLock l(cxt->mu);
      CHECK_EQ(cxt->g0, -cxt->g1) << "Error in TestRW";
      cxt->mu.AssertReaderHeld();
    }
  }
}

struct MyContext {
  int target;
  TestContext *cxt;
  bool MyTurn();
};

bool MyContext::MyTurn() {
  TestContext *cxt = this->cxt;
  return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
}

static void TestAwait(TestContext *cxt, int c) {
  MyContext mc;
  mc.target = c;
  mc.cxt = cxt;
  absl::MutexLock l(cxt->mu);
  cxt->mu.AssertHeld();
  while (cxt->g0 < cxt->iterations) {
    cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
    CHECK(mc.MyTurn()) << "Error in TestAwait";
    cxt->mu.AssertHeld();
    if (cxt->g0 < cxt->iterations) {
      int a = cxt->g0 + 1;
      cxt->g0 = a;
      mc.target += cxt->threads;
    }
  }
}

static void TestSignalAll(TestContext *cxt, int c) {
  int target = c;
  absl::MutexLock l(cxt->mu);
  cxt->mu.AssertHeld();
  while (cxt->g0 < cxt->iterations) {
    while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
      cxt->cv.Wait(&cxt->mu);
    }
    if (cxt->g0 < cxt->iterations) {
      int a = cxt->g0 + 1;
      cxt->g0 = a;
      cxt->cv.SignalAll();
      target += cxt->threads;
    }
  }
}

static void TestSignal(TestContext *cxt, int c) {
  CHECK_EQ(cxt->threads, 2) << "TestSignal should use 2 threads";
  int target = c;
  absl::MutexLock l(cxt->mu);
  cxt->mu.AssertHeld();
  while (cxt->g0 < cxt->iterations) {
    while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
      cxt->cv.Wait(&cxt->mu);
    }
    if (cxt->g0 < cxt->iterations) {
      int a = cxt->g0 + 1;
      cxt->g0 = a;
      cxt->cv.Signal();
      target += cxt->threads;
    }
  }
}

static void TestCVTimeout(TestContext *cxt, int c) {
  int target = c;
  absl::MutexLock l(cxt->mu);
  cxt->mu.AssertHeld();
  while (cxt->g0 < cxt->iterations) {
    while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
    }
    if (cxt->g0 < cxt->iterations) {
      int a = cxt->g0 + 1;
      cxt->g0 = a;
      cxt->cv.SignalAll();
      target += cxt->threads;
    }
  }
}

static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }

static void TestTime(TestContext *cxt, int c, bool use_cv) {
  CHECK_EQ(cxt->iterations, 1) << "TestTime should only use 1 iteration";
  CHECK_GT(cxt->threads, 2) << "TestTime should use more than 2 threads";
  const bool kFalse = false;
  absl::Condition false_cond(&kFalse);
  absl::Condition g0ge2(G0GE2, cxt);
  if (c == 0) {
    absl::MutexLock l(cxt->mu);

    absl::Time start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
          << "TestTime failed";
    }
    absl::Duration elapsed = absl::Now() - start;
    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
        << "TestTime failed";
    CHECK_EQ(cxt->g0, 1) << "TestTime failed";

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
          << "TestTime failed";
    }
    elapsed = absl::Now() - start;
    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
        << "TestTime failed";
    cxt->g0++;
    if (use_cv) {
      cxt->cv.Signal();
    }

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)))
          << "TestTime failed";
    }
    elapsed = absl::Now() - start;
    CHECK(absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0))
        << "TestTime failed";
    CHECK_GE(cxt->g0, 3) << "TestTime failed";

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
          << "TestTime failed";
    }
    elapsed = absl::Now() - start;
    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
        << "TestTime failed";
    if (use_cv) {
      cxt->cv.SignalAll();
    }

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)))
          << "TestTime failed";
    }
    elapsed = absl::Now() - start;
    CHECK(absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0))
        << "TestTime failed";
    CHECK_EQ(cxt->g0, cxt->threads) << "TestTime failed";

  } else if (c == 1) {
    absl::MutexLock l(cxt->mu);
    const absl::Time start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
    } else {
      CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)))
          << "TestTime failed";
    }
    const absl::Duration elapsed = absl::Now() - start;
    CHECK(absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9))
        << "TestTime failed";
    cxt->g0++;
  } else if (c == 2) {
    absl::MutexLock l(cxt->mu);
    if (use_cv) {
      while (cxt->g0 < 2) {
        cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
      }
    } else {
      CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)))
          << "TestTime failed";
    }
    cxt->g0++;
  } else {
    absl::MutexLock l(cxt->mu);
    if (use_cv) {
      while (cxt->g0 < 2) {
        cxt->cv.Wait(&cxt->mu);
      }
    } else {
      cxt->mu.Await(g0ge2);
    }
    cxt->g0++;
  }
}

static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); }

static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }

static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
                    const std::function<void(int)> &cb) {
  mu->lock();
  int c = (*c0)++;
  mu->unlock();
  cb(c);
  absl::MutexLock l(*mu);
  (*c1)++;
  cv->Signal();
}

// Code common to RunTest() and RunTestWithInvariantDebugging().
static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
                         int threads, int iterations, int operations) {
  absl::Mutex mu2;
  absl::CondVar cv2;
  int c0 = 0;
  int c1 = 0;
  cxt->g0 = 0;
  cxt->g1 = 0;
  cxt->iterations = iterations;
  cxt->threads = threads;
  absl::synchronization_internal::ThreadPool tp(threads);
  for (int i = 0; i != threads; i++) {
    tp.Schedule(std::bind(
        &EndTest, &c0, &c1, &mu2, &cv2,
        std::function<void(int)>(std::bind(test, cxt, std::placeholders::_1))));
  }
  mu2.lock();
  while (c1 != threads) {
    cv2.Wait(&mu2);
  }
  mu2.unlock();
  return cxt->g0;
}

// Basis for the parameterized tests configured below.
static int RunTest(void (*test)(TestContext *cxt, int), int threads,
                   int iterations, int operations) {
  TestContext cxt;
  return RunTestCommon(&cxt, test, threads, iterations, operations);
}

// Like RunTest(), but sets an invariant on the tested Mutex and
// verifies that the invariant check happened. The invariant function
// will be passed the TestContext* as its arg and must call
// SetInvariantChecked(true);
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
                                         int threads, int iterations,
                                         int operations,
                                         void (*invariant)(void *)) {
  ScopedInvariantDebugging scoped_debugging;
  SetInvariantChecked(false);
  TestContext cxt;
  cxt.mu.EnableInvariantDebugging(invariant, &cxt);
  int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
  CHECK(GetInvariantChecked()) << "Invariant not checked";
  return ret;
}
#endif

// --------------------------------------------------------
// Test for fix of bug in TryRemove()
struct TimeoutBugStruct {
  absl::Mutex mu;
  bool a;
  int a_waiter_count;
};

static void WaitForA(TimeoutBugStruct *x) {
  x->mu.LockWhen(absl::Condition(&x->a));
  x->a_waiter_count--;
  x->mu.unlock();
}

static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }

// Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in
// another thread.
TEST(Mutex, CondVarWaitSignalsAwait) {
  // Use a struct so the lock annotations apply.
  struct {
    absl::Mutex barrier_mu;
    bool barrier ABSL_GUARDED_BY(barrier_mu) = false;

    absl::Mutex release_mu;
    bool release ABSL_GUARDED_BY(release_mu) = false;
    absl::CondVar released_cv;
  } state;

  auto pool = CreateDefaultPool();

  // Thread A.  Sets barrier, waits for release using Mutex::Await, then
  // signals released_cv.
  pool->Schedule([&state] {
    state.release_mu.lock();

    state.barrier_mu.lock();
    state.barrier = true;
    state.barrier_mu.unlock();

    state.release_mu.Await(absl::Condition(&state.release));
    state.released_cv.Signal();
    state.release_mu.unlock();
  });

  state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
  state.barrier_mu.unlock();
  state.release_mu.lock();
  // Thread A is now blocked on release by way of Mutex::Await().

  // Set release.  Calling released_cv.Wait() should un-block thread A,
  // which will signal released_cv.  If not, the test will hang.
  state.release = true;
  state.released_cv.Wait(&state.release_mu);
  state.release_mu.unlock();
}

// Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
// mutex.Await() in another thread.
TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
  // Use a struct so the lock annotations apply.
  struct {
    absl::Mutex barrier_mu;
    bool barrier ABSL_GUARDED_BY(barrier_mu) = false;

    absl::Mutex release_mu;
    bool release ABSL_GUARDED_BY(release_mu) = false;
    absl::CondVar released_cv;
  } state;

  auto pool = CreateDefaultPool();

  // Thread A.  Sets barrier, waits for release using Mutex::Await, then
  // signals released_cv.
  pool->Schedule([&state] {
    state.release_mu.lock();

    state.barrier_mu.lock();
    state.barrier = true;
    state.barrier_mu.unlock();

    state.release_mu.Await(absl::Condition(&state.release));
    state.released_cv.Signal();
    state.release_mu.unlock();
  });

  state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
  state.barrier_mu.unlock();
  state.release_mu.lock();
  // Thread A is now blocked on release by way of Mutex::Await().

  // Set release.  Calling released_cv.Wait() should un-block thread A,
  // which will signal released_cv.  If not, the test will hang.
  state.release = true;
  EXPECT_TRUE(
      !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10)))
      << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
         "unblock the absl::Mutex::Await call in another thread.";

  state.release_mu.unlock();
}

// Test for regression of a bug in loop of TryRemove()
TEST(Mutex, MutexTimeoutBug) {
  auto tp = CreateDefaultPool();

  TimeoutBugStruct x;
  x.a = false;
  x.a_waiter_count = 2;
  tp->Schedule(std::bind(&WaitForA, &x));
  tp->Schedule(std::bind(&WaitForA, &x));
  absl::SleepFor(absl::Seconds(1));  // Allow first two threads to hang.
  // The skip field of the second will point to the first because there are
  // only two.

  // Now cause a thread waiting on an always-false to time out
  // This would deadlock when the bug was present.
  bool always_false = false;
  x.mu.LockWhenWithTimeout(absl::Condition(&always_false),
                           absl::Milliseconds(500));

  // if we get here, the bug is not present.   Cleanup the state.

  x.a = true;                                    // wakeup the two waiters on A
  x.mu.Await(absl::Condition(&NoAWaiters, &x));  // wait for them to exit
  x.mu.unlock();
}

struct CondVarWaitDeadlock : testing::TestWithParam<int> {
  absl::Mutex mu;
  absl::CondVar cv;
  bool cond1 = false;
  bool cond2 = false;
  bool read_lock1;
  bool read_lock2;
  bool signal_unlocked;

  CondVarWaitDeadlock() {
    read_lock1 = GetParam() & (1 << 0);
    read_lock2 = GetParam() & (1 << 1);
    signal_unlocked = GetParam() & (1 << 2);
  }

  void Waiter1() {
    if (read_lock1) {
      mu.lock_shared();
      while (!cond1) {
        cv.Wait(&mu);
      }
      mu.unlock_shared();
    } else {
      mu.lock();
      while (!cond1) {
        cv.Wait(&mu);
      }
      mu.unlock();
    }
  }

  void Waiter2() {
    if (read_lock2) {
      mu.ReaderLockWhen(absl::Condition(&cond2));
      mu.unlock_shared();
    } else {
      mu.LockWhen(absl::Condition(&cond2));
      mu.unlock();
    }
  }
};

// Test for a deadlock bug in Mutex::Fer().
// The sequence of events that lead to the deadlock is:
// 1. waiter1 blocks on cv in read mode (mu bits = 0).
// 2. waiter2 blocks on mu in either mode (mu bits = kMuWait).
// 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait).
// 4. main thread signals on cv and this eventually calls Mutex::Fer().
// Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked).
// Before the bug fix Fer neither woke waiter1 nor queued it on mutex,
// which resulted in deadlock.
TEST_P(CondVarWaitDeadlock, Test) {
  auto waiter1 = CreatePool(1);
  auto waiter2 = CreatePool(1);
  waiter1->Schedule([this] { this->Waiter1(); });
  waiter2->Schedule([this] { this->Waiter2(); });

  // Wait while threads block (best-effort is fine).
  absl::SleepFor(absl::Milliseconds(100));

  // Wake condwaiter.
  mu.lock();
  cond1 = true;
  if (signal_unlocked) {
    mu.unlock();
    cv.Signal();
  } else {
    cv.Signal();
    mu.unlock();
  }
  waiter1.reset();  // "join" waiter1

  // Wake waiter.
  mu.lock();
  cond2 = true;
  mu.unlock();
  waiter2.reset();  // "join" waiter2
}

INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
                         ::testing::Range(0, 8),
                         ::testing::PrintToStringParamName());

// --------------------------------------------------------
// Test for fix of bug in DequeueAllWakeable()
// Bug was that if there was more than one waiting reader
// and all should be woken, the most recently blocked one
// would not be.

struct DequeueAllWakeableBugStruct {
  absl::Mutex mu;
  absl::Mutex mu2;       // protects all fields below
  int unfinished_count;  // count of unfinished readers; under mu2
  bool done1;            // unfinished_count == 0; under mu2
  int finished_count;    // count of finished readers, under mu2
  bool done2;            // finished_count == 0; under mu2
};

// Test for regression of a bug in loop of DequeueAllWakeable()
static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
  x->mu.lock_shared();
  x->mu2.lock();
  x->unfinished_count--;
  x->done1 = (x->unfinished_count == 0);
  x->mu2.unlock();
  // make sure that both readers acquired mu before we release it.
  absl::SleepFor(absl::Seconds(2));
  x->mu.unlock_shared();

  x->mu2.lock();
  x->finished_count--;
  x->done2 = (x->finished_count == 0);
  x->mu2.unlock();
}

// Test for regression of a bug in loop of DequeueAllWakeable()
TEST(Mutex, MutexReaderWakeupBug) {
  auto tp = CreateDefaultPool();

  DequeueAllWakeableBugStruct x;
  x.unfinished_count = 2;
  x.done1 = false;
  x.finished_count = 2;
  x.done2 = false;
  x.mu.lock();  // acquire mu exclusively
  // queue two thread that will block on reader locks on x.mu
  tp->Schedule(std::bind(&AcquireAsReader, &x));
  tp->Schedule(std::bind(&AcquireAsReader, &x));
  absl::SleepFor(absl::Seconds(1));  // give time for reader threads to block
  x.mu.unlock();                     // wake them up

  // both readers should finish promptly
  EXPECT_TRUE(
      x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
  x.mu2.unlock();

  EXPECT_TRUE(
      x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
  x.mu2.unlock();
}

struct LockWhenTestStruct {
  absl::Mutex mu1;
  bool cond = false;

  absl::Mutex mu2;
  bool waiting = false;
};

static bool LockWhenTestIsCond(LockWhenTestStruct *s) {
  s->mu2.lock();
  s->waiting = true;
  s->mu2.unlock();
  return s->cond;
}

static void LockWhenTestWaitForIsCond(LockWhenTestStruct *s) {
  s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
  s->mu1.unlock();
}

TEST(Mutex, LockWhen) {
  LockWhenTestStruct s;

  std::thread t(LockWhenTestWaitForIsCond, &s);
  s.mu2.LockWhen(absl::Condition(&s.waiting));
  s.mu2.unlock();

  s.mu1.lock();
  s.cond = true;
  s.mu1.unlock();

  t.join();
}

TEST(Mutex, LockWhenGuard) {
  absl::Mutex mu;
  int n = 30;
  bool done = false;

  // We don't inline the lambda because the conversion is ambiguous in MSVC.
  bool (*cond_eq_10)(int *) = [](int *p) { return *p == 10; };
  bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; };

  std::thread t1([&mu, &n, &done, cond_eq_10]() {
    absl::ReaderMutexLock lock(mu, absl::Condition(cond_eq_10, &n));
    done = true;
  });

  std::thread t2[10];
  for (std::thread &t : t2) {
    t = std::thread([&mu, &n, cond_lt_10]() {
      absl::WriterMutexLock lock(mu, absl::Condition(cond_lt_10, &n));
      ++n;
    });
  }

  {
    absl::MutexLock lock(mu);
    n = 0;
  }

  for (std::thread &t : t2) t.join();
  t1.join();

  EXPECT_TRUE(done);
  EXPECT_EQ(n, 10);
}

// --------------------------------------------------------
// The following test requires Mutex::lock_shared to be a real shared
// lock, which is not the case in all builds.
#if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)

// Test for fix of bug in UnlockSlow() that incorrectly decremented the reader
// count when putting a thread to sleep waiting for a false condition when the
// lock was not held.

// For this bug to strike, we make a thread wait on a free mutex with no
// waiters by causing its wakeup condition to be false.   Then the
// next two acquirers must be readers.   The bug causes the lock
// to be released when one reader unlocks, rather than both.

struct ReaderDecrementBugStruct {
  bool cond;  // to delay first thread (under mu)
  int done;   // reference count (under mu)
  absl::Mutex mu;

  bool waiting_on_cond;   // under mu2
  bool have_reader_lock;  // under mu2
  bool complete;          // under mu2
  absl::Mutex mu2;        // > mu
};

// L >= mu, L < mu_waiting_on_cond
static bool IsCond(void *v) {
  ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
  x->mu2.lock();
  x->waiting_on_cond = true;
  x->mu2.unlock();
  return x->cond;
}

// L >= mu
static bool AllDone(void *v) {
  ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
  return x->done == 0;
}

// L={}
static void WaitForCond(ReaderDecrementBugStruct *x) {
  absl::Mutex dummy;
  absl::MutexLock l(dummy);
  x->mu.LockWhen(absl::Condition(&IsCond, x));
  x->done--;
  x->mu.unlock();
}

// L={}
static void GetReadLock(ReaderDecrementBugStruct *x) {
  x->mu.lock_shared();
  x->mu2.lock();
  x->have_reader_lock = true;
  x->mu2.Await(absl::Condition(&x->complete));
  x->mu2.unlock();
  x->mu.unlock_shared();
  x->mu.lock();
  x->done--;
  x->mu.unlock();
}

// Test for reader counter being decremented incorrectly by waiter
// with false condition.
TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  ReaderDecrementBugStruct x;
  x.cond = false;
  x.waiting_on_cond = false;
  x.have_reader_lock = false;
  x.complete = false;
  x.done = 2;  // initial ref count

  // Run WaitForCond() and wait for it to sleep
  std::thread thread1(WaitForCond, &x);
  x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
  x.mu2.unlock();

  // Run GetReadLock(), and wait for it to get the read lock
  std::thread thread2(GetReadLock, &x);
  x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
  x.mu2.unlock();

  // Get the reader lock ourselves, and release it.
  x.mu.lock_shared();
  x.mu.unlock_shared();

  // The lock should be held in read mode by GetReadLock().
  // If we have the bug, the lock will be free.
  x.mu.AssertReaderHeld();

  // Wake up all the threads.
  x.mu2.lock();
  x.complete = true;
  x.mu2.unlock();

  // TODO(delesley): turn on analysis once lock upgrading is supported.
  // (This call upgrades the lock from shared to exclusive.)
  x.mu.lock();
  x.cond = true;
  x.mu.Await(absl::Condition(&AllDone, &x));
  x.mu.unlock();

  thread1.join();
  thread2.join();
}
#endif  // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE

// Test that we correctly handle the situation when a lock is
// held and then destroyed (w/o unlocking).
#ifdef ABSL_HAVE_THREAD_SANITIZER
// TSAN reports errors when locked Mutexes are destroyed.
TEST(Mutex, DISABLED_LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
#else
TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
#endif
  for (int i = 0; i != 10; i++) {
    // Create, lock and destroy 10 locks.
    const int kNumLocks = 10;
    auto mu = std::make_unique<absl::Mutex[]>(kNumLocks);
    for (int j = 0; j != kNumLocks; j++) {
      if ((j % 2) == 0) {
        mu[j].lock();
      } else {
        mu[j].lock_shared();
      }
    }
  }
}

// Some functions taking pointers to non-const.
bool Equals42(int *p) { return *p == 42; }
bool Equals43(int *p) { return *p == 43; }

// Some functions taking pointers to const.
bool ConstEquals42(const int *p) { return *p == 42; }
bool ConstEquals43(const int *p) { return *p == 43; }

// Some function templates taking pointers. Note it's possible for `T` to be
// deduced as non-const or const, which creates the potential for ambiguity,
// but which the implementation is careful to avoid.
template <typename T>
bool TemplateEquals42(T *p) {
  return *p == 42;
}
template <typename T>
bool TemplateEquals43(T *p) {
  return *p == 43;
}

TEST(Mutex, FunctionPointerCondition) {
  // Some arguments.
  int x = 42;
  const int const_x = 42;

  // Parameter non-const, argument non-const.
  EXPECT_TRUE(absl::Condition(Equals42, &x).Eval());
  EXPECT_FALSE(absl::Condition(Equals43, &x).Eval());

  // Parameter const, argument non-const.
  EXPECT_TRUE(absl::Condition(ConstEquals42, &x).Eval());
  EXPECT_FALSE(absl::Condition(ConstEquals43, &x).Eval());

  // Parameter const, argument const.
  EXPECT_TRUE(absl::Condition(ConstEquals42, &const_x).Eval());
  EXPECT_FALSE(absl::Condition(ConstEquals43, &const_x).Eval());

  // Parameter type deduced, argument non-const.
  EXPECT_TRUE(absl::Condition(TemplateEquals42, &x).Eval());
  EXPECT_FALSE(absl::Condition(TemplateEquals43, &x).Eval());

  // Parameter type deduced, argument const.
  EXPECT_TRUE(absl::Condition(TemplateEquals42, &const_x).Eval());
  EXPECT_FALSE(absl::Condition(TemplateEquals43, &const_x).Eval());

  // Parameter non-const, argument const is not well-formed.
  EXPECT_FALSE((std::is_constructible_v<absl::Condition, decltype(Equals42),
                                        decltype(&const_x)>));
  // Validate use of is_constructible by contrasting to a well-formed case.
  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(ConstEquals42),
                                       decltype(&const_x)>));
}

// Example base and derived class for use in predicates and test below. Not a
// particularly realistic example, but it suffices for testing purposes.
struct Base {
  explicit Base(int v) : value(v) {}
  int value;
};
struct Derived : Base {
  explicit Derived(int v) : Base(v) {}
};

// Some functions taking pointer to non-const `Base`.
bool BaseEquals42(Base *p) { return p->value == 42; }
bool BaseEquals43(Base *p) { return p->value == 43; }

// Some functions taking pointer to const `Base`.
bool ConstBaseEquals42(const Base *p) { return p->value == 42; }
bool ConstBaseEquals43(const Base *p) { return p->value == 43; }

TEST(Mutex, FunctionPointerConditionWithDerivedToBaseConversion) {
  // Some arguments.
  Derived derived(42);
  const Derived const_derived(42);

  // Parameter non-const base, argument derived non-const.
  EXPECT_TRUE(absl::Condition(BaseEquals42, &derived).Eval());
  EXPECT_FALSE(absl::Condition(BaseEquals43, &derived).Eval());

  // Parameter const base, argument derived non-const.
  EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &derived).Eval());
  EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &derived).Eval());

  // Parameter const base, argument derived const.
  EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &const_derived).Eval());
  EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &const_derived).Eval());

  // Parameter const base, argument derived const.
  EXPECT_TRUE(absl::Condition(ConstBaseEquals42, &const_derived).Eval());
  EXPECT_FALSE(absl::Condition(ConstBaseEquals43, &const_derived).Eval());

  // Parameter derived, argument base is not well-formed.
  bool (*derived_pred)(const Derived *) = [](const Derived *) { return true; };
  EXPECT_FALSE((
      std::is_constructible_v<absl::Condition, decltype(derived_pred), Base*>));
  EXPECT_FALSE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
                                        const Base*>));
  // Validate use of is_constructible by contrasting to well-formed cases.
  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
                                       Derived*>));
  EXPECT_TRUE((std::is_constructible_v<absl::Condition, decltype(derived_pred),
                                       const Derived*>));
}

struct Constable {
  bool WotsAllThisThen() const { return true; }
};

TEST(Mutex, FunctionPointerConditionWithConstMethod) {
  const Constable chapman;
  EXPECT_TRUE(absl::Condition(&chapman, &Constable::WotsAllThisThen).Eval());
}

#ifdef __cpp_explicit_this_parameter
struct TrueViaDeducingThis {
  template <class This, class... Args>
  bool operator()(this const This&, Args...) {
    return true;
  }
};

TEST(Mutex, FunctorConditionDeducingThis) {
  TrueViaDeducingThis f;
  EXPECT_TRUE(absl::Condition(&f).Eval());
}
#endif

struct True {
  template <class... Args>
  bool operator()(Args...) const {
    return true;
  }
};

struct DerivedTrue : True {};

TEST(Mutex, FunctorCondition) {
  {  // Variadic
    True f;
    EXPECT_TRUE(absl::Condition(&f).Eval());
  }

  {  // Inherited
    DerivedTrue g;
    EXPECT_TRUE(absl::Condition(&g).Eval());
  }

  {  // lambda
    int value = 3;
    auto is_zero = [&value] { return value == 0; };
    absl::Condition c(&is_zero);
    EXPECT_FALSE(c.Eval());
    value = 0;
    EXPECT_TRUE(c.Eval());
  }

  {  // bind
    int value = 0;
    auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
    absl::Condition c(&is_positive);
    EXPECT_FALSE(c.Eval());
    value = 1;
    EXPECT_TRUE(c.Eval());
  }

  {  // std::function
    int value = 3;
    std::function<bool()> is_zero = [&value] { return value == 0; };
    absl::Condition c(&is_zero);
    EXPECT_FALSE(c.Eval());
    value = 0;
    EXPECT_TRUE(c.Eval());
  }
}

TEST(Mutex, ConditionSwap) {
  // Ensure that Conditions can be swap'ed.
  bool b1 = true;
  absl::Condition c1(&b1);
  bool b2 = false;
  absl::Condition c2(&b2);
  EXPECT_TRUE(c1.Eval());
  EXPECT_FALSE(c2.Eval());
  std::swap(c1, c2);
  EXPECT_FALSE(c1.Eval());
  EXPECT_TRUE(c2.Eval());
}

// --------------------------------------------------------
// Test for bug with pattern of readers using a condvar.  The bug was that if a
// reader went to sleep on a condition variable while one or more other readers
// held the lock, but there were no waiters, the reader count (held in the
// mutex word) would be lost.  (This is because Enqueue() had at one time
// always placed the thread on the Mutex queue.  Later (CL 4075610), to
// tolerate re-entry into Mutex from a Condition predicate, Enqueue() was
// changed so that it could also place a thread on a condition-variable.  This
// introduced the case where Enqueue() returned with an empty queue, and this
// case was handled incorrectly in one place.)

static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
                                     int *running) {
  absl::InsecureBitGen gen;
  std::uniform_int_distribution<int> random_millis(0, 15);
  mu->lock_shared();
  while (*running == 3) {
    absl::SleepFor(absl::Milliseconds(random_millis(gen)));
    cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
  }
  mu->unlock_shared();
  mu->lock();
  (*running)--;
  mu->unlock();
}

static bool IntIsZero(int *x) { return *x == 0; }

// Test for reader waiting condition variable when there are other readers
// but no waiters.
TEST(Mutex, TestReaderOnCondVar) {
  auto tp = CreateDefaultPool();
  absl::Mutex mu;
  absl::CondVar cv;
  int running = 3;
  tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
  tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
  absl::SleepFor(absl::Seconds(2));
  mu.lock();
  running--;
  mu.Await(absl::Condition(&IntIsZero, &running));
  mu.unlock();
}

// --------------------------------------------------------
struct AcquireFromConditionStruct {
  absl::Mutex mu0;   // protects value, done
  int value;         // times condition function is called; under mu0,
  bool done;         // done with test?  under mu0
  absl::Mutex mu1;   // used to attempt to mess up state of mu0
  absl::CondVar cv;  // so the condition function can be invoked from
                     // CondVar::Wait().
};

static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
  x->value++;  // count times this function is called

  if (x->value == 2 || x->value == 3) {
    // On the second and third invocation of this function, sleep for 100ms,
    // but with the side-effect of altering the state of a Mutex other than
    // than one for which this is a condition.  The spec now explicitly allows
    // this side effect; previously it did not.  it was illegal.
    bool always_false = false;
    x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
                               absl::Milliseconds(100));
    x->mu1.unlock();
  }
  CHECK_LT(x->value, 4) << "should not be invoked a fourth time";

  // We arrange for the condition to return true on only the 2nd and 3rd calls.
  return x->value == 2 || x->value == 3;
}

static void WaitForCond2(AcquireFromConditionStruct *x) {
  // wait for cond0 to become true
  x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
  x->done = true;
  x->mu0.unlock();
}

// Test for Condition whose function acquires other Mutexes
TEST(Mutex, AcquireFromCondition) {
  auto tp = CreateDefaultPool();

  AcquireFromConditionStruct x;
  x.value = 0;
  x.done = false;
  tp->Schedule(
      std::bind(&WaitForCond2, &x));  // run WaitForCond2() in a thread T
  // T will hang because the first invocation of ConditionWithAcquire() will
  // return false.
  absl::SleepFor(absl::Milliseconds(500));  // allow T time to hang

  x.mu0.lock();
  x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500));  // wake T
  // T will be woken because the Wait() will call ConditionWithAcquire()
  // for the second time, and it will return true.

  x.mu0.unlock();

  // T will then acquire the lock and recheck its own condition.
  // It will find the condition true, as this is the third invocation,
  // but the use of another Mutex by the calling function will
  // cause the old mutex implementation to think that the outer
  // LockWhen() has timed out because the inner LockWhenWithTimeout() did.
  // T will then check the condition a fourth time because it finds a
  // timeout occurred.  This should not happen in the new
  // implementation that allows the Condition function to use Mutexes.

  // It should also succeed, even though the Condition function
  // is being invoked from CondVar::Wait, and thus this thread
  // is conceptually waiting both on the condition variable, and on mu2.

  x.mu0.LockWhen(absl::Condition(&x.done));
  x.mu0.unlock();
}

TEST(Mutex, DeadlockDetector) {
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);

  // check that we can call ForgetDeadlockInfo() on a lock with the lock held
  absl::Mutex m1;
  absl::Mutex m2;
  absl::Mutex m3;
  absl::Mutex m4;

  m1.lock();  // m1 gets ID1
  m2.lock();  // m2 gets ID2
  m3.lock();  // m3 gets ID3
  m3.unlock();
  m2.unlock();
  // m1 still held
  m1.ForgetDeadlockInfo();  // m1 loses ID
  m2.lock();                // m2 gets ID2
  m3.lock();                // m3 gets ID3
  m4.lock();                // m4 gets ID4
  m3.unlock();
  m2.unlock();
  m4.unlock();
  m1.unlock();
}

// Bazel has a test "warning" file that programs can write to if the
// test should pass with a warning.  This class disables the warning
// file until it goes out of scope.
class ScopedDisableBazelTestWarnings {
 public:
  ScopedDisableBazelTestWarnings() {
#ifdef _WIN32
    char file[MAX_PATH];
    if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
      warnings_output_file_ = file;
      SetEnvironmentVariableA(kVarName, nullptr);
    }
#else
    const char *file = getenv(kVarName);
    if (file != nullptr) {
      warnings_output_file_ = file;
      unsetenv(kVarName);
    }
#endif
  }

  ~ScopedDisableBazelTestWarnings() {
    if (!warnings_output_file_.empty()) {
#ifdef _WIN32
      SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
#else
      setenv(kVarName, warnings_output_file_.c_str(), 0);
#endif
    }
  }

 private:
  static const char kVarName[];
  std::string warnings_output_file_;
};
const char ScopedDisableBazelTestWarnings::kVarName[] =
    "TEST_WARNINGS_OUTPUT_FILE";

#ifdef ABSL_HAVE_THREAD_SANITIZER
// This test intentionally creates deadlocks to test the deadlock detector.
TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
#else
TEST(Mutex, DeadlockDetectorBazelWarning) {
#endif
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);

  // Cause deadlock detection to detect something, if it's
  // compiled in and enabled.  But turn off the bazel warning.
  ScopedDisableBazelTestWarnings disable_bazel_test_warnings;

  absl::Mutex mu0;
  absl::Mutex mu1;
  bool got_mu0 = mu0.try_lock();
  mu1.lock();  // acquire mu1 while holding mu0
  if (got_mu0) {
    mu0.unlock();
  }
  if (mu0.try_lock()) {  // try lock shouldn't cause deadlock detector to fire
    mu0.unlock();
  }
  mu0.lock();  // acquire mu0 while holding mu1; should get one deadlock
               // report here
  mu0.unlock();
  mu1.unlock();

  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
}

TEST(Mutex, DeadlockDetectorLongCycle) {
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);

  // This test generates a warning if it passes, and crashes otherwise.
  // Cause bazel to ignore the warning.
  ScopedDisableBazelTestWarnings disable_bazel_test_warnings;

  // Check that we survive a deadlock with a lock cycle.
  std::vector<absl::Mutex> mutex(100);
  for (size_t i = 0; i != mutex.size(); i++) {
    mutex[i].lock();
    mutex[(i + 1) % mutex.size()].lock();
    mutex[i].unlock();
    mutex[(i + 1) % mutex.size()].unlock();
  }

  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
}

// This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the
// annotation-based static thread-safety analysis is not currently
// predicate-aware and cannot tell if the two for-loops that acquire and
// release the locks have the same predicates.
TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
  // Stress test: Here we create a large number of locks and use all of them.
  // If a deadlock detector keeps a full graph of lock acquisition order,
  // it will likely be too slow for this test to pass.
  const int n_locks = 1 << 17;
  auto array_of_locks = std::make_unique<absl::Mutex[]>(n_locks);
  for (int i = 0; i < n_locks; i++) {
    int end = std::min(n_locks, i + 5);
    // acquire and then release locks i, i+1, ..., i+4
    for (int j = i; j < end; j++) {
      array_of_locks[j].lock();
    }
    for (int j = i; j < end; j++) {
      array_of_locks[j].unlock();
    }
  }
}

#ifdef ABSL_HAVE_THREAD_SANITIZER
// TSAN reports errors when locked Mutexes are destroyed.
TEST(Mutex, DISABLED_DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
#else
TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
#endif
  // Test a scenario where a cached deadlock graph node id in the
  // list of held locks is not invalidated when the corresponding
  // mutex is deleted.
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);
  // Mutex that will be destroyed while being held
  absl::Mutex *a = new absl::Mutex;
  // Other mutexes needed by test
  absl::Mutex b, c;

  // Hold mutex.
  a->lock();

  // Force deadlock id assignment by acquiring another lock.
  b.lock();
  b.unlock();

  // Delete the mutex. The Mutex destructor tries to remove held locks,
  // but the attempt isn't foolproof.  It can fail if:
  //   (a) Deadlock detection is currently disabled.
  //   (b) The destruction is from another thread.
  // We exploit (a) by temporarily disabling deadlock detection.
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kIgnore);
  delete a;
  absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kAbort);

  // Now acquire another lock which will force a deadlock id assignment.
  // We should end up getting assigned the same deadlock id that was
  // freed up when "a" was deleted, which will cause a spurious deadlock
  // report if the held lock entry for "a" was not invalidated.
  c.lock();
  c.unlock();
}

// --------------------------------------------------------
// Test for timeouts/deadlines on condition waits that are specified using
// absl::Duration and absl::Time.  For each waiting function we test with
// a timeout/deadline that has already expired/passed, one that is infinite
// and so never expires/passes, and one that will expire/pass in the near
// future.

static absl::Duration TimeoutTestAllowedSchedulingDelay() {
  // Note: we use a function here because Microsoft Visual Studio fails to
  // properly initialize constexpr static absl::Duration variables.
  return absl::Milliseconds(150);
}

// Returns true if `actual_delay` is close enough to `expected_delay` to pass
// the timeouts/deadlines test.  Otherwise, logs warnings and returns false.
[[nodiscard]]
static bool DelayIsWithinBounds(absl::Duration expected_delay,
                                absl::Duration actual_delay) {
  bool pass = true;
  // Do not allow the observed delay to be less than expected.  This may occur
  // in practice due to clock skew or when the synchronization primitives use a
  // different clock than absl::Now(), but these cases should be handled by the
  // the retry mechanism in each TimeoutTest.
  if (actual_delay < expected_delay) {
    LOG(WARNING) << "Actual delay " << actual_delay
                 << " was too short, expected " << expected_delay
                 << " (difference " << actual_delay - expected_delay << ")";
    pass = false;
  }
  // If the expected delay is <= zero then allow a small error tolerance, since
  // we do not expect context switches to occur during test execution.
  // Otherwise, thread scheduling delays may be substantial in rare cases, so
  // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
  absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
                                 ? absl::Milliseconds(10)
                                 : TimeoutTestAllowedSchedulingDelay();
  if (actual_delay > expected_delay + tolerance) {
    LOG(WARNING) << "Actual delay " << actual_delay
                 << " was too long, expected " << expected_delay
                 << " (difference " << actual_delay - expected_delay << ")";
    pass = false;
  }
  return pass;
}

// Parameters for TimeoutTest, below.
struct TimeoutTestParam {
  // The file and line number (used for logging purposes only).
  const char *from_file;
  int from_line;

  // Should the absolute deadline API based on absl::Time be tested?  If false,
  // the relative deadline API based on absl::Duration is tested.
  bool use_absolute_deadline;

  // The deadline/timeout used when calling the API being tested
  // (e.g. Mutex::LockWhenWithDeadline).
  absl::Duration wait_timeout;

  // The delay before the condition will be set true by the test code.  If zero
  // or negative, the condition is set true immediately (before calling the API
  // being tested).  Otherwise, if infinite, the condition is never set true.
  // Otherwise a closure is scheduled for the future that sets the condition
  // true.
  absl::Duration satisfy_condition_delay;

  // The expected result of the condition after the call to the API being
  // tested. Generally `true` means the condition was true when the API returns,
  // `false` indicates an expected timeout.
  bool expected_result;

  // The expected delay before the API under test returns.  This is inherently
  // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
  // test keeps trying indefinitely until this constraint passes.
  absl::Duration expected_delay;
};

// Print a `TimeoutTestParam` to a debug log.
std::ostream &operator<<(std::ostream &os, const TimeoutTestParam &param) {
  return os << "from: " << param.from_file << ":" << param.from_line
            << " use_absolute_deadline: "
            << (param.use_absolute_deadline ? "true" : "false")
            << " wait_timeout: " << param.wait_timeout
            << " satisfy_condition_delay: " << param.satisfy_condition_delay
            << " expected_result: "
            << (param.expected_result ? "true" : "false")
            << " expected_delay: " << param.expected_delay;
}

// Like `thread::Executor::ScheduleAt` except:
// a) Delays zero or negative are executed immediately in the current thread.
// b) Infinite delays are never scheduled.
// c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
static void RunAfterDelay(absl::Duration delay,
                          absl::synchronization_internal::ThreadPool *pool,
                          const std::function<void()> &callback) {
  if (delay <= absl::ZeroDuration()) {
    callback();  // immediate
  } else if (delay != absl::InfiniteDuration()) {
    ScheduleAfter(pool, delay, callback);
  }
}

class TimeoutTest : public ::testing::Test,
                    public ::testing::WithParamInterface<TimeoutTestParam> {};

std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
  // The `finite` delay is a finite, relatively short, delay.  We make it larger
  // than our allowed scheduling delay (slop factor) to avoid confusion when
  // diagnosing test failures.  The other constants here have clear meanings.
  const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
  const absl::Duration never = absl::InfiniteDuration();
  const absl::Duration negative = -absl::InfiniteDuration();
  const absl::Duration immediate = absl::ZeroDuration();

  // Every test case is run twice; once using the absolute deadline API and once
  // using the relative timeout API.
  std::vector<TimeoutTestParam> values;
  for (bool use_absolute_deadline : {false, true}) {
    // Tests with a negative timeout (deadline in the past), which should
    // immediately return current state of the condition.

    // The condition is already true:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        negative,   // wait_timeout
        immediate,  // satisfy_condition_delay
        true,       // expected_result
        immediate,  // expected_delay
    });

    // The condition becomes true, but the timeout has already expired:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        negative,  // wait_timeout
        finite,    // satisfy_condition_delay
        false,     // expected_result
        immediate  // expected_delay
    });

    // The condition never becomes true:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        negative,  // wait_timeout
        never,     // satisfy_condition_delay
        false,     // expected_result
        immediate  // expected_delay
    });

    // Tests with an infinite timeout (deadline in the infinite future), which
    // should only return when the condition becomes true.

    // The condition is already true:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        never,      // wait_timeout
        immediate,  // satisfy_condition_delay
        true,       // expected_result
        immediate   // expected_delay
    });

    // The condition becomes true before the (infinite) expiry:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        never,   // wait_timeout
        finite,  // satisfy_condition_delay
        true,    // expected_result
        finite,  // expected_delay
    });

    // Tests with a (small) finite timeout (deadline soon), with the condition
    // becoming true both before and after its expiry.

    // The condition is already true:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        never,      // wait_timeout
        immediate,  // satisfy_condition_delay
        true,       // expected_result
        immediate   // expected_delay
    });

    // The condition becomes true before the expiry:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        finite * 2,  // wait_timeout
        finite,      // satisfy_condition_delay
        true,        // expected_result
        finite       // expected_delay
    });

    // The condition becomes true, but the timeout has already expired:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        finite,      // wait_timeout
        finite * 2,  // satisfy_condition_delay
        false,       // expected_result
        finite       // expected_delay
    });

    // The condition never becomes true:
    values.push_back(TimeoutTestParam{
        __FILE__, __LINE__, use_absolute_deadline,
        finite,  // wait_timeout
        never,   // satisfy_condition_delay
        false,   // expected_result
        finite   // expected_delay
    });
  }
  return values;
}

// Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
                         testing::ValuesIn(MakeTimeoutTestParamValues()));

TEST_P(TimeoutTest, Await) {
  const TimeoutTestParam params = GetParam();
  LOG(INFO) << "Params: " << params;

  // Because this test asserts bounds on scheduling delays it is flaky.  To
  // compensate it loops forever until it passes.  Failures express as test
  // timeouts, in which case the test log can be used to diagnose the issue.
  for (int attempt = 1;; ++attempt) {
    LOG(INFO) << "Attempt " << attempt;

    absl::Mutex mu;
    bool value = false;  // condition value (under mu)

    std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
        CreateDefaultPool();
    RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
      absl::MutexLock l(mu);
      value = true;
    });

    absl::MutexLock lock(mu);
    absl::Time start_time = absl::Now();
    absl::Condition cond(&value);
    bool result =
        params.use_absolute_deadline
            ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
            : mu.AwaitWithTimeout(cond, params.wait_timeout);
    if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
      EXPECT_EQ(params.expected_result, result);
      break;
    }
  }
}

TEST_P(TimeoutTest, LockWhen) {
  const TimeoutTestParam params = GetParam();
  LOG(INFO) << "Params: " << params;

  // Because this test asserts bounds on scheduling delays it is flaky.  To
  // compensate it loops forever until it passes.  Failures express as test
  // timeouts, in which case the test log can be used to diagnose the issue.
  for (int attempt = 1;; ++attempt) {
    LOG(INFO) << "Attempt " << attempt;

    absl::Mutex mu;
    bool value = false;  // condition value (under mu)

    std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
        CreateDefaultPool();
    RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
      absl::MutexLock l(mu);
      value = true;
    });

    absl::Time start_time = absl::Now();
    absl::Condition cond(&value);
    bool result =
        params.use_absolute_deadline
            ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
            : mu.LockWhenWithTimeout(cond, params.wait_timeout);
    mu.unlock();

    if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
      EXPECT_EQ(params.expected_result, result);
      break;
    }
  }
}

TEST_P(TimeoutTest, ReaderLockWhen) {
  const TimeoutTestParam params = GetParam();
  LOG(INFO) << "Params: " << params;

  // Because this test asserts bounds on scheduling delays it is flaky.  To
  // compensate it loops forever until it passes.  Failures express as test
  // timeouts, in which case the test log can be used to diagnose the issue.
  for (int attempt = 0;; ++attempt) {
    LOG(INFO) << "Attempt " << attempt;

    absl::Mutex mu;
    bool value = false;  // condition value (under mu)

    std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
        CreateDefaultPool();
    RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
      absl::MutexLock l(mu);
      value = true;
    });

    absl::Time start_time = absl::Now();
    bool result =
        params.use_absolute_deadline
            ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
                                            start_time + params.wait_timeout)
            : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
                                           params.wait_timeout);
    mu.unlock_shared();

    if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
      EXPECT_EQ(params.expected_result, result);
      break;
    }
  }
}

TEST_P(TimeoutTest, Wait) {
  const TimeoutTestParam params = GetParam();
  LOG(INFO) << "Params: " << params;

  // Because this test asserts bounds on scheduling delays it is flaky.  To
  // compensate it loops forever until it passes.  Failures express as test
  // timeouts, in which case the test log can be used to diagnose the issue.
  for (int attempt = 0;; ++attempt) {
    LOG(INFO) << "Attempt " << attempt;

    absl::Mutex mu;
    bool value = false;  // condition value (under mu)
    absl::CondVar cv;    // signals a change of `value`

    std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
        CreateDefaultPool();
    RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
      absl::MutexLock l(mu);
      value = true;
      cv.Signal();
    });

    absl::MutexLock lock(mu);
    absl::Time start_time = absl::Now();
    absl::Duration timeout = params.wait_timeout;
    absl::Time deadline = start_time + timeout;
    while (!value) {
      if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
                                       : cv.WaitWithTimeout(&mu, timeout)) {
        break;  // deadline/timeout exceeded
      }
      timeout = deadline - absl::Now();  // recompute
    }
    bool result = value;  // note: `mu` is still held

    if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
      EXPECT_EQ(params.expected_result, result);
      break;
    }
  }
}

TEST(Mutex, Logging) {
  // Allow user to look at logging output
  absl::Mutex logged_mutex;
  logged_mutex.EnableDebugLog("fido_mutex");
  absl::CondVar logged_cv;
  logged_cv.EnableDebugLog("rover_cv");
  logged_mutex.lock();
  logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
  logged_mutex.unlock();
  logged_mutex.lock_shared();
  logged_mutex.unlock_shared();
  logged_mutex.lock();
  logged_mutex.unlock();
  logged_cv.Signal();
  logged_cv.SignalAll();
}

TEST(Mutex, LoggingAddressReuse) {
  // Repeatedly re-create a Mutex with debug logging at the same address.
  ScopedInvariantDebugging scoped_debugging;
  alignas(absl::Mutex) unsigned char storage[sizeof(absl::Mutex)];
  auto invariant =
      +[](void *alive) { EXPECT_TRUE(*static_cast<bool *>(alive)); };
  constexpr size_t kIters = 10;
  bool alive[kIters] = {};
  for (size_t i = 0; i < kIters; ++i) {
    absl::Mutex *mu = new (storage) absl::Mutex;
    alive[i] = true;
    mu->EnableDebugLog("Mutex");
    mu->EnableInvariantDebugging(invariant, &alive[i]);
    mu->lock();
    mu->unlock();
    mu->~Mutex();
    alive[i] = false;
  }
}

TEST(Mutex, LoggingBankrupcy) {
  // Test the case with too many live Mutexes with debug logging.
  ScopedInvariantDebugging scoped_debugging;
  std::vector<absl::Mutex> mus(1 << 20);
  for (auto &mu : mus) {
    mu.EnableDebugLog("Mutex");
  }
}

TEST(Mutex, SynchEventRace) {
  // Regression test for a false TSan race report in
  // EnableInvariantDebugging/EnableDebugLog related to SynchEvent reuse.
  ScopedInvariantDebugging scoped_debugging;
  std::vector<std::thread> threads;
  for (size_t i = 0; i < 5; i++) {
    threads.emplace_back([&] {
      for (size_t j = 0; j < (1 << 17); j++) {
        {
          absl::Mutex mu;
          mu.EnableInvariantDebugging([](void *) {}, nullptr);
          mu.lock();
          mu.unlock();
        }
        {
          absl::Mutex mu;
          mu.EnableDebugLog("Mutex");
        }
      }
    });
  }
  for (auto &thread : threads) {
    thread.join();
  }
}

// --------------------------------------------------------

// Generate the vector of thread counts for tests parameterized on thread count.
static std::vector<int> AllThreadCountValues() {
  if (kExtendedTest) {
    return {2, 4, 8, 10, 16, 20, 24, 30, 32};
  }
  return {2, 4, 10};
}

// A test fixture parameterized by thread count.
class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {};

// Instantiate the above with AllThreadCountOptions().
INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
                         ::testing::ValuesIn(AllThreadCountValues()),
                         ::testing::PrintToStringParamName());

// Reduces iterations by some factor for slow platforms
// (determined empirically).
static int ScaleIterations(int x) {
  // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation
  // of Mutex that uses either std::mutex or pthread_mutex_t. Use
  // these as keys to determine the slow implementation.
#if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
  return x / 10;
#else
  return x;
#endif
}

TEST_P(MutexVariableThreadCountTest, Mutex) {
  int threads = GetParam();
  int iterations = ScaleIterations(10000000) / threads;
  int operations = threads * iterations;
  EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  iterations = std::min(iterations, 10);
  operations = threads * iterations;
  EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
                                          operations, CheckSumG0G1),
            operations);
#endif
}

TEST_P(MutexVariableThreadCountTest, Try) {
  int threads = GetParam();
  int iterations = 1000000 / threads;
  int operations = iterations * threads;
  EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  iterations = std::min(iterations, 10);
  operations = threads * iterations;
  EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
                                          operations, CheckSumG0G1),
            operations);
#endif
}

TEST_P(MutexVariableThreadCountTest, R20ms) {
  int threads = GetParam();
  int iterations = 100;
  int operations = iterations * threads;
  EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
}

TEST_P(MutexVariableThreadCountTest, RW) {
  int threads = GetParam();
  int iterations = ScaleIterations(20000000) / threads;
  int operations = iterations * threads;
  EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
  iterations = std::min(iterations, 10);
  operations = threads * iterations;
  EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
                                          operations, CheckSumG0G1),
            operations / 2);
#endif
}

TEST_P(MutexVariableThreadCountTest, Await) {
  int threads = GetParam();
  int iterations = ScaleIterations(500000);
  int operations = iterations;
  EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
}

TEST_P(MutexVariableThreadCountTest, SignalAll) {
  int threads = GetParam();
  int iterations = 200000 / threads;
  int operations = iterations;
  EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
            operations);
}

TEST(Mutex, Signal) {
  int threads = 2;  // TestSignal must use two threads
  int iterations = 200000;
  int operations = iterations;
  EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
}

TEST(Mutex, Timed) {
  int threads = 10;  // Use a fixed thread count of 10
  int iterations = 1000;
  int operations = iterations;
  EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
            operations);
}

TEST(Mutex, CVTime) {
  int threads = 10;  // Use a fixed thread count of 10
  int iterations = 1;
  EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1), threads * iterations);
}

TEST(Mutex, MuTime) {
  int threads = 10;  // Use a fixed thread count of 10
  int iterations = 1;
  EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
}

TEST(Mutex, SignalExitedThread) {
  // The test may expose a race when Mutex::unlock signals a thread
  // that has already exited.
#if defined(__wasm__) || defined(__asmjs__)
  constexpr int kThreads = 1;  // OOMs under WASM
#else
  constexpr int kThreads = 100;
#endif
  std::vector<std::thread> top;
  for (unsigned i = 0; i < 2 * std::thread::hardware_concurrency(); i++) {
    top.emplace_back([&]() {
      for (int i = 0; i < kThreads; i++) {
        absl::Mutex mu;
        std::thread t([&]() {
          mu.lock();
          mu.unlock();
        });
        mu.lock();
        mu.unlock();
        t.join();
      }
    });
  }
  for (auto &th : top) th.join();
}

TEST(Mutex, WriterPriority) {
  absl::Mutex mu;
  bool wrote = false;
  std::atomic<bool> saw_wrote{false};
  auto readfunc = [&]() {
    for (size_t i = 0; i < 10; ++i) {
      absl::ReaderMutexLock lock(mu);
      if (wrote) {
        saw_wrote = true;
        break;
      }
      absl::SleepFor(absl::Seconds(1));
    }
  };
  std::thread t1(readfunc);
  absl::SleepFor(absl::Milliseconds(500));
  std::thread t2(readfunc);
  // Note: this test guards against a bug that was related to an uninit
  // PerThreadSynch::priority, so the writer intentionally runs on a new thread.
  std::thread t3([&]() {
    // The writer should be able squeeze between the two alternating readers.
    absl::MutexLock lock(mu);
    wrote = true;
  });
  t1.join();
  t2.join();
  t3.join();
  EXPECT_TRUE(saw_wrote.load());
}

#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
TEST(Mutex, CondVarPriority) {
  // A regression test for a bug in condition variable wait morphing,
  // which resulted in the waiting thread getting priority of the waking thread.
  int err = 0;
  sched_param param;
  param.sched_priority = 7;
  std::thread test([&]() {
    err = pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);
  });
  test.join();
  if (err) {
    // Setting priority usually requires special privileges.
    GTEST_SKIP() << "failed to set priority: " << strerror(err);
  }
  absl::Mutex mu;
  absl::CondVar cv;
  bool locked = false;
  bool notified = false;
  bool waiting = false;
  bool morph = false;
  std::thread th([&]() {
    EXPECT_EQ(0, pthread_setschedparam(pthread_self(), SCHED_FIFO, &param));
    mu.lock();
    locked = true;
    mu.Await(absl::Condition(&notified));
    mu.unlock();
    EXPECT_EQ(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
                  ->per_thread_synch.priority,
              param.sched_priority);
    mu.lock();
    mu.Await(absl::Condition(&waiting));
    morph = true;
    absl::SleepFor(absl::Seconds(1));
    cv.Signal();
    mu.unlock();
  });
  mu.lock();
  mu.Await(absl::Condition(&locked));
  notified = true;
  mu.unlock();
  mu.lock();
  waiting = true;
  while (!morph) {
    cv.Wait(&mu);
  }
  mu.unlock();
  th.join();
  EXPECT_NE(absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()
                ->per_thread_synch.priority,
            param.sched_priority);
}
#endif

TEST(Mutex, LockWhenWithTimeoutResult) {
  // Check various corner cases for Await/LockWhen return value
  // with always true/always false conditions.
  absl::Mutex mu;
  const bool kAlwaysTrue = true, kAlwaysFalse = false;
  const absl::Condition kTrueCond(&kAlwaysTrue), kFalseCond(&kAlwaysFalse);
  EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
  mu.unlock();
  EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
  EXPECT_TRUE(mu.AwaitWithTimeout(kTrueCond, absl::Milliseconds(1)));
  EXPECT_FALSE(mu.AwaitWithTimeout(kFalseCond, absl::Milliseconds(1)));
  std::thread th1([&]() {
    EXPECT_TRUE(mu.LockWhenWithTimeout(kTrueCond, absl::Milliseconds(1)));
    mu.unlock();
  });
  std::thread th2([&]() {
    EXPECT_FALSE(mu.LockWhenWithTimeout(kFalseCond, absl::Milliseconds(1)));
    mu.unlock();
  });
  absl::SleepFor(absl::Milliseconds(100));
  mu.unlock();
  th1.join();
  th2.join();
}

TEST(Mutex, ScopedLock) {
  absl::Mutex mu;
  {
    std::scoped_lock l(mu);
  }

  {
    std::shared_lock l(mu);
    EXPECT_TRUE(l.owns_lock());
  }
}

}  // namespace
