// 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 <random>
#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/raw_logging.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/memory/memory.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"

namespace {

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

std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
    int threads) {
  return absl::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 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);
  ABSL_RAW_CHECK(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.TryLock());
    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);
      ABSL_RAW_CHECK(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));
    ABSL_RAW_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) {
  ABSL_RAW_CHECK(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) {
  ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration");
  ABSL_RAW_CHECK(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 {
      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
                     "TestTime failed");
    }
    absl::Duration elapsed = absl::Now() - start;
    ABSL_RAW_CHECK(
        absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
        "TestTime failed");
    ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed");

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
                     "TestTime failed");
    }
    elapsed = absl::Now() - start;
    ABSL_RAW_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 {
      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)),
                     "TestTime failed");
    }
    elapsed = absl::Now() - start;
    ABSL_RAW_CHECK(
        absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0),
        "TestTime failed");
    ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed");

    start = absl::Now();
    if (use_cv) {
      cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
    } else {
      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
                     "TestTime failed");
    }
    elapsed = absl::Now() - start;
    ABSL_RAW_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 {
      ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
                     "TestTime failed");
    }
    elapsed = absl::Now() - start;
    ABSL_RAW_CHECK(absl::Seconds(0.9) <= elapsed &&
                   elapsed <= absl::Seconds(2.0), "TestTime failed");
    ABSL_RAW_CHECK(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 {
      ABSL_RAW_CHECK(
          !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)),
          "TestTime failed");
    }
    const absl::Duration elapsed = absl::Now() - start;
    ABSL_RAW_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 {
      ABSL_RAW_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 *)) {
  absl::EnableMutexInvariantDebugging(true);
  SetInvariantChecked(false);
  TestContext cxt;
  cxt.mu.EnableInvariantDebugging(invariant, &cxt);
  int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
  ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
  absl::EnableMutexInvariantDebugging(false);  // Restore.
  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.ReaderLock();
      while (!cond1) {
        cv.Wait(&mu);
      }
      mu.ReaderUnlock();
    } else {
      mu.Lock();
      while (!cond1) {
        cv.Wait(&mu);
      }
      mu.Unlock();
    }
  }

  void Waiter2() {
    if (read_lock2) {
      mu.ReaderLockWhen(absl::Condition(&cond2));
      mu.ReaderUnlock();
    } 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.ReaderLock();
  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.ReaderUnlock();

  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::ReaderLock 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.ReaderLock();
  x->mu2.Lock();
  x->have_reader_lock = true;
  x->mu2.Await(absl::Condition(&x->complete));
  x->mu2.Unlock();
  x->mu.ReaderUnlock();
  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.ReaderLock();
  x.mu.ReaderUnlock();

  // 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 = absl::make_unique<absl::Mutex[]>(kNumLocks);
    for (int j = 0; j != kNumLocks; j++) {
      if ((j % 2) == 0) {
        mu[j].WriterLock();
      } else {
        mu[j].ReaderLock();
      }
    }
  }
}

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 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) {
  std::random_device dev;
  std::mt19937 gen(dev());
  std::uniform_int_distribution<int> random_millis(0, 15);
  mu->ReaderLock();
  while (*running == 3) {
    absl::SleepFor(absl::Milliseconds(random_millis(gen)));
    cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
  }
  mu->ReaderUnlock();
  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();
  }
  ABSL_RAW_CHECK(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.TryLock();
  mu1.Lock();  // acquire mu1 while holding mu0
  if (got_mu0) {
    mu0.Unlock();
  }
  if (mu0.TryLock()) {  // 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);
}

// 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 = absl::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.
ABSL_MUST_USE_RESULT
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) {
    ABSL_RAW_LOG(WARNING,
                 "Actual delay %s was too short, expected %s (difference %s)",
                 absl::FormatDuration(actual_delay).c_str(),
                 absl::FormatDuration(expected_delay).c_str(),
                 absl::FormatDuration(actual_delay - expected_delay).c_str());
    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) {
    ABSL_RAW_LOG(WARNING,
                 "Actual delay %s was too long, expected %s (difference %s)",
                 absl::FormatDuration(actual_delay).c_str(),
                 absl::FormatDuration(expected_delay).c_str(),
                 absl::FormatDuration(actual_delay - expected_delay).c_str());
    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;
}

std::string FormatString(const TimeoutTestParam &param) {
  std::ostringstream os;
  os << param;
  return os.str();
}

// 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();
  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());

  // 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) {
    ABSL_RAW_LOG(INFO, "Attempt %d", 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();
  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());

  // 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) {
    ABSL_RAW_LOG(INFO, "Attempt %d", 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();
  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());

  // 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) {
    ABSL_RAW_LOG(INFO, "Attempt %d", 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.ReaderUnlock();

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

TEST_P(TimeoutTest, Wait) {
  const TimeoutTestParam params = GetParam();
  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());

  // 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) {
    ABSL_RAW_LOG(INFO, "Attempt %d", 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.ReaderLock();
  logged_mutex.ReaderUnlock();
  logged_mutex.Lock();
  logged_mutex.Unlock();
  logged_cv.Signal();
  logged_cv.SignalAll();
}

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

// 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();
}

}  // namespace
