// 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
//
//      http://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 <vector>

#include "gtest/gtest.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,
                          const std::function<void()> &func,
                          absl::Duration after) {
  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 GUARDED_BY(barrier_mu) = false;

    absl::Mutex release_mu;
    bool release 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 GUARDED_BY(barrier_mu) = false;

    absl::Mutex release_mu;
    bool release 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_CASE_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();
}

// --------------------------------------------------------
// 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) 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).
TEST(Mutex, LockedMutexDestructionBug) NO_THREAD_SAFETY_ANALYSIS {
  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();
      }
    }
  }
}

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

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

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

// The deadlock detector is not part of non-prod builds, so do not test it.
#if !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX)

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 (GetEnvironmentVariable(kVarName, file, sizeof(file)) < sizeof(file)) {
      warnings_output_file_ = file;
      SetEnvironmentVariable(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
      SetEnvironmentVariable(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";

TEST(Mutex, DeadlockDetectorBazelWarning) {
  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, DeadlockDetectorStessTest) 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();
    }
  }
}

TEST(Mutex, DeadlockIdBug) NO_THREAD_SAFETY_ANALYSIS {
  // 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();
}
#endif  // !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX)

// --------------------------------------------------------
// 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.

// Encapsulate a Mutex-protected bool with its associated Condition/CondVar.
class Cond {
 public:
  explicit Cond(bool use_deadline) : use_deadline_(use_deadline), c_(&b_) {}

  void Set(bool v) {
    absl::MutexLock lock(&mu_);
    b_ = v;
  }

  bool AwaitWithTimeout(absl::Duration timeout) {
    absl::MutexLock lock(&mu_);
    return use_deadline_ ? mu_.AwaitWithDeadline(c_, absl::Now() + timeout)
                         : mu_.AwaitWithTimeout(c_, timeout);
  }

  bool LockWhenWithTimeout(absl::Duration timeout) {
    bool b = use_deadline_ ? mu_.LockWhenWithDeadline(c_, absl::Now() + timeout)
                           : mu_.LockWhenWithTimeout(c_, timeout);
    mu_.Unlock();
    return b;
  }

  bool ReaderLockWhenWithTimeout(absl::Duration timeout) {
    bool b = use_deadline_
                 ? mu_.ReaderLockWhenWithDeadline(c_, absl::Now() + timeout)
                 : mu_.ReaderLockWhenWithTimeout(c_, timeout);
    mu_.ReaderUnlock();
    return b;
  }

  void Await() {
    absl::MutexLock lock(&mu_);
    mu_.Await(c_);
  }

  void Signal(bool v) {
    absl::MutexLock lock(&mu_);
    b_ = v;
    cv_.Signal();
  }

  bool WaitWithTimeout(absl::Duration timeout) {
    absl::MutexLock lock(&mu_);
    absl::Time deadline = absl::Now() + timeout;
    if (use_deadline_) {
      while (!b_ && !cv_.WaitWithDeadline(&mu_, deadline)) {
      }
    } else {
      while (!b_ && !cv_.WaitWithTimeout(&mu_, timeout)) {
        timeout = deadline - absl::Now();  // recompute timeout
      }
    }
    return b_;
  }

  void Wait() {
    absl::MutexLock lock(&mu_);
    while (!b_) cv_.Wait(&mu_);
  }

 private:
  const bool use_deadline_;

  bool b_;
  absl::Condition c_;
  absl::CondVar cv_;
  absl::Mutex mu_;
};

class OperationTimer {
 public:
  OperationTimer() : start_(absl::Now()) {}
  absl::Duration Get() const { return absl::Now() - start_; }

 private:
  const absl::Time start_;
};

static void CheckResults(bool exp_result, bool act_result,
                         absl::Duration exp_duration,
                         absl::Duration act_duration) {
  ABSL_RAW_CHECK(exp_result == act_result, "CheckResults failed");
  // Allow for some worse-case scheduling delay and clock skew.
  if ((exp_duration - absl::Milliseconds(40) > act_duration) ||
      (exp_duration + absl::Milliseconds(150) < act_duration)) {
    ABSL_RAW_LOG(FATAL, "CheckResults failed: operation took %s, expected %s",
                 absl::FormatDuration(act_duration).c_str(),
                 absl::FormatDuration(exp_duration).c_str());
  }
}

static void TestAwaitTimeout(Cond *cp, absl::Duration timeout, bool exp_result,
                             absl::Duration exp_duration) {
  OperationTimer t;
  bool act_result = cp->AwaitWithTimeout(timeout);
  CheckResults(exp_result, act_result, exp_duration, t.Get());
}

static void TestLockWhenTimeout(Cond *cp, absl::Duration timeout,
                                bool exp_result, absl::Duration exp_duration) {
  OperationTimer t;
  bool act_result = cp->LockWhenWithTimeout(timeout);
  CheckResults(exp_result, act_result, exp_duration, t.Get());
}

static void TestReaderLockWhenTimeout(Cond *cp, absl::Duration timeout,
                                      bool exp_result,
                                      absl::Duration exp_duration) {
  OperationTimer t;
  bool act_result = cp->ReaderLockWhenWithTimeout(timeout);
  CheckResults(exp_result, act_result, exp_duration, t.Get());
}

static void TestWaitTimeout(Cond *cp, absl::Duration timeout, bool exp_result,
                            absl::Duration exp_duration) {
  OperationTimer t;
  bool act_result = cp->WaitWithTimeout(timeout);
  CheckResults(exp_result, act_result, exp_duration, t.Get());
}

// Tests with a negative timeout (deadline in the past), which should
// immediately return the current state of the condition.
static void TestNegativeTimeouts(absl::synchronization_internal::ThreadPool *tp,
                                 Cond *cp) {
  const absl::Duration negative = -absl::InfiniteDuration();
  const absl::Duration immediate = absl::ZeroDuration();

  // The condition is already true:
  cp->Set(true);
  TestAwaitTimeout(cp, negative, true, immediate);
  TestLockWhenTimeout(cp, negative, true, immediate);
  TestReaderLockWhenTimeout(cp, negative, true, immediate);
  TestWaitTimeout(cp, negative, true, immediate);

  // The condition becomes true, but the timeout has already expired:
  const absl::Duration delay = absl::Milliseconds(200);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), 3 * delay);
  TestAwaitTimeout(cp, negative, false, immediate);
  TestLockWhenTimeout(cp, negative, false, immediate);
  TestReaderLockWhenTimeout(cp, negative, false, immediate);
  cp->Await();  // wait for the scheduled Set() to complete
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay);
  TestWaitTimeout(cp, negative, false, immediate);
  cp->Wait();  // wait for the scheduled Signal() to complete

  // The condition never becomes true:
  cp->Set(false);
  TestAwaitTimeout(cp, negative, false, immediate);
  TestLockWhenTimeout(cp, negative, false, immediate);
  TestReaderLockWhenTimeout(cp, negative, false, immediate);
  TestWaitTimeout(cp, negative, false, immediate);
}

// Tests with an infinite timeout (deadline in the infinite future), which
// should only return when the condition becomes true.
static void TestInfiniteTimeouts(absl::synchronization_internal::ThreadPool *tp,
                                 Cond *cp) {
  const absl::Duration infinite = absl::InfiniteDuration();
  const absl::Duration immediate = absl::ZeroDuration();

  // The condition is already true:
  cp->Set(true);
  TestAwaitTimeout(cp, infinite, true, immediate);
  TestLockWhenTimeout(cp, infinite, true, immediate);
  TestReaderLockWhenTimeout(cp, infinite, true, immediate);
  TestWaitTimeout(cp, infinite, true, immediate);

  // The condition becomes true before the (infinite) expiry:
  const absl::Duration delay = absl::Milliseconds(200);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
  TestAwaitTimeout(cp, infinite, true, delay);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
  TestLockWhenTimeout(cp, infinite, true, delay);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay);
  TestReaderLockWhenTimeout(cp, infinite, true, delay);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay);
  TestWaitTimeout(cp, infinite, true, delay);
}

// Tests with a (small) finite timeout (deadline soon), with the condition
// becoming true both before and after its expiry.
static void TestFiniteTimeouts(absl::synchronization_internal::ThreadPool *tp,
                               Cond *cp) {
  const absl::Duration finite = absl::Milliseconds(400);
  const absl::Duration immediate = absl::ZeroDuration();

  // The condition is already true:
  cp->Set(true);
  TestAwaitTimeout(cp, finite, true, immediate);
  TestLockWhenTimeout(cp, finite, true, immediate);
  TestReaderLockWhenTimeout(cp, finite, true, immediate);
  TestWaitTimeout(cp, finite, true, immediate);

  // The condition becomes true before the expiry:
  const absl::Duration delay1 = finite / 2;
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
  TestAwaitTimeout(cp, finite, true, delay1);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
  TestLockWhenTimeout(cp, finite, true, delay1);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), delay1);
  TestReaderLockWhenTimeout(cp, finite, true, delay1);
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay1);
  TestWaitTimeout(cp, finite, true, delay1);

  // The condition becomes true, but the timeout has already expired:
  const absl::Duration delay2 = finite * 2;
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Set, cp, true), 3 * delay2);
  TestAwaitTimeout(cp, finite, false, finite);
  TestLockWhenTimeout(cp, finite, false, finite);
  TestReaderLockWhenTimeout(cp, finite, false, finite);
  cp->Await();  // wait for the scheduled Set() to complete
  cp->Set(false);
  ScheduleAfter(tp, std::bind(&Cond::Signal, cp, true), delay2);
  TestWaitTimeout(cp, finite, false, finite);
  cp->Wait();  // wait for the scheduled Signal() to complete

  // The condition never becomes true:
  cp->Set(false);
  TestAwaitTimeout(cp, finite, false, finite);
  TestLockWhenTimeout(cp, finite, false, finite);
  TestReaderLockWhenTimeout(cp, finite, false, finite);
  TestWaitTimeout(cp, finite, false, finite);
}

TEST(Mutex, Timeouts) {
  auto tp = CreateDefaultPool();
  for (bool use_deadline : {false, true}) {
    Cond cond(use_deadline);
    TestNegativeTimeouts(tp.get(), &cond);
    TestInfiniteTimeouts(tp.get(), &cond);
    TestFiniteTimeouts(tp.get(), &cond);
  }
}

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_CASE_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);
}

}  // namespace
