31 #include "gtest/gtest.h" 43 static constexpr
bool kExtendedTest =
false;
45 std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
47 return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads);
50 std::unique_ptr<absl::synchronization_internal::ThreadPool>
52 return CreatePool(kExtendedTest ? 32 : 10);
59 const std::function<
void()> &func) {
76 static std::atomic<bool> invariant_checked;
78 static bool GetInvariantChecked() {
79 return invariant_checked.load(std::memory_order_relaxed);
82 static void SetInvariantChecked(
bool new_value) {
83 invariant_checked.store(new_value, std::memory_order_relaxed);
86 static void CheckSumG0G1(
void *
v) {
87 TestContext *cxt =
static_cast<TestContext *
>(
v);
89 SetInvariantChecked(
true);
92 static void TestMu(TestContext *cxt,
int c) {
93 for (
int i = 0;
i != cxt->iterations;
i++) {
101 static void TestTry(TestContext *cxt,
int c) {
102 for (
int i = 0;
i != cxt->iterations;
i++) {
104 std::this_thread::yield();
105 }
while (!cxt->mu.TryLock());
113 static void TestR20ms(TestContext *cxt,
int c) {
114 for (
int i = 0;
i != cxt->iterations;
i++) {
117 cxt->mu.AssertReaderHeld();
121 static void TestRW(TestContext *cxt,
int c) {
123 for (
int i = 0;
i != cxt->iterations;
i++) {
127 cxt->mu.AssertHeld();
128 cxt->mu.AssertReaderHeld();
131 for (
int i = 0;
i != cxt->iterations;
i++) {
134 cxt->mu.AssertReaderHeld();
145 bool MyContext::MyTurn() {
146 TestContext *cxt = this->cxt;
147 return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
150 static void TestAwait(TestContext *cxt,
int c) {
155 cxt->mu.AssertHeld();
156 while (cxt->g0 < cxt->iterations) {
159 cxt->mu.AssertHeld();
160 if (cxt->g0 < cxt->iterations) {
163 mc.target += cxt->threads;
168 static void TestSignalAll(TestContext *cxt,
int c) {
171 cxt->mu.AssertHeld();
172 while (cxt->g0 < cxt->iterations) {
173 while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
174 cxt->cv.Wait(&cxt->mu);
176 if (cxt->g0 < cxt->iterations) {
180 target += cxt->threads;
185 static void TestSignal(TestContext *cxt,
int c) {
186 ABSL_RAW_CHECK(cxt->threads == 2,
"TestSignal should use 2 threads");
189 cxt->mu.AssertHeld();
190 while (cxt->g0 < cxt->iterations) {
191 while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
192 cxt->cv.Wait(&cxt->mu);
194 if (cxt->g0 < cxt->iterations) {
198 target += cxt->threads;
203 static void TestCVTimeout(TestContext *cxt,
int c) {
206 cxt->mu.AssertHeld();
207 while (cxt->g0 < cxt->iterations) {
208 while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
211 if (cxt->g0 < cxt->iterations) {
215 target += cxt->threads;
220 static bool G0GE2(TestContext *cxt) {
return cxt->g0 >= 2; }
222 static void TestTime(TestContext *cxt,
int c,
bool use_cv) {
223 ABSL_RAW_CHECK(cxt->iterations == 1,
"TestTime should only use 1 iteration");
224 ABSL_RAW_CHECK(cxt->threads > 2,
"TestTime should use more than 2 threads");
225 const bool kFalse =
false;
318 while (cxt->g0 < 2) {
329 while (cxt->g0 < 2) {
330 cxt->cv.Wait(&cxt->mu);
333 cxt->mu.Await(g0ge2);
339 static void TestMuTime(TestContext *cxt,
int c) { TestTime(cxt, c,
false); }
341 static void TestCVTime(TestContext *cxt,
int c) { TestTime(cxt, c,
true); }
344 const std::function<
void(
int)>& cb) {
355 static int RunTestCommon(TestContext *cxt,
void (*test)(TestContext *cxt,
int),
356 int threads,
int iterations,
int operations) {
363 cxt->iterations = iterations;
364 cxt->threads = threads;
366 for (
int i = 0;
i != threads;
i++) {
367 tp.
Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
368 std::function<
void(
int)>(
369 std::bind(test, cxt, std::placeholders::_1))));
372 while (c1 != threads) {
380 static int RunTest(
void (*test)(TestContext *cxt,
int),
int threads,
381 int iterations,
int operations) {
383 return RunTestCommon(&cxt, test, threads, iterations, operations);
390 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) 391 static int RunTestWithInvariantDebugging(
void (*test)(TestContext *cxt,
int),
392 int threads,
int iterations,
396 SetInvariantChecked(
false);
398 cxt.mu.EnableInvariantDebugging(
invariant, &cxt);
399 int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
408 struct TimeoutBugStruct {
414 static void WaitForA(TimeoutBugStruct *x) {
420 static bool NoAWaiters(TimeoutBugStruct *x) {
return x->a_waiter_count == 0; }
424 TEST(Mutex, CondVarWaitSignalsAwait) {
435 auto pool = CreateDefaultPool();
439 pool->Schedule([&state] {
440 state.release_mu.Lock();
442 state.barrier_mu.Lock();
443 state.barrier =
true;
444 state.barrier_mu.Unlock();
447 state.released_cv.Signal();
448 state.release_mu.Unlock();
452 state.barrier_mu.Unlock();
453 state.release_mu.Lock();
458 state.release =
true;
459 state.released_cv.Wait(&state.release_mu);
460 state.release_mu.Unlock();
465 TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
476 auto pool = CreateDefaultPool();
480 pool->Schedule([&state] {
481 state.release_mu.Lock();
483 state.barrier_mu.Lock();
484 state.barrier =
true;
485 state.barrier_mu.Unlock();
488 state.released_cv.Signal();
489 state.release_mu.Unlock();
493 state.barrier_mu.Unlock();
494 state.release_mu.Lock();
499 state.release =
true;
501 !state.released_cv.WaitWithTimeout(&state.release_mu,
absl::Seconds(10)))
502 <<
"; Unrecoverable test failure: CondVar::WaitWithTimeout did not " 503 "unblock the absl::Mutex::Await call in another thread.";
505 state.release_mu.Unlock();
509 TEST(Mutex, MutexTimeoutBug) {
510 auto tp = CreateDefaultPool();
514 x.a_waiter_count = 2;
515 tp->
Schedule(std::bind(&WaitForA, &x));
516 tp->
Schedule(std::bind(&WaitForA, &x));
523 bool always_false =
false;
534 struct CondVarWaitDeadlock : testing::TestWithParam<int> {
541 bool signal_unlocked;
543 CondVarWaitDeadlock() {
544 read_lock1 = GetParam() & (1 << 0);
545 read_lock2 = GetParam() & (1 << 1);
546 signal_unlocked = GetParam() & (1 << 2);
585 TEST_P(CondVarWaitDeadlock, Test) {
586 auto waiter1 = CreatePool(1);
587 auto waiter2 = CreatePool(1);
588 waiter1->Schedule([
this] { this->Waiter1(); });
589 waiter2->Schedule([
this] { this->Waiter2(); });
597 if (signal_unlocked) {
613 INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
614 ::testing::Range(0, 8),
615 ::testing::PrintToStringParamName());
623 struct DequeueAllWakeableBugStruct {
626 int unfinished_count;
633 static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
636 x->unfinished_count--;
637 x->done1 = (x->unfinished_count == 0);
641 x->mu.ReaderUnlock();
645 x->done2 = (x->finished_count == 0);
650 TEST(Mutex, MutexReaderWakeupBug) {
651 auto tp = CreateDefaultPool();
653 DequeueAllWakeableBugStruct x;
654 x.unfinished_count = 2;
656 x.finished_count = 2;
660 tp->
Schedule(std::bind(&AcquireAsReader, &x));
661 tp->
Schedule(std::bind(&AcquireAsReader, &x));
675 struct LockWhenTestStruct {
680 bool waiting =
false;
683 static bool LockWhenTestIsCond(LockWhenTestStruct* s) {
690 static void LockWhenTestWaitForIsCond(LockWhenTestStruct* s) {
695 TEST(Mutex, LockWhen) {
696 LockWhenTestStruct s;
698 std::thread t(LockWhenTestWaitForIsCond, &s);
712 #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE) 723 struct ReaderDecrementBugStruct {
728 bool waiting_on_cond;
729 bool have_reader_lock;
735 static bool IsCond(
void *
v) {
736 ReaderDecrementBugStruct *x =
reinterpret_cast<ReaderDecrementBugStruct *
>(
v);
738 x->waiting_on_cond =
true;
744 static bool AllDone(
void *v) {
745 ReaderDecrementBugStruct *x =
reinterpret_cast<ReaderDecrementBugStruct *
>(
v);
750 static void WaitForCond(ReaderDecrementBugStruct *x) {
759 static void GetReadLock(ReaderDecrementBugStruct *x) {
762 x->have_reader_lock =
true;
765 x->mu.ReaderUnlock();
774 ReaderDecrementBugStruct x;
776 x.waiting_on_cond =
false;
777 x.have_reader_lock =
false;
782 std::thread thread1(WaitForCond, &x);
787 std::thread thread2(GetReadLock, &x);
797 x.mu.AssertReaderHeld();
814 #endif // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE 818 #ifdef THREAD_SANITIZER 824 for (
int i = 0;
i != 10;
i++) {
826 const int kNumLocks = 10;
827 auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks);
828 for (
int j = 0; j != kNumLocks; j++) {
851 std::random_device dev;
852 std::mt19937 gen(dev());
853 std::uniform_int_distribution<int> random_millis(0, 15);
855 while (*running == 3) {
866 template <
class... Args>
867 bool operator()(Args...)
const {
872 struct DerivedTrue : True {};
874 TEST(Mutex, FunctorCondition) {
887 auto is_zero = [&
value] {
return value == 0; };
889 EXPECT_FALSE(c.Eval());
891 EXPECT_TRUE(c.Eval());
896 auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
898 EXPECT_FALSE(c.Eval());
900 EXPECT_TRUE(c.Eval());
905 std::function<bool()> is_zero = [&
value] {
return value == 0; };
907 EXPECT_FALSE(c.Eval());
909 EXPECT_TRUE(c.Eval());
913 static bool IntIsZero(
int *x) {
return *x == 0; }
917 TEST(Mutex, TestReaderOnCondVar) {
918 auto tp = CreateDefaultPool();
922 tp->
Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
923 tp->
Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
932 struct AcquireFromConditionStruct {
941 static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
944 if (x->value == 2 || x->value == 3) {
949 bool always_false =
false;
954 ABSL_RAW_CHECK(x->value < 4,
"should not be invoked a fourth time");
957 return x->value == 2 || x->value == 3;
960 static void WaitForCond2(AcquireFromConditionStruct *x) {
968 TEST(Mutex, AcquireFromCondition) {
969 auto tp = CreateDefaultPool();
971 AcquireFromConditionStruct x;
975 std::bind(&WaitForCond2, &x));
1005 #if !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) 1007 TEST(Mutex, DeadlockDetector) {
1035 class ScopedDisableBazelTestWarnings {
1037 ScopedDisableBazelTestWarnings() {
1039 char file[MAX_PATH];
1040 if (GetEnvironmentVariableA(kVarName, file,
sizeof(file)) <
sizeof(file)) {
1041 warnings_output_file_ = file;
1042 SetEnvironmentVariableA(kVarName,
nullptr);
1045 const char *file = getenv(kVarName);
1046 if (file !=
nullptr) {
1047 warnings_output_file_ = file;
1053 ~ScopedDisableBazelTestWarnings() {
1054 if (!warnings_output_file_.empty()) {
1056 SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
1058 setenv(kVarName, warnings_output_file_.c_str(), 0);
1064 static const char kVarName[];
1065 std::string warnings_output_file_;
1067 const char ScopedDisableBazelTestWarnings::kVarName[] =
1068 "TEST_WARNINGS_OUTPUT_FILE";
1070 #ifdef THREAD_SANITIZER 1072 TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
1074 TEST(Mutex, DeadlockDetectorBazelWarning) {
1080 ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
1108 const int n_locks = 1 << 17;
1109 auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks);
1110 for (
int i = 0;
i < n_locks;
i++) {
1111 int end = std::min(n_locks,
i + 5);
1113 for (
int j =
i; j <
end; j++) {
1114 array_of_locks[j].Lock();
1116 for (
int j =
i; j <
end; j++) {
1117 array_of_locks[j].Unlock();
1122 #ifdef THREAD_SANITIZER 1160 #endif // !defined(ABSL_INTERNAL_USE_NONPROD_MUTEX) 1185 if (actual_delay < expected_delay) {
1187 "Actual delay %s was too short, expected %s (difference %s)",
1199 : TimeoutTestAllowedSchedulingDelay();
1200 if (actual_delay > expected_delay + tolerance) {
1202 "Actual delay %s was too long, expected %s (difference %s)",
1212 struct TimeoutTestParam {
1214 const char *from_file;
1219 bool use_absolute_deadline;
1235 bool expected_result;
1244 std::ostream &
operator<<(std::ostream &os,
const TimeoutTestParam ¶m) {
1245 return os <<
"from: " << param.from_file <<
":" << param.from_line
1246 <<
" use_absolute_deadline: " 1247 << (param.use_absolute_deadline ?
"true" :
"false")
1248 <<
" wait_timeout: " << param.wait_timeout
1249 <<
" satisfy_condition_delay: " << param.satisfy_condition_delay
1250 <<
" expected_result: " 1251 << (param.expected_result ?
"true" :
"false")
1252 <<
" expected_delay: " << param.expected_delay;
1255 std::string FormatString(
const TimeoutTestParam ¶m) {
1256 std::ostringstream os;
1267 const std::function<
void()> &callback) {
1271 ScheduleAfter(pool, delay, callback);
1275 class TimeoutTest :
public ::testing::Test,
1276 public ::testing::WithParamInterface<TimeoutTestParam> {};
1278 std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
1282 const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
1289 std::vector<TimeoutTestParam> values;
1290 for (
bool use_absolute_deadline : {
false,
true}) {
1295 values.push_back(TimeoutTestParam{
1296 __FILE__, __LINE__, use_absolute_deadline,
1304 values.push_back(TimeoutTestParam{
1305 __FILE__, __LINE__, use_absolute_deadline,
1313 values.push_back(TimeoutTestParam{
1314 __FILE__, __LINE__, use_absolute_deadline,
1325 values.push_back(TimeoutTestParam{
1326 __FILE__, __LINE__, use_absolute_deadline,
1334 values.push_back(TimeoutTestParam{
1335 __FILE__, __LINE__, use_absolute_deadline,
1346 values.push_back(TimeoutTestParam{
1347 __FILE__, __LINE__, use_absolute_deadline,
1355 values.push_back(TimeoutTestParam{
1356 __FILE__, __LINE__, use_absolute_deadline,
1364 values.push_back(TimeoutTestParam{
1365 __FILE__, __LINE__, use_absolute_deadline,
1373 values.push_back(TimeoutTestParam{
1374 __FILE__, __LINE__, use_absolute_deadline,
1385 INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
1386 testing::ValuesIn(MakeTimeoutTestParamValues()));
1388 TEST_P(TimeoutTest, Await) {
1389 const TimeoutTestParam params = GetParam();
1390 ABSL_RAW_LOG(INFO,
"Params: %s", FormatString(params).c_str());
1395 for (
int attempt = 1;; ++attempt) {
1401 std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1402 CreateDefaultPool();
1403 RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1412 params.use_absolute_deadline
1415 if (DelayIsWithinBounds(params.expected_delay,
absl::Now() - start_time)) {
1416 EXPECT_EQ(params.expected_result, result);
1422 TEST_P(TimeoutTest, LockWhen) {
1423 const TimeoutTestParam params = GetParam();
1424 ABSL_RAW_LOG(INFO,
"Params: %s", FormatString(params).c_str());
1429 for (
int attempt = 1;; ++attempt) {
1435 std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1436 CreateDefaultPool();
1437 RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1445 params.use_absolute_deadline
1450 if (DelayIsWithinBounds(params.expected_delay,
absl::Now() - start_time)) {
1451 EXPECT_EQ(params.expected_result, result);
1457 TEST_P(TimeoutTest, ReaderLockWhen) {
1458 const TimeoutTestParam params = GetParam();
1459 ABSL_RAW_LOG(INFO,
"Params: %s", FormatString(params).c_str());
1464 for (
int attempt = 0;; ++attempt) {
1470 std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1471 CreateDefaultPool();
1472 RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1479 params.use_absolute_deadline
1481 start_time + params.wait_timeout)
1483 params.wait_timeout);
1486 if (DelayIsWithinBounds(params.expected_delay,
absl::Now() - start_time)) {
1487 EXPECT_EQ(params.expected_result, result);
1493 TEST_P(TimeoutTest, Wait) {
1494 const TimeoutTestParam params = GetParam();
1495 ABSL_RAW_LOG(INFO,
"Params: %s", FormatString(params).c_str());
1500 for (
int attempt = 0;; ++attempt) {
1507 std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1508 CreateDefaultPool();
1509 RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1526 bool result =
value;
1528 if (DelayIsWithinBounds(params.expected_delay,
absl::Now() - start_time)) {
1529 EXPECT_EQ(params.expected_result, result);
1535 TEST(Mutex, Logging) {
1541 logged_mutex.
Lock();
1546 logged_mutex.
Lock();
1555 static std::vector<int> AllThreadCountValues() {
1556 if (kExtendedTest) {
1557 return {2, 4, 8, 10, 16, 20, 24, 30, 32};
1563 class MutexVariableThreadCountTest :
public ::testing::TestWithParam<int> {};
1566 INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
1567 ::testing::ValuesIn(AllThreadCountValues()),
1568 ::testing::PrintToStringParamName());
1572 static int ScaleIterations(
int x) {
1576 #if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE) 1583 TEST_P(MutexVariableThreadCountTest, Mutex) {
1584 int threads = GetParam();
1585 int iterations = ScaleIterations(10000000) / threads;
1586 int operations = threads * iterations;
1587 EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
1588 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) 1589 iterations = std::min(iterations, 10);
1590 operations = threads * iterations;
1591 EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
1592 operations, CheckSumG0G1),
1597 TEST_P(MutexVariableThreadCountTest, Try) {
1598 int threads = GetParam();
1599 int iterations = 1000000 / threads;
1600 int operations = iterations * threads;
1601 EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
1602 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) 1603 iterations = std::min(iterations, 10);
1604 operations = threads * iterations;
1605 EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
1606 operations, CheckSumG0G1),
1611 TEST_P(MutexVariableThreadCountTest, R20ms) {
1612 int threads = GetParam();
1613 int iterations = 100;
1614 int operations = iterations * threads;
1615 EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
1618 TEST_P(MutexVariableThreadCountTest, RW) {
1619 int threads = GetParam();
1620 int iterations = ScaleIterations(20000000) / threads;
1621 int operations = iterations * threads;
1622 EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
1623 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED) 1624 iterations = std::min(iterations, 10);
1625 operations = threads * iterations;
1626 EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
1627 operations, CheckSumG0G1),
1632 TEST_P(MutexVariableThreadCountTest, Await) {
1633 int threads = GetParam();
1634 int iterations = ScaleIterations(500000);
1635 int operations = iterations;
1636 EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
1639 TEST_P(MutexVariableThreadCountTest, SignalAll) {
1640 int threads = GetParam();
1641 int iterations = 200000 / threads;
1642 int operations = iterations;
1643 EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
1647 TEST(Mutex, Signal) {
1649 int iterations = 200000;
1650 int operations = iterations;
1651 EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
1654 TEST(Mutex, Timed) {
1656 int iterations = 1000;
1657 int operations = iterations;
1658 EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
1662 TEST(Mutex, CVTime) {
1665 EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1),
1666 threads * iterations);
1669 TEST(Mutex, MuTime) {
1672 EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
bool AwaitWithDeadline(const Condition &cond, absl::Time deadline)
void ForgetDeadlockInfo()
void ReaderLockWhen(const Condition &cond) SHARED_LOCK_FUNCTION()
bool WaitWithDeadline(Mutex *mu, absl::Time deadline)
void SleepFor(absl::Duration duration)
#define ABSL_RAW_LOG(severity,...)
bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true)
void LockWhen(const Condition &cond) EXCLUSIVE_LOCK_FUNCTION()
std::ostream & operator<<(std::ostream &os, absl::LogSeverity s)
bool ReaderLockWhenWithDeadline(const Condition &cond, absl::Time deadline) SHARED_LOCK_FUNCTION()
void WriterLock() EXCLUSIVE_LOCK_FUNCTION()
constexpr Duration Milliseconds(int64_t n)
void EnableDebugLog(const char *name)
void EnableDebugLog(const char *name)
void(* invariant)(void *arg)
bool ReaderLockWhenWithTimeout(const Condition &cond, absl::Duration timeout) SHARED_LOCK_FUNCTION()
#define ABSL_RAW_CHECK(condition, message)
bool LockWhenWithDeadline(const Condition &cond, absl::Time deadline) EXCLUSIVE_LOCK_FUNCTION()
void ReaderUnlock() UNLOCK_FUNCTION()
void Unlock() UNLOCK_FUNCTION()
#define ABSL_MUST_USE_RESULT
int refcount GUARDED_BY(synch_event_mu)
std::string FormatDuration(Duration d)
bool LockWhenWithTimeout(const Condition &cond, absl::Duration timeout) EXCLUSIVE_LOCK_FUNCTION()
bool AwaitWithTimeout(const Condition &cond, absl::Duration timeout)
#define NO_THREAD_SAFETY_ANALYSIS
void Lock() EXCLUSIVE_LOCK_FUNCTION()
constexpr Duration Seconds(int64_t n)
TEST(Symbolize, Unimplemented)
void Await(const Condition &cond)
void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode)
void EnableMutexInvariantDebugging(bool enabled)
bool WaitWithTimeout(Mutex *mu, absl::Duration timeout)
void ReaderLock() SHARED_LOCK_FUNCTION()
constexpr Duration InfiniteDuration()
constexpr Duration ZeroDuration()
void Schedule(std::function< void()> func)