bloaty/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
Go to the documentation of this file.
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "absl/synchronization/mutex.h"
16 
17 #ifdef _WIN32
18 #include <windows.h>
19 #endif
20 
21 #include <algorithm>
22 #include <atomic>
23 #include <cstdlib>
24 #include <functional>
25 #include <memory>
26 #include <random>
27 #include <string>
28 #include <thread> // NOLINT(build/c++11)
29 #include <vector>
30 
31 #include "gtest/gtest.h"
32 #include "absl/base/attributes.h"
33 #include "absl/base/config.h"
34 #include "absl/base/internal/raw_logging.h"
35 #include "absl/base/internal/sysinfo.h"
36 #include "absl/memory/memory.h"
37 #include "absl/synchronization/internal/thread_pool.h"
38 #include "absl/time/clock.h"
39 #include "absl/time/time.h"
40 
41 namespace {
42 
43 // TODO(dmauro): Replace with a commandline flag.
44 static constexpr bool kExtendedTest = false;
45 
46 std::unique_ptr<absl::synchronization_internal::ThreadPool> CreatePool(
47  int threads) {
48  return absl::make_unique<absl::synchronization_internal::ThreadPool>(threads);
49 }
50 
51 std::unique_ptr<absl::synchronization_internal::ThreadPool>
52 CreateDefaultPool() {
53  return CreatePool(kExtendedTest ? 32 : 10);
54 }
55 
56 // Hack to schedule a function to run on a thread pool thread after a
57 // duration has elapsed.
58 static void ScheduleAfter(absl::synchronization_internal::ThreadPool *tp,
60  const std::function<void()> &func) {
61  tp->Schedule([func, after] {
63  func();
64  });
65 }
66 
67 struct TestContext {
68  int iterations;
69  int threads;
70  int g0; // global 0
71  int g1; // global 1
74 };
75 
76 // To test whether the invariant check call occurs
77 static std::atomic<bool> invariant_checked;
78 
79 static bool GetInvariantChecked() {
80  return invariant_checked.load(std::memory_order_relaxed);
81 }
82 
83 static void SetInvariantChecked(bool new_value) {
84  invariant_checked.store(new_value, std::memory_order_relaxed);
85 }
86 
87 static void CheckSumG0G1(void *v) {
88  TestContext *cxt = static_cast<TestContext *>(v);
89  ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in CheckSumG0G1");
90  SetInvariantChecked(true);
91 }
92 
93 static void TestMu(TestContext *cxt, int c) {
94  for (int i = 0; i != cxt->iterations; i++) {
95  absl::MutexLock l(&cxt->mu);
96  int a = cxt->g0 + 1;
97  cxt->g0 = a;
98  cxt->g1--;
99  }
100 }
101 
102 static void TestTry(TestContext *cxt, int c) {
103  for (int i = 0; i != cxt->iterations; i++) {
104  do {
105  std::this_thread::yield();
106  } while (!cxt->mu.TryLock());
107  int a = cxt->g0 + 1;
108  cxt->g0 = a;
109  cxt->g1--;
110  cxt->mu.Unlock();
111  }
112 }
113 
114 static void TestR20ms(TestContext *cxt, int c) {
115  for (int i = 0; i != cxt->iterations; i++) {
116  absl::ReaderMutexLock l(&cxt->mu);
118  cxt->mu.AssertReaderHeld();
119  }
120 }
121 
122 static void TestRW(TestContext *cxt, int c) {
123  if ((c & 1) == 0) {
124  for (int i = 0; i != cxt->iterations; i++) {
125  absl::WriterMutexLock l(&cxt->mu);
126  cxt->g0++;
127  cxt->g1--;
128  cxt->mu.AssertHeld();
129  cxt->mu.AssertReaderHeld();
130  }
131  } else {
132  for (int i = 0; i != cxt->iterations; i++) {
133  absl::ReaderMutexLock l(&cxt->mu);
134  ABSL_RAW_CHECK(cxt->g0 == -cxt->g1, "Error in TestRW");
135  cxt->mu.AssertReaderHeld();
136  }
137  }
138 }
139 
140 struct MyContext {
141  int target;
142  TestContext *cxt;
143  bool MyTurn();
144 };
145 
146 bool MyContext::MyTurn() {
147  TestContext *cxt = this->cxt;
148  return cxt->g0 == this->target || cxt->g0 == cxt->iterations;
149 }
150 
151 static void TestAwait(TestContext *cxt, int c) {
152  MyContext mc;
153  mc.target = c;
154  mc.cxt = cxt;
155  absl::MutexLock l(&cxt->mu);
156  cxt->mu.AssertHeld();
157  while (cxt->g0 < cxt->iterations) {
158  cxt->mu.Await(absl::Condition(&mc, &MyContext::MyTurn));
159  ABSL_RAW_CHECK(mc.MyTurn(), "Error in TestAwait");
160  cxt->mu.AssertHeld();
161  if (cxt->g0 < cxt->iterations) {
162  int a = cxt->g0 + 1;
163  cxt->g0 = a;
164  mc.target += cxt->threads;
165  }
166  }
167 }
168 
169 static void TestSignalAll(TestContext *cxt, int c) {
170  int target = c;
171  absl::MutexLock l(&cxt->mu);
172  cxt->mu.AssertHeld();
173  while (cxt->g0 < cxt->iterations) {
174  while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
175  cxt->cv.Wait(&cxt->mu);
176  }
177  if (cxt->g0 < cxt->iterations) {
178  int a = cxt->g0 + 1;
179  cxt->g0 = a;
180  cxt->cv.SignalAll();
181  target += cxt->threads;
182  }
183  }
184 }
185 
186 static void TestSignal(TestContext *cxt, int c) {
187  ABSL_RAW_CHECK(cxt->threads == 2, "TestSignal should use 2 threads");
188  int target = c;
189  absl::MutexLock l(&cxt->mu);
190  cxt->mu.AssertHeld();
191  while (cxt->g0 < cxt->iterations) {
192  while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
193  cxt->cv.Wait(&cxt->mu);
194  }
195  if (cxt->g0 < cxt->iterations) {
196  int a = cxt->g0 + 1;
197  cxt->g0 = a;
198  cxt->cv.Signal();
199  target += cxt->threads;
200  }
201  }
202 }
203 
204 static void TestCVTimeout(TestContext *cxt, int c) {
205  int target = c;
206  absl::MutexLock l(&cxt->mu);
207  cxt->mu.AssertHeld();
208  while (cxt->g0 < cxt->iterations) {
209  while (cxt->g0 != target && cxt->g0 != cxt->iterations) {
210  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
211  }
212  if (cxt->g0 < cxt->iterations) {
213  int a = cxt->g0 + 1;
214  cxt->g0 = a;
215  cxt->cv.SignalAll();
216  target += cxt->threads;
217  }
218  }
219 }
220 
221 static bool G0GE2(TestContext *cxt) { return cxt->g0 >= 2; }
222 
223 static void TestTime(TestContext *cxt, int c, bool use_cv) {
224  ABSL_RAW_CHECK(cxt->iterations == 1, "TestTime should only use 1 iteration");
225  ABSL_RAW_CHECK(cxt->threads > 2, "TestTime should use more than 2 threads");
226  const bool kFalse = false;
227  absl::Condition false_cond(&kFalse);
228  absl::Condition g0ge2(G0GE2, cxt);
229  if (c == 0) {
230  absl::MutexLock l(&cxt->mu);
231 
233  if (use_cv) {
234  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
235  } else {
236  ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
237  "TestTime failed");
238  }
239  absl::Duration elapsed = absl::Now() - start;
241  absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
242  "TestTime failed");
243  ABSL_RAW_CHECK(cxt->g0 == 1, "TestTime failed");
244 
245  start = absl::Now();
246  if (use_cv) {
247  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
248  } else {
249  ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
250  "TestTime failed");
251  }
252  elapsed = absl::Now() - start;
254  absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
255  "TestTime failed");
256  cxt->g0++;
257  if (use_cv) {
258  cxt->cv.Signal();
259  }
260 
261  start = absl::Now();
262  if (use_cv) {
263  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(4));
264  } else {
265  ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(4)),
266  "TestTime failed");
267  }
268  elapsed = absl::Now() - start;
270  absl::Seconds(3.9) <= elapsed && elapsed <= absl::Seconds(6.0),
271  "TestTime failed");
272  ABSL_RAW_CHECK(cxt->g0 >= 3, "TestTime failed");
273 
274  start = absl::Now();
275  if (use_cv) {
276  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
277  } else {
278  ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
279  "TestTime failed");
280  }
281  elapsed = absl::Now() - start;
283  absl::Seconds(0.9) <= elapsed && elapsed <= absl::Seconds(2.0),
284  "TestTime failed");
285  if (use_cv) {
286  cxt->cv.SignalAll();
287  }
288 
289  start = absl::Now();
290  if (use_cv) {
291  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(1));
292  } else {
293  ABSL_RAW_CHECK(!cxt->mu.AwaitWithTimeout(false_cond, absl::Seconds(1)),
294  "TestTime failed");
295  }
296  elapsed = absl::Now() - start;
297  ABSL_RAW_CHECK(absl::Seconds(0.9) <= elapsed &&
298  elapsed <= absl::Seconds(2.0), "TestTime failed");
299  ABSL_RAW_CHECK(cxt->g0 == cxt->threads, "TestTime failed");
300 
301  } else if (c == 1) {
302  absl::MutexLock l(&cxt->mu);
303  const absl::Time start = absl::Now();
304  if (use_cv) {
305  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Milliseconds(500));
306  } else {
308  !cxt->mu.AwaitWithTimeout(false_cond, absl::Milliseconds(500)),
309  "TestTime failed");
310  }
311  const absl::Duration elapsed = absl::Now() - start;
313  absl::Seconds(0.4) <= elapsed && elapsed <= absl::Seconds(0.9),
314  "TestTime failed");
315  cxt->g0++;
316  } else if (c == 2) {
317  absl::MutexLock l(&cxt->mu);
318  if (use_cv) {
319  while (cxt->g0 < 2) {
320  cxt->cv.WaitWithTimeout(&cxt->mu, absl::Seconds(100));
321  }
322  } else {
323  ABSL_RAW_CHECK(cxt->mu.AwaitWithTimeout(g0ge2, absl::Seconds(100)),
324  "TestTime failed");
325  }
326  cxt->g0++;
327  } else {
328  absl::MutexLock l(&cxt->mu);
329  if (use_cv) {
330  while (cxt->g0 < 2) {
331  cxt->cv.Wait(&cxt->mu);
332  }
333  } else {
334  cxt->mu.Await(g0ge2);
335  }
336  cxt->g0++;
337  }
338 }
339 
340 static void TestMuTime(TestContext *cxt, int c) { TestTime(cxt, c, false); }
341 
342 static void TestCVTime(TestContext *cxt, int c) { TestTime(cxt, c, true); }
343 
344 static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
345  const std::function<void(int)>& cb) {
346  mu->Lock();
347  int c = (*c0)++;
348  mu->Unlock();
349  cb(c);
351  (*c1)++;
352  cv->Signal();
353 }
354 
355 // Code common to RunTest() and RunTestWithInvariantDebugging().
356 static int RunTestCommon(TestContext *cxt, void (*test)(TestContext *cxt, int),
357  int threads, int iterations, int operations) {
358  absl::Mutex mu2;
359  absl::CondVar cv2;
360  int c0 = 0;
361  int c1 = 0;
362  cxt->g0 = 0;
363  cxt->g1 = 0;
364  cxt->iterations = iterations;
365  cxt->threads = threads;
367  for (int i = 0; i != threads; i++) {
368  tp.Schedule(std::bind(&EndTest, &c0, &c1, &mu2, &cv2,
369  std::function<void(int)>(
370  std::bind(test, cxt, std::placeholders::_1))));
371  }
372  mu2.Lock();
373  while (c1 != threads) {
374  cv2.Wait(&mu2);
375  }
376  mu2.Unlock();
377  return cxt->g0;
378 }
379 
380 // Basis for the parameterized tests configured below.
381 static int RunTest(void (*test)(TestContext *cxt, int), int threads,
382  int iterations, int operations) {
383  TestContext cxt;
384  return RunTestCommon(&cxt, test, threads, iterations, operations);
385 }
386 
387 // Like RunTest(), but sets an invariant on the tested Mutex and
388 // verifies that the invariant check happened. The invariant function
389 // will be passed the TestContext* as its arg and must call
390 // SetInvariantChecked(true);
391 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
392 static int RunTestWithInvariantDebugging(void (*test)(TestContext *cxt, int),
393  int threads, int iterations,
394  int operations,
395  void (*invariant)(void *)) {
397  SetInvariantChecked(false);
398  TestContext cxt;
399  cxt.mu.EnableInvariantDebugging(invariant, &cxt);
400  int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
401  ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
402  absl::EnableMutexInvariantDebugging(false); // Restore.
403  return ret;
404 }
405 #endif
406 
407 // --------------------------------------------------------
408 // Test for fix of bug in TryRemove()
409 struct TimeoutBugStruct {
410  absl::Mutex mu;
411  bool a;
412  int a_waiter_count;
413 };
414 
415 static void WaitForA(TimeoutBugStruct *x) {
416  x->mu.LockWhen(absl::Condition(&x->a));
417  x->a_waiter_count--;
418  x->mu.Unlock();
419 }
420 
421 static bool NoAWaiters(TimeoutBugStruct *x) { return x->a_waiter_count == 0; }
422 
423 // Test that a CondVar.Wait(&mutex) can un-block a call to mutex.Await() in
424 // another thread.
425 TEST(Mutex, CondVarWaitSignalsAwait) {
426  // Use a struct so the lock annotations apply.
427  struct {
428  absl::Mutex barrier_mu;
429  bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
430 
431  absl::Mutex release_mu;
432  bool release ABSL_GUARDED_BY(release_mu) = false;
433  absl::CondVar released_cv;
434  } state;
435 
436  auto pool = CreateDefaultPool();
437 
438  // Thread A. Sets barrier, waits for release using Mutex::Await, then
439  // signals released_cv.
440  pool->Schedule([&state] {
441  state.release_mu.Lock();
442 
443  state.barrier_mu.Lock();
444  state.barrier = true;
445  state.barrier_mu.Unlock();
446 
447  state.release_mu.Await(absl::Condition(&state.release));
448  state.released_cv.Signal();
449  state.release_mu.Unlock();
450  });
451 
452  state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
453  state.barrier_mu.Unlock();
454  state.release_mu.Lock();
455  // Thread A is now blocked on release by way of Mutex::Await().
456 
457  // Set release. Calling released_cv.Wait() should un-block thread A,
458  // which will signal released_cv. If not, the test will hang.
459  state.release = true;
460  state.released_cv.Wait(&state.release_mu);
461  state.release_mu.Unlock();
462 }
463 
464 // Test that a CondVar.WaitWithTimeout(&mutex) can un-block a call to
465 // mutex.Await() in another thread.
466 TEST(Mutex, CondVarWaitWithTimeoutSignalsAwait) {
467  // Use a struct so the lock annotations apply.
468  struct {
469  absl::Mutex barrier_mu;
470  bool barrier ABSL_GUARDED_BY(barrier_mu) = false;
471 
472  absl::Mutex release_mu;
473  bool release ABSL_GUARDED_BY(release_mu) = false;
474  absl::CondVar released_cv;
475  } state;
476 
477  auto pool = CreateDefaultPool();
478 
479  // Thread A. Sets barrier, waits for release using Mutex::Await, then
480  // signals released_cv.
481  pool->Schedule([&state] {
482  state.release_mu.Lock();
483 
484  state.barrier_mu.Lock();
485  state.barrier = true;
486  state.barrier_mu.Unlock();
487 
488  state.release_mu.Await(absl::Condition(&state.release));
489  state.released_cv.Signal();
490  state.release_mu.Unlock();
491  });
492 
493  state.barrier_mu.LockWhen(absl::Condition(&state.barrier));
494  state.barrier_mu.Unlock();
495  state.release_mu.Lock();
496  // Thread A is now blocked on release by way of Mutex::Await().
497 
498  // Set release. Calling released_cv.Wait() should un-block thread A,
499  // which will signal released_cv. If not, the test will hang.
500  state.release = true;
501  EXPECT_TRUE(
502  !state.released_cv.WaitWithTimeout(&state.release_mu, absl::Seconds(10)))
503  << "; Unrecoverable test failure: CondVar::WaitWithTimeout did not "
504  "unblock the absl::Mutex::Await call in another thread.";
505 
506  state.release_mu.Unlock();
507 }
508 
509 // Test for regression of a bug in loop of TryRemove()
510 TEST(Mutex, MutexTimeoutBug) {
511  auto tp = CreateDefaultPool();
512 
513  TimeoutBugStruct x;
514  x.a = false;
515  x.a_waiter_count = 2;
516  tp->Schedule(std::bind(&WaitForA, &x));
517  tp->Schedule(std::bind(&WaitForA, &x));
518  absl::SleepFor(absl::Seconds(1)); // Allow first two threads to hang.
519  // The skip field of the second will point to the first because there are
520  // only two.
521 
522  // Now cause a thread waiting on an always-false to time out
523  // This would deadlock when the bug was present.
524  bool always_false = false;
525  x.mu.LockWhenWithTimeout(absl::Condition(&always_false),
526  absl::Milliseconds(500));
527 
528  // if we get here, the bug is not present. Cleanup the state.
529 
530  x.a = true; // wakeup the two waiters on A
531  x.mu.Await(absl::Condition(&NoAWaiters, &x)); // wait for them to exit
532  x.mu.Unlock();
533 }
534 
535 struct CondVarWaitDeadlock : testing::TestWithParam<int> {
536  absl::Mutex mu;
538  bool cond1 = false;
539  bool cond2 = false;
540  bool read_lock1;
541  bool read_lock2;
542  bool signal_unlocked;
543 
544  CondVarWaitDeadlock() {
545  read_lock1 = GetParam() & (1 << 0);
546  read_lock2 = GetParam() & (1 << 1);
547  signal_unlocked = GetParam() & (1 << 2);
548  }
549 
550  void Waiter1() {
551  if (read_lock1) {
552  mu.ReaderLock();
553  while (!cond1) {
554  cv.Wait(&mu);
555  }
556  mu.ReaderUnlock();
557  } else {
558  mu.Lock();
559  while (!cond1) {
560  cv.Wait(&mu);
561  }
562  mu.Unlock();
563  }
564  }
565 
566  void Waiter2() {
567  if (read_lock2) {
568  mu.ReaderLockWhen(absl::Condition(&cond2));
569  mu.ReaderUnlock();
570  } else {
571  mu.LockWhen(absl::Condition(&cond2));
572  mu.Unlock();
573  }
574  }
575 };
576 
577 // Test for a deadlock bug in Mutex::Fer().
578 // The sequence of events that lead to the deadlock is:
579 // 1. waiter1 blocks on cv in read mode (mu bits = 0).
580 // 2. waiter2 blocks on mu in either mode (mu bits = kMuWait).
581 // 3. main thread locks mu, sets cond1, unlocks mu (mu bits = kMuWait).
582 // 4. main thread signals on cv and this eventually calls Mutex::Fer().
583 // Currently Fer wakes waiter1 since mu bits = kMuWait (mutex is unlocked).
584 // Before the bug fix Fer neither woke waiter1 nor queued it on mutex,
585 // which resulted in deadlock.
586 TEST_P(CondVarWaitDeadlock, Test) {
587  auto waiter1 = CreatePool(1);
588  auto waiter2 = CreatePool(1);
589  waiter1->Schedule([this] { this->Waiter1(); });
590  waiter2->Schedule([this] { this->Waiter2(); });
591 
592  // Wait while threads block (best-effort is fine).
594 
595  // Wake condwaiter.
596  mu.Lock();
597  cond1 = true;
598  if (signal_unlocked) {
599  mu.Unlock();
600  cv.Signal();
601  } else {
602  cv.Signal();
603  mu.Unlock();
604  }
605  waiter1.reset(); // "join" waiter1
606 
607  // Wake waiter.
608  mu.Lock();
609  cond2 = true;
610  mu.Unlock();
611  waiter2.reset(); // "join" waiter2
612 }
613 
614 INSTANTIATE_TEST_SUITE_P(CondVarWaitDeadlockTest, CondVarWaitDeadlock,
615  ::testing::Range(0, 8),
617 
618 // --------------------------------------------------------
619 // Test for fix of bug in DequeueAllWakeable()
620 // Bug was that if there was more than one waiting reader
621 // and all should be woken, the most recently blocked one
622 // would not be.
623 
624 struct DequeueAllWakeableBugStruct {
625  absl::Mutex mu;
626  absl::Mutex mu2; // protects all fields below
627  int unfinished_count; // count of unfinished readers; under mu2
628  bool done1; // unfinished_count == 0; under mu2
629  int finished_count; // count of finished readers, under mu2
630  bool done2; // finished_count == 0; under mu2
631 };
632 
633 // Test for regression of a bug in loop of DequeueAllWakeable()
634 static void AcquireAsReader(DequeueAllWakeableBugStruct *x) {
635  x->mu.ReaderLock();
636  x->mu2.Lock();
637  x->unfinished_count--;
638  x->done1 = (x->unfinished_count == 0);
639  x->mu2.Unlock();
640  // make sure that both readers acquired mu before we release it.
642  x->mu.ReaderUnlock();
643 
644  x->mu2.Lock();
645  x->finished_count--;
646  x->done2 = (x->finished_count == 0);
647  x->mu2.Unlock();
648 }
649 
650 // Test for regression of a bug in loop of DequeueAllWakeable()
651 TEST(Mutex, MutexReaderWakeupBug) {
652  auto tp = CreateDefaultPool();
653 
654  DequeueAllWakeableBugStruct x;
655  x.unfinished_count = 2;
656  x.done1 = false;
657  x.finished_count = 2;
658  x.done2 = false;
659  x.mu.Lock(); // acquire mu exclusively
660  // queue two thread that will block on reader locks on x.mu
661  tp->Schedule(std::bind(&AcquireAsReader, &x));
662  tp->Schedule(std::bind(&AcquireAsReader, &x));
663  absl::SleepFor(absl::Seconds(1)); // give time for reader threads to block
664  x.mu.Unlock(); // wake them up
665 
666  // both readers should finish promptly
667  EXPECT_TRUE(
668  x.mu2.LockWhenWithTimeout(absl::Condition(&x.done1), absl::Seconds(10)));
669  x.mu2.Unlock();
670 
671  EXPECT_TRUE(
672  x.mu2.LockWhenWithTimeout(absl::Condition(&x.done2), absl::Seconds(10)));
673  x.mu2.Unlock();
674 }
675 
676 struct LockWhenTestStruct {
677  absl::Mutex mu1;
678  bool cond = false;
679 
680  absl::Mutex mu2;
681  bool waiting = false;
682 };
683 
684 static bool LockWhenTestIsCond(LockWhenTestStruct* s) {
685  s->mu2.Lock();
686  s->waiting = true;
687  s->mu2.Unlock();
688  return s->cond;
689 }
690 
691 static void LockWhenTestWaitForIsCond(LockWhenTestStruct* s) {
692  s->mu1.LockWhen(absl::Condition(&LockWhenTestIsCond, s));
693  s->mu1.Unlock();
694 }
695 
696 TEST(Mutex, LockWhen) {
697  LockWhenTestStruct s;
698 
699  std::thread t(LockWhenTestWaitForIsCond, &s);
700  s.mu2.LockWhen(absl::Condition(&s.waiting));
701  s.mu2.Unlock();
702 
703  s.mu1.Lock();
704  s.cond = true;
705  s.mu1.Unlock();
706 
707  t.join();
708 }
709 
710 TEST(Mutex, LockWhenGuard) {
711  absl::Mutex mu;
712  int n = 30;
713  bool done = false;
714 
715  // We don't inline the lambda because the conversion is ambiguous in MSVC.
716  bool (*cond_eq_10)(int *) = [](int *p) { return *p == 10; };
717  bool (*cond_lt_10)(int *) = [](int *p) { return *p < 10; };
718 
719  std::thread t1([&mu, &n, &done, cond_eq_10]() {
720  absl::ReaderMutexLock lock(&mu, absl::Condition(cond_eq_10, &n));
721  done = true;
722  });
723 
724  std::thread t2[10];
725  for (std::thread &t : t2) {
726  t = std::thread([&mu, &n, cond_lt_10]() {
727  absl::WriterMutexLock lock(&mu, absl::Condition(cond_lt_10, &n));
728  ++n;
729  });
730  }
731 
732  {
733  absl::MutexLock lock(&mu);
734  n = 0;
735  }
736 
737  for (std::thread &t : t2) t.join();
738  t1.join();
739 
740  EXPECT_TRUE(done);
741  EXPECT_EQ(n, 10);
742 }
743 
744 // --------------------------------------------------------
745 // The following test requires Mutex::ReaderLock to be a real shared
746 // lock, which is not the case in all builds.
747 #if !defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
748 
749 // Test for fix of bug in UnlockSlow() that incorrectly decremented the reader
750 // count when putting a thread to sleep waiting for a false condition when the
751 // lock was not held.
752 
753 // For this bug to strike, we make a thread wait on a free mutex with no
754 // waiters by causing its wakeup condition to be false. Then the
755 // next two acquirers must be readers. The bug causes the lock
756 // to be released when one reader unlocks, rather than both.
757 
758 struct ReaderDecrementBugStruct {
759  bool cond; // to delay first thread (under mu)
760  int done; // reference count (under mu)
761  absl::Mutex mu;
762 
763  bool waiting_on_cond; // under mu2
764  bool have_reader_lock; // under mu2
765  bool complete; // under mu2
766  absl::Mutex mu2; // > mu
767 };
768 
769 // L >= mu, L < mu_waiting_on_cond
770 static bool IsCond(void *v) {
771  ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
772  x->mu2.Lock();
773  x->waiting_on_cond = true;
774  x->mu2.Unlock();
775  return x->cond;
776 }
777 
778 // L >= mu
779 static bool AllDone(void *v) {
780  ReaderDecrementBugStruct *x = reinterpret_cast<ReaderDecrementBugStruct *>(v);
781  return x->done == 0;
782 }
783 
784 // L={}
785 static void WaitForCond(ReaderDecrementBugStruct *x) {
788  x->mu.LockWhen(absl::Condition(&IsCond, x));
789  x->done--;
790  x->mu.Unlock();
791 }
792 
793 // L={}
794 static void GetReadLock(ReaderDecrementBugStruct *x) {
795  x->mu.ReaderLock();
796  x->mu2.Lock();
797  x->have_reader_lock = true;
798  x->mu2.Await(absl::Condition(&x->complete));
799  x->mu2.Unlock();
800  x->mu.ReaderUnlock();
801  x->mu.Lock();
802  x->done--;
803  x->mu.Unlock();
804 }
805 
806 // Test for reader counter being decremented incorrectly by waiter
807 // with false condition.
808 TEST(Mutex, MutexReaderDecrementBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
809  ReaderDecrementBugStruct x;
810  x.cond = false;
811  x.waiting_on_cond = false;
812  x.have_reader_lock = false;
813  x.complete = false;
814  x.done = 2; // initial ref count
815 
816  // Run WaitForCond() and wait for it to sleep
817  std::thread thread1(WaitForCond, &x);
818  x.mu2.LockWhen(absl::Condition(&x.waiting_on_cond));
819  x.mu2.Unlock();
820 
821  // Run GetReadLock(), and wait for it to get the read lock
822  std::thread thread2(GetReadLock, &x);
823  x.mu2.LockWhen(absl::Condition(&x.have_reader_lock));
824  x.mu2.Unlock();
825 
826  // Get the reader lock ourselves, and release it.
827  x.mu.ReaderLock();
828  x.mu.ReaderUnlock();
829 
830  // The lock should be held in read mode by GetReadLock().
831  // If we have the bug, the lock will be free.
832  x.mu.AssertReaderHeld();
833 
834  // Wake up all the threads.
835  x.mu2.Lock();
836  x.complete = true;
837  x.mu2.Unlock();
838 
839  // TODO(delesley): turn on analysis once lock upgrading is supported.
840  // (This call upgrades the lock from shared to exclusive.)
841  x.mu.Lock();
842  x.cond = true;
843  x.mu.Await(absl::Condition(&AllDone, &x));
844  x.mu.Unlock();
845 
846  thread1.join();
847  thread2.join();
848 }
849 #endif // !ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE
850 
851 // Test that we correctly handle the situation when a lock is
852 // held and then destroyed (w/o unlocking).
853 #ifdef ABSL_HAVE_THREAD_SANITIZER
854 // TSAN reports errors when locked Mutexes are destroyed.
855 TEST(Mutex, DISABLED_LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
856 #else
857 TEST(Mutex, LockedMutexDestructionBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
858 #endif
859  for (int i = 0; i != 10; i++) {
860  // Create, lock and destroy 10 locks.
861  const int kNumLocks = 10;
862  auto mu = absl::make_unique<absl::Mutex[]>(kNumLocks);
863  for (int j = 0; j != kNumLocks; j++) {
864  if ((j % 2) == 0) {
865  mu[j].WriterLock();
866  } else {
867  mu[j].ReaderLock();
868  }
869  }
870  }
871 }
872 
873 // --------------------------------------------------------
874 // Test for bug with pattern of readers using a condvar. The bug was that if a
875 // reader went to sleep on a condition variable while one or more other readers
876 // held the lock, but there were no waiters, the reader count (held in the
877 // mutex word) would be lost. (This is because Enqueue() had at one time
878 // always placed the thread on the Mutex queue. Later (CL 4075610), to
879 // tolerate re-entry into Mutex from a Condition predicate, Enqueue() was
880 // changed so that it could also place a thread on a condition-variable. This
881 // introduced the case where Enqueue() returned with an empty queue, and this
882 // case was handled incorrectly in one place.)
883 
884 static void ReaderForReaderOnCondVar(absl::Mutex *mu, absl::CondVar *cv,
885  int *running) {
886  std::random_device dev;
887  std::mt19937 gen(dev());
888  std::uniform_int_distribution<int> random_millis(0, 15);
889  mu->ReaderLock();
890  while (*running == 3) {
891  absl::SleepFor(absl::Milliseconds(random_millis(gen)));
892  cv->WaitWithTimeout(mu, absl::Milliseconds(random_millis(gen)));
893  }
894  mu->ReaderUnlock();
895  mu->Lock();
896  (*running)--;
897  mu->Unlock();
898 }
899 
900 struct True {
901  template <class... Args>
902  bool operator()(Args...) const {
903  return true;
904  }
905 };
906 
907 struct DerivedTrue : True {};
908 
909 TEST(Mutex, FunctorCondition) {
910  { // Variadic
911  True f;
912  EXPECT_TRUE(absl::Condition(&f).Eval());
913  }
914 
915  { // Inherited
916  DerivedTrue g;
917  EXPECT_TRUE(absl::Condition(&g).Eval());
918  }
919 
920  { // lambda
921  int value = 3;
922  auto is_zero = [&value] { return value == 0; };
923  absl::Condition c(&is_zero);
924  EXPECT_FALSE(c.Eval());
925  value = 0;
926  EXPECT_TRUE(c.Eval());
927  }
928 
929  { // bind
930  int value = 0;
931  auto is_positive = std::bind(std::less<int>(), 0, std::cref(value));
932  absl::Condition c(&is_positive);
933  EXPECT_FALSE(c.Eval());
934  value = 1;
935  EXPECT_TRUE(c.Eval());
936  }
937 
938  { // std::function
939  int value = 3;
940  std::function<bool()> is_zero = [&value] { return value == 0; };
941  absl::Condition c(&is_zero);
942  EXPECT_FALSE(c.Eval());
943  value = 0;
944  EXPECT_TRUE(c.Eval());
945  }
946 }
947 
948 static bool IntIsZero(int *x) { return *x == 0; }
949 
950 // Test for reader waiting condition variable when there are other readers
951 // but no waiters.
952 TEST(Mutex, TestReaderOnCondVar) {
953  auto tp = CreateDefaultPool();
954  absl::Mutex mu;
956  int running = 3;
957  tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
958  tp->Schedule(std::bind(&ReaderForReaderOnCondVar, &mu, &cv, &running));
960  mu.Lock();
961  running--;
962  mu.Await(absl::Condition(&IntIsZero, &running));
963  mu.Unlock();
964 }
965 
966 // --------------------------------------------------------
967 struct AcquireFromConditionStruct {
968  absl::Mutex mu0; // protects value, done
969  int value; // times condition function is called; under mu0,
970  bool done; // done with test? under mu0
971  absl::Mutex mu1; // used to attempt to mess up state of mu0
972  absl::CondVar cv; // so the condition function can be invoked from
973  // CondVar::Wait().
974 };
975 
976 static bool ConditionWithAcquire(AcquireFromConditionStruct *x) {
977  x->value++; // count times this function is called
978 
979  if (x->value == 2 || x->value == 3) {
980  // On the second and third invocation of this function, sleep for 100ms,
981  // but with the side-effect of altering the state of a Mutex other than
982  // than one for which this is a condition. The spec now explicitly allows
983  // this side effect; previously it did not. it was illegal.
984  bool always_false = false;
985  x->mu1.LockWhenWithTimeout(absl::Condition(&always_false),
986  absl::Milliseconds(100));
987  x->mu1.Unlock();
988  }
989  ABSL_RAW_CHECK(x->value < 4, "should not be invoked a fourth time");
990 
991  // We arrange for the condition to return true on only the 2nd and 3rd calls.
992  return x->value == 2 || x->value == 3;
993 }
994 
995 static void WaitForCond2(AcquireFromConditionStruct *x) {
996  // wait for cond0 to become true
997  x->mu0.LockWhen(absl::Condition(&ConditionWithAcquire, x));
998  x->done = true;
999  x->mu0.Unlock();
1000 }
1001 
1002 // Test for Condition whose function acquires other Mutexes
1003 TEST(Mutex, AcquireFromCondition) {
1004  auto tp = CreateDefaultPool();
1005 
1006  AcquireFromConditionStruct x;
1007  x.value = 0;
1008  x.done = false;
1009  tp->Schedule(
1010  std::bind(&WaitForCond2, &x)); // run WaitForCond2() in a thread T
1011  // T will hang because the first invocation of ConditionWithAcquire() will
1012  // return false.
1013  absl::SleepFor(absl::Milliseconds(500)); // allow T time to hang
1014 
1015  x.mu0.Lock();
1016  x.cv.WaitWithTimeout(&x.mu0, absl::Milliseconds(500)); // wake T
1017  // T will be woken because the Wait() will call ConditionWithAcquire()
1018  // for the second time, and it will return true.
1019 
1020  x.mu0.Unlock();
1021 
1022  // T will then acquire the lock and recheck its own condition.
1023  // It will find the condition true, as this is the third invocation,
1024  // but the use of another Mutex by the calling function will
1025  // cause the old mutex implementation to think that the outer
1026  // LockWhen() has timed out because the inner LockWhenWithTimeout() did.
1027  // T will then check the condition a fourth time because it finds a
1028  // timeout occurred. This should not happen in the new
1029  // implementation that allows the Condition function to use Mutexes.
1030 
1031  // It should also succeed, even though the Condition function
1032  // is being invoked from CondVar::Wait, and thus this thread
1033  // is conceptually waiting both on the condition variable, and on mu2.
1034 
1035  x.mu0.LockWhen(absl::Condition(&x.done));
1036  x.mu0.Unlock();
1037 }
1038 
1039 TEST(Mutex, DeadlockDetector) {
1041 
1042  // check that we can call ForgetDeadlockInfo() on a lock with the lock held
1043  absl::Mutex m1;
1044  absl::Mutex m2;
1045  absl::Mutex m3;
1046  absl::Mutex m4;
1047 
1048  m1.Lock(); // m1 gets ID1
1049  m2.Lock(); // m2 gets ID2
1050  m3.Lock(); // m3 gets ID3
1051  m3.Unlock();
1052  m2.Unlock();
1053  // m1 still held
1054  m1.ForgetDeadlockInfo(); // m1 loses ID
1055  m2.Lock(); // m2 gets ID2
1056  m3.Lock(); // m3 gets ID3
1057  m4.Lock(); // m4 gets ID4
1058  m3.Unlock();
1059  m2.Unlock();
1060  m4.Unlock();
1061  m1.Unlock();
1062 }
1063 
1064 // Bazel has a test "warning" file that programs can write to if the
1065 // test should pass with a warning. This class disables the warning
1066 // file until it goes out of scope.
1067 class ScopedDisableBazelTestWarnings {
1068  public:
1069  ScopedDisableBazelTestWarnings() {
1070 #ifdef _WIN32
1071  char file[MAX_PATH];
1072  if (GetEnvironmentVariableA(kVarName, file, sizeof(file)) < sizeof(file)) {
1073  warnings_output_file_ = file;
1074  SetEnvironmentVariableA(kVarName, nullptr);
1075  }
1076 #else
1077  const char *file = getenv(kVarName);
1078  if (file != nullptr) {
1079  warnings_output_file_ = file;
1080  unsetenv(kVarName);
1081  }
1082 #endif
1083  }
1084 
1085  ~ScopedDisableBazelTestWarnings() {
1086  if (!warnings_output_file_.empty()) {
1087 #ifdef _WIN32
1088  SetEnvironmentVariableA(kVarName, warnings_output_file_.c_str());
1089 #else
1090  setenv(kVarName, warnings_output_file_.c_str(), 0);
1091 #endif
1092  }
1093  }
1094 
1095  private:
1096  static const char kVarName[];
1097  std::string warnings_output_file_;
1098 };
1099 const char ScopedDisableBazelTestWarnings::kVarName[] =
1100  "TEST_WARNINGS_OUTPUT_FILE";
1101 
1102 #ifdef ABSL_HAVE_THREAD_SANITIZER
1103 // This test intentionally creates deadlocks to test the deadlock detector.
1104 TEST(Mutex, DISABLED_DeadlockDetectorBazelWarning) {
1105 #else
1106 TEST(Mutex, DeadlockDetectorBazelWarning) {
1107 #endif
1109 
1110  // Cause deadlock detection to detect something, if it's
1111  // compiled in and enabled. But turn off the bazel warning.
1112  ScopedDisableBazelTestWarnings disable_bazel_test_warnings;
1113 
1114  absl::Mutex mu0;
1115  absl::Mutex mu1;
1116  bool got_mu0 = mu0.TryLock();
1117  mu1.Lock(); // acquire mu1 while holding mu0
1118  if (got_mu0) {
1119  mu0.Unlock();
1120  }
1121  if (mu0.TryLock()) { // try lock shouldn't cause deadlock detector to fire
1122  mu0.Unlock();
1123  }
1124  mu0.Lock(); // acquire mu0 while holding mu1; should get one deadlock
1125  // report here
1126  mu0.Unlock();
1127  mu1.Unlock();
1128 
1130 }
1131 
1132 // This test is tagged with NO_THREAD_SAFETY_ANALYSIS because the
1133 // annotation-based static thread-safety analysis is not currently
1134 // predicate-aware and cannot tell if the two for-loops that acquire and
1135 // release the locks have the same predicates.
1136 TEST(Mutex, DeadlockDetectorStressTest) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1137  // Stress test: Here we create a large number of locks and use all of them.
1138  // If a deadlock detector keeps a full graph of lock acquisition order,
1139  // it will likely be too slow for this test to pass.
1140  const int n_locks = 1 << 17;
1141  auto array_of_locks = absl::make_unique<absl::Mutex[]>(n_locks);
1142  for (int i = 0; i < n_locks; i++) {
1143  int end = std::min(n_locks, i + 5);
1144  // acquire and then release locks i, i+1, ..., i+4
1145  for (int j = i; j < end; j++) {
1146  array_of_locks[j].Lock();
1147  }
1148  for (int j = i; j < end; j++) {
1149  array_of_locks[j].Unlock();
1150  }
1151  }
1152 }
1153 
1154 #ifdef ABSL_HAVE_THREAD_SANITIZER
1155 // TSAN reports errors when locked Mutexes are destroyed.
1156 TEST(Mutex, DISABLED_DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1157 #else
1158 TEST(Mutex, DeadlockIdBug) ABSL_NO_THREAD_SAFETY_ANALYSIS {
1159 #endif
1160  // Test a scenario where a cached deadlock graph node id in the
1161  // list of held locks is not invalidated when the corresponding
1162  // mutex is deleted.
1164  // Mutex that will be destroyed while being held
1165  absl::Mutex *a = new absl::Mutex;
1166  // Other mutexes needed by test
1167  absl::Mutex b, c;
1168 
1169  // Hold mutex.
1170  a->Lock();
1171 
1172  // Force deadlock id assignment by acquiring another lock.
1173  b.Lock();
1174  b.Unlock();
1175 
1176  // Delete the mutex. The Mutex destructor tries to remove held locks,
1177  // but the attempt isn't foolproof. It can fail if:
1178  // (a) Deadlock detection is currently disabled.
1179  // (b) The destruction is from another thread.
1180  // We exploit (a) by temporarily disabling deadlock detection.
1182  delete a;
1184 
1185  // Now acquire another lock which will force a deadlock id assignment.
1186  // We should end up getting assigned the same deadlock id that was
1187  // freed up when "a" was deleted, which will cause a spurious deadlock
1188  // report if the held lock entry for "a" was not invalidated.
1189  c.Lock();
1190  c.Unlock();
1191 }
1192 
1193 // --------------------------------------------------------
1194 // Test for timeouts/deadlines on condition waits that are specified using
1195 // absl::Duration and absl::Time. For each waiting function we test with
1196 // a timeout/deadline that has already expired/passed, one that is infinite
1197 // and so never expires/passes, and one that will expire/pass in the near
1198 // future.
1199 
1200 static absl::Duration TimeoutTestAllowedSchedulingDelay() {
1201  // Note: we use a function here because Microsoft Visual Studio fails to
1202  // properly initialize constexpr static absl::Duration variables.
1203  return absl::Milliseconds(150);
1204 }
1205 
1206 // Returns true if `actual_delay` is close enough to `expected_delay` to pass
1207 // the timeouts/deadlines test. Otherwise, logs warnings and returns false.
1209 static bool DelayIsWithinBounds(absl::Duration expected_delay,
1210  absl::Duration actual_delay) {
1211  bool pass = true;
1212  // Do not allow the observed delay to be less than expected. This may occur
1213  // in practice due to clock skew or when the synchronization primitives use a
1214  // different clock than absl::Now(), but these cases should be handled by the
1215  // the retry mechanism in each TimeoutTest.
1216  if (actual_delay < expected_delay) {
1218  "Actual delay %s was too short, expected %s (difference %s)",
1219  absl::FormatDuration(actual_delay).c_str(),
1220  absl::FormatDuration(expected_delay).c_str(),
1221  absl::FormatDuration(actual_delay - expected_delay).c_str());
1222  pass = false;
1223  }
1224  // If the expected delay is <= zero then allow a small error tolerance, since
1225  // we do not expect context switches to occur during test execution.
1226  // Otherwise, thread scheduling delays may be substantial in rare cases, so
1227  // tolerate up to kTimeoutTestAllowedSchedulingDelay of error.
1228  absl::Duration tolerance = expected_delay <= absl::ZeroDuration()
1229  ? absl::Milliseconds(10)
1230  : TimeoutTestAllowedSchedulingDelay();
1231  if (actual_delay > expected_delay + tolerance) {
1233  "Actual delay %s was too long, expected %s (difference %s)",
1234  absl::FormatDuration(actual_delay).c_str(),
1235  absl::FormatDuration(expected_delay).c_str(),
1236  absl::FormatDuration(actual_delay - expected_delay).c_str());
1237  pass = false;
1238  }
1239  return pass;
1240 }
1241 
1242 // Parameters for TimeoutTest, below.
1243 struct TimeoutTestParam {
1244  // The file and line number (used for logging purposes only).
1245  const char *from_file;
1246  int from_line;
1247 
1248  // Should the absolute deadline API based on absl::Time be tested? If false,
1249  // the relative deadline API based on absl::Duration is tested.
1250  bool use_absolute_deadline;
1251 
1252  // The deadline/timeout used when calling the API being tested
1253  // (e.g. Mutex::LockWhenWithDeadline).
1254  absl::Duration wait_timeout;
1255 
1256  // The delay before the condition will be set true by the test code. If zero
1257  // or negative, the condition is set true immediately (before calling the API
1258  // being tested). Otherwise, if infinite, the condition is never set true.
1259  // Otherwise a closure is scheduled for the future that sets the condition
1260  // true.
1261  absl::Duration satisfy_condition_delay;
1262 
1263  // The expected result of the condition after the call to the API being
1264  // tested. Generally `true` means the condition was true when the API returns,
1265  // `false` indicates an expected timeout.
1266  bool expected_result;
1267 
1268  // The expected delay before the API under test returns. This is inherently
1269  // flaky, so some slop is allowed (see `DelayIsWithinBounds` above), and the
1270  // test keeps trying indefinitely until this constraint passes.
1271  absl::Duration expected_delay;
1272 };
1273 
1274 // Print a `TimeoutTestParam` to a debug log.
1275 std::ostream &operator<<(std::ostream &os, const TimeoutTestParam &param) {
1276  return os << "from: " << param.from_file << ":" << param.from_line
1277  << " use_absolute_deadline: "
1278  << (param.use_absolute_deadline ? "true" : "false")
1279  << " wait_timeout: " << param.wait_timeout
1280  << " satisfy_condition_delay: " << param.satisfy_condition_delay
1281  << " expected_result: "
1282  << (param.expected_result ? "true" : "false")
1283  << " expected_delay: " << param.expected_delay;
1284 }
1285 
1286 std::string FormatString(const TimeoutTestParam &param) {
1287  std::ostringstream os;
1288  os << param;
1289  return os.str();
1290 }
1291 
1292 // Like `thread::Executor::ScheduleAt` except:
1293 // a) Delays zero or negative are executed immediately in the current thread.
1294 // b) Infinite delays are never scheduled.
1295 // c) Calls this test's `ScheduleAt` helper instead of using `pool` directly.
1296 static void RunAfterDelay(absl::Duration delay,
1298  const std::function<void()> &callback) {
1299  if (delay <= absl::ZeroDuration()) {
1300  callback(); // immediate
1301  } else if (delay != absl::InfiniteDuration()) {
1302  ScheduleAfter(pool, delay, callback);
1303  }
1304 }
1305 
1306 class TimeoutTest : public ::testing::Test,
1307  public ::testing::WithParamInterface<TimeoutTestParam> {};
1308 
1309 std::vector<TimeoutTestParam> MakeTimeoutTestParamValues() {
1310  // The `finite` delay is a finite, relatively short, delay. We make it larger
1311  // than our allowed scheduling delay (slop factor) to avoid confusion when
1312  // diagnosing test failures. The other constants here have clear meanings.
1313  const absl::Duration finite = 3 * TimeoutTestAllowedSchedulingDelay();
1316  const absl::Duration immediate = absl::ZeroDuration();
1317 
1318  // Every test case is run twice; once using the absolute deadline API and once
1319  // using the relative timeout API.
1320  std::vector<TimeoutTestParam> values;
1321  for (bool use_absolute_deadline : {false, true}) {
1322  // Tests with a negative timeout (deadline in the past), which should
1323  // immediately return current state of the condition.
1324 
1325  // The condition is already true:
1326  values.push_back(TimeoutTestParam{
1327  __FILE__, __LINE__, use_absolute_deadline,
1328  negative, // wait_timeout
1329  immediate, // satisfy_condition_delay
1330  true, // expected_result
1331  immediate, // expected_delay
1332  });
1333 
1334  // The condition becomes true, but the timeout has already expired:
1335  values.push_back(TimeoutTestParam{
1336  __FILE__, __LINE__, use_absolute_deadline,
1337  negative, // wait_timeout
1338  finite, // satisfy_condition_delay
1339  false, // expected_result
1340  immediate // expected_delay
1341  });
1342 
1343  // The condition never becomes true:
1344  values.push_back(TimeoutTestParam{
1345  __FILE__, __LINE__, use_absolute_deadline,
1346  negative, // wait_timeout
1347  never, // satisfy_condition_delay
1348  false, // expected_result
1349  immediate // expected_delay
1350  });
1351 
1352  // Tests with an infinite timeout (deadline in the infinite future), which
1353  // should only return when the condition becomes true.
1354 
1355  // The condition is already true:
1356  values.push_back(TimeoutTestParam{
1357  __FILE__, __LINE__, use_absolute_deadline,
1358  never, // wait_timeout
1359  immediate, // satisfy_condition_delay
1360  true, // expected_result
1361  immediate // expected_delay
1362  });
1363 
1364  // The condition becomes true before the (infinite) expiry:
1365  values.push_back(TimeoutTestParam{
1366  __FILE__, __LINE__, use_absolute_deadline,
1367  never, // wait_timeout
1368  finite, // satisfy_condition_delay
1369  true, // expected_result
1370  finite, // expected_delay
1371  });
1372 
1373  // Tests with a (small) finite timeout (deadline soon), with the condition
1374  // becoming true both before and after its expiry.
1375 
1376  // The condition is already true:
1377  values.push_back(TimeoutTestParam{
1378  __FILE__, __LINE__, use_absolute_deadline,
1379  never, // wait_timeout
1380  immediate, // satisfy_condition_delay
1381  true, // expected_result
1382  immediate // expected_delay
1383  });
1384 
1385  // The condition becomes true before the expiry:
1386  values.push_back(TimeoutTestParam{
1387  __FILE__, __LINE__, use_absolute_deadline,
1388  finite * 2, // wait_timeout
1389  finite, // satisfy_condition_delay
1390  true, // expected_result
1391  finite // expected_delay
1392  });
1393 
1394  // The condition becomes true, but the timeout has already expired:
1395  values.push_back(TimeoutTestParam{
1396  __FILE__, __LINE__, use_absolute_deadline,
1397  finite, // wait_timeout
1398  finite * 2, // satisfy_condition_delay
1399  false, // expected_result
1400  finite // expected_delay
1401  });
1402 
1403  // The condition never becomes true:
1404  values.push_back(TimeoutTestParam{
1405  __FILE__, __LINE__, use_absolute_deadline,
1406  finite, // wait_timeout
1407  never, // satisfy_condition_delay
1408  false, // expected_result
1409  finite // expected_delay
1410  });
1411  }
1412  return values;
1413 }
1414 
1415 // Instantiate `TimeoutTest` with `MakeTimeoutTestParamValues()`.
1416 INSTANTIATE_TEST_SUITE_P(All, TimeoutTest,
1417  testing::ValuesIn(MakeTimeoutTestParamValues()));
1418 
1419 TEST_P(TimeoutTest, Await) {
1420  const TimeoutTestParam params = GetParam();
1421  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1422 
1423  // Because this test asserts bounds on scheduling delays it is flaky. To
1424  // compensate it loops forever until it passes. Failures express as test
1425  // timeouts, in which case the test log can be used to diagnose the issue.
1426  for (int attempt = 1;; ++attempt) {
1427  ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1428 
1429  absl::Mutex mu;
1430  bool value = false; // condition value (under mu)
1431 
1432  std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1433  CreateDefaultPool();
1434  RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1435  absl::MutexLock l(&mu);
1436  value = true;
1437  });
1438 
1439  absl::MutexLock lock(&mu);
1442  bool result =
1443  params.use_absolute_deadline
1444  ? mu.AwaitWithDeadline(cond, start_time + params.wait_timeout)
1445  : mu.AwaitWithTimeout(cond, params.wait_timeout);
1446  if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1447  EXPECT_EQ(params.expected_result, result);
1448  break;
1449  }
1450  }
1451 }
1452 
1453 TEST_P(TimeoutTest, LockWhen) {
1454  const TimeoutTestParam params = GetParam();
1455  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1456 
1457  // Because this test asserts bounds on scheduling delays it is flaky. To
1458  // compensate it loops forever until it passes. Failures express as test
1459  // timeouts, in which case the test log can be used to diagnose the issue.
1460  for (int attempt = 1;; ++attempt) {
1461  ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1462 
1463  absl::Mutex mu;
1464  bool value = false; // condition value (under mu)
1465 
1466  std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1467  CreateDefaultPool();
1468  RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1469  absl::MutexLock l(&mu);
1470  value = true;
1471  });
1472 
1475  bool result =
1476  params.use_absolute_deadline
1477  ? mu.LockWhenWithDeadline(cond, start_time + params.wait_timeout)
1478  : mu.LockWhenWithTimeout(cond, params.wait_timeout);
1479  mu.Unlock();
1480 
1481  if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1482  EXPECT_EQ(params.expected_result, result);
1483  break;
1484  }
1485  }
1486 }
1487 
1488 TEST_P(TimeoutTest, ReaderLockWhen) {
1489  const TimeoutTestParam params = GetParam();
1490  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1491 
1492  // Because this test asserts bounds on scheduling delays it is flaky. To
1493  // compensate it loops forever until it passes. Failures express as test
1494  // timeouts, in which case the test log can be used to diagnose the issue.
1495  for (int attempt = 0;; ++attempt) {
1496  ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1497 
1498  absl::Mutex mu;
1499  bool value = false; // condition value (under mu)
1500 
1501  std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1502  CreateDefaultPool();
1503  RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1504  absl::MutexLock l(&mu);
1505  value = true;
1506  });
1507 
1509  bool result =
1510  params.use_absolute_deadline
1511  ? mu.ReaderLockWhenWithDeadline(absl::Condition(&value),
1512  start_time + params.wait_timeout)
1513  : mu.ReaderLockWhenWithTimeout(absl::Condition(&value),
1514  params.wait_timeout);
1515  mu.ReaderUnlock();
1516 
1517  if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1518  EXPECT_EQ(params.expected_result, result);
1519  break;
1520  }
1521  }
1522 }
1523 
1524 TEST_P(TimeoutTest, Wait) {
1525  const TimeoutTestParam params = GetParam();
1526  ABSL_RAW_LOG(INFO, "Params: %s", FormatString(params).c_str());
1527 
1528  // Because this test asserts bounds on scheduling delays it is flaky. To
1529  // compensate it loops forever until it passes. Failures express as test
1530  // timeouts, in which case the test log can be used to diagnose the issue.
1531  for (int attempt = 0;; ++attempt) {
1532  ABSL_RAW_LOG(INFO, "Attempt %d", attempt);
1533 
1534  absl::Mutex mu;
1535  bool value = false; // condition value (under mu)
1536  absl::CondVar cv; // signals a change of `value`
1537 
1538  std::unique_ptr<absl::synchronization_internal::ThreadPool> pool =
1539  CreateDefaultPool();
1540  RunAfterDelay(params.satisfy_condition_delay, pool.get(), [&] {
1541  absl::MutexLock l(&mu);
1542  value = true;
1543  cv.Signal();
1544  });
1545 
1546  absl::MutexLock lock(&mu);
1548  absl::Duration timeout = params.wait_timeout;
1549  absl::Time deadline = start_time + timeout;
1550  while (!value) {
1551  if (params.use_absolute_deadline ? cv.WaitWithDeadline(&mu, deadline)
1552  : cv.WaitWithTimeout(&mu, timeout)) {
1553  break; // deadline/timeout exceeded
1554  }
1555  timeout = deadline - absl::Now(); // recompute
1556  }
1557  bool result = value; // note: `mu` is still held
1558 
1559  if (DelayIsWithinBounds(params.expected_delay, absl::Now() - start_time)) {
1560  EXPECT_EQ(params.expected_result, result);
1561  break;
1562  }
1563  }
1564 }
1565 
1566 TEST(Mutex, Logging) {
1567  // Allow user to look at logging output
1568  absl::Mutex logged_mutex;
1569  logged_mutex.EnableDebugLog("fido_mutex");
1570  absl::CondVar logged_cv;
1571  logged_cv.EnableDebugLog("rover_cv");
1572  logged_mutex.Lock();
1573  logged_cv.WaitWithTimeout(&logged_mutex, absl::Milliseconds(20));
1574  logged_mutex.Unlock();
1575  logged_mutex.ReaderLock();
1576  logged_mutex.ReaderUnlock();
1577  logged_mutex.Lock();
1578  logged_mutex.Unlock();
1579  logged_cv.Signal();
1580  logged_cv.SignalAll();
1581 }
1582 
1583 // --------------------------------------------------------
1584 
1585 // Generate the vector of thread counts for tests parameterized on thread count.
1586 static std::vector<int> AllThreadCountValues() {
1587  if (kExtendedTest) {
1588  return {2, 4, 8, 10, 16, 20, 24, 30, 32};
1589  }
1590  return {2, 4, 10};
1591 }
1592 
1593 // A test fixture parameterized by thread count.
1594 class MutexVariableThreadCountTest : public ::testing::TestWithParam<int> {};
1595 
1596 // Instantiate the above with AllThreadCountOptions().
1597 INSTANTIATE_TEST_SUITE_P(ThreadCounts, MutexVariableThreadCountTest,
1598  ::testing::ValuesIn(AllThreadCountValues()),
1600 
1601 // Reduces iterations by some factor for slow platforms
1602 // (determined empirically).
1603 static int ScaleIterations(int x) {
1604  // ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE is set in the implementation
1605  // of Mutex that uses either std::mutex or pthread_mutex_t. Use
1606  // these as keys to determine the slow implementation.
1607 #if defined(ABSL_MUTEX_READER_LOCK_IS_EXCLUSIVE)
1608  return x / 10;
1609 #else
1610  return x;
1611 #endif
1612 }
1613 
1614 TEST_P(MutexVariableThreadCountTest, Mutex) {
1615  int threads = GetParam();
1616  int iterations = ScaleIterations(10000000) / threads;
1617  int operations = threads * iterations;
1618  EXPECT_EQ(RunTest(&TestMu, threads, iterations, operations), operations);
1619 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1620  iterations = std::min(iterations, 10);
1621  operations = threads * iterations;
1622  EXPECT_EQ(RunTestWithInvariantDebugging(&TestMu, threads, iterations,
1623  operations, CheckSumG0G1),
1624  operations);
1625 #endif
1626 }
1627 
1628 TEST_P(MutexVariableThreadCountTest, Try) {
1629  int threads = GetParam();
1630  int iterations = 1000000 / threads;
1631  int operations = iterations * threads;
1632  EXPECT_EQ(RunTest(&TestTry, threads, iterations, operations), operations);
1633 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1634  iterations = std::min(iterations, 10);
1635  operations = threads * iterations;
1636  EXPECT_EQ(RunTestWithInvariantDebugging(&TestTry, threads, iterations,
1637  operations, CheckSumG0G1),
1638  operations);
1639 #endif
1640 }
1641 
1642 TEST_P(MutexVariableThreadCountTest, R20ms) {
1643  int threads = GetParam();
1644  int iterations = 100;
1645  int operations = iterations * threads;
1646  EXPECT_EQ(RunTest(&TestR20ms, threads, iterations, operations), 0);
1647 }
1648 
1649 TEST_P(MutexVariableThreadCountTest, RW) {
1650  int threads = GetParam();
1651  int iterations = ScaleIterations(20000000) / threads;
1652  int operations = iterations * threads;
1653  EXPECT_EQ(RunTest(&TestRW, threads, iterations, operations), operations / 2);
1654 #if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
1655  iterations = std::min(iterations, 10);
1656  operations = threads * iterations;
1657  EXPECT_EQ(RunTestWithInvariantDebugging(&TestRW, threads, iterations,
1658  operations, CheckSumG0G1),
1659  operations / 2);
1660 #endif
1661 }
1662 
1663 TEST_P(MutexVariableThreadCountTest, Await) {
1664  int threads = GetParam();
1665  int iterations = ScaleIterations(500000);
1666  int operations = iterations;
1667  EXPECT_EQ(RunTest(&TestAwait, threads, iterations, operations), operations);
1668 }
1669 
1670 TEST_P(MutexVariableThreadCountTest, SignalAll) {
1671  int threads = GetParam();
1672  int iterations = 200000 / threads;
1673  int operations = iterations;
1674  EXPECT_EQ(RunTest(&TestSignalAll, threads, iterations, operations),
1675  operations);
1676 }
1677 
1678 TEST(Mutex, Signal) {
1679  int threads = 2; // TestSignal must use two threads
1680  int iterations = 200000;
1681  int operations = iterations;
1682  EXPECT_EQ(RunTest(&TestSignal, threads, iterations, operations), operations);
1683 }
1684 
1685 TEST(Mutex, Timed) {
1686  int threads = 10; // Use a fixed thread count of 10
1687  int iterations = 1000;
1688  int operations = iterations;
1689  EXPECT_EQ(RunTest(&TestCVTimeout, threads, iterations, operations),
1690  operations);
1691 }
1692 
1693 TEST(Mutex, CVTime) {
1694  int threads = 10; // Use a fixed thread count of 10
1695  int iterations = 1;
1696  EXPECT_EQ(RunTest(&TestCVTime, threads, iterations, 1),
1697  threads * iterations);
1698 }
1699 
1700 TEST(Mutex, MuTime) {
1701  int threads = 10; // Use a fixed thread count of 10
1702  int iterations = 1;
1703  EXPECT_EQ(RunTest(&TestMuTime, threads, iterations, 1), threads * iterations);
1704 }
1705 
1706 } // namespace
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
ABSL_RAW_CHECK
#define ABSL_RAW_CHECK(condition, message)
Definition: abseil-cpp/absl/base/internal/raw_logging.h:59
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
absl::internal_any_invocable::True
std::integral_constant< bool, sizeof(absl::void_t< T... > *) !=0 > True
Definition: internal/any_invocable.h:687
absl::str_format_internal::LengthMod::j
@ j
testing::WithParamInterface
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1848
bool
bool
Definition: setup_once.h:312
absl::ZeroDuration
constexpr Duration ZeroDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:308
invariant
void(* invariant)(void *arg)
Definition: abseil-cpp/absl/synchronization/mutex.cc:308
absl::synchronization_internal::ThreadPool
Definition: third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h:33
absl::Time
Definition: third_party/abseil-cpp/absl/time/time.h:642
file
const grpc_generator::File * file
Definition: python_private_generator.h:38
absl::Mutex
Definition: abseil-cpp/absl/synchronization/mutex.h:131
test
Definition: spinlock_test.cc:36
absl::Mutex::Unlock
void Unlock() ABSL_UNLOCK_FUNCTION()
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
file
Definition: bloaty/third_party/zlib/examples/gzappend.c:170
ABSL_GUARDED_BY
#define ABSL_GUARDED_BY(x)
Definition: abseil-cpp/absl/base/thread_annotations.h:62
absl::Mutex::ReaderLock
void ReaderLock() ABSL_SHARED_LOCK_FUNCTION()
absl::FormatConversionChar::s
@ s
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
testing::Range
internal::ParamGenerator< T > Range(T start, T end, IncrementT step)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:229
absl::SleepFor
void SleepFor(absl::Duration duration)
Definition: abseil-cpp/absl/time/clock.h:70
xds_manager.p
p
Definition: xds_manager.py:60
start_time
static int64_t start_time
Definition: benchmark-getaddrinfo.c:37
absl::Mutex::ForgetDeadlockInfo
void ForgetDeadlockInfo()
Definition: abseil-cpp/absl/synchronization/mutex.cc:1421
threads
static uv_thread_t * threads
Definition: threadpool.c:38
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
absl::CondVar::EnableDebugLog
void EnableDebugLog(const char *name)
Definition: abseil-cpp/absl/synchronization/mutex.cc:2456
benchmark::FormatString
std::string FormatString(const char *msg, va_list args)
Definition: benchmark/src/colorprint.cc:85
ABSL_MUST_USE_RESULT
#define ABSL_MUST_USE_RESULT
Definition: abseil-cpp/absl/base/attributes.h:441
absl::Milliseconds
constexpr Duration Milliseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:415
absl::MutexLock
Definition: abseil-cpp/absl/synchronization/mutex.h:525
absl::OnDeadlockCycle::kIgnore
@ kIgnore
absl::Mutex::EnableDebugLog
void EnableDebugLog(const char *name)
Definition: abseil-cpp/absl/synchronization/mutex.cc:741
start
static uint64_t start
Definition: benchmark-pound.c:74
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
autogen_x86imm.f
f
Definition: autogen_x86imm.py:9
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
hpack_encoder_fixtures::Args
Args({0, 16384})
grpc_core::TestContext
promise_detail::Context< T > TestContext
Definition: test_context.h:23
absl::WriterMutexLock
Definition: abseil-cpp/absl/synchronization/mutex.h:587
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
TEST_P
#define TEST_P(test_suite_name, test_name)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:414
python_utils.jobset.INFO
INFO
Definition: jobset.py:111
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::Mutex::Lock
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION()
cond
static uv_cond_t cond
Definition: threadpool.c:33
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
absl::Duration
Definition: third_party/abseil-cpp/absl/time/time.h:159
negative
static uint8_t negative(signed char b)
Definition: curve25519.c:786
x
int x
Definition: bloaty/third_party/googletest/googlemock/test/gmock-matchers_test.cc:3610
google::protobuf::WARNING
static const LogLevel WARNING
Definition: bloaty/third_party/protobuf/src/google/protobuf/testing/googletest.h:71
callback
static void callback(void *arg, int status, int timeouts, struct hostent *host)
Definition: acountry.c:224
gen
OPENSSL_EXPORT GENERAL_NAME * gen
Definition: x509v3.h:495
running
static const char running[]
Definition: benchmark-async-pummel.c:34
absl::Condition
Definition: abseil-cpp/absl/synchronization/mutex.h:663
min
#define min(a, b)
Definition: qsort.h:83
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
g
struct @717 g
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
absl::FormatDuration
std::string FormatDuration(Duration d)
Definition: abseil-cpp/absl/time/duration.cc:768
after
IntAfterTypedTestSuiteP after
Definition: googletest/googletest/test/gtest-typed-test_test.cc:375
absl::CondVar::Wait
void Wait(Mutex *mu)
Definition: abseil-cpp/absl/synchronization/mutex.cc:2628
grpc_core::never
Poll< int > never()
Definition: race_test.cc:24
value
const char * value
Definition: hpack_parser_table.cc:165
absl::Seconds
constexpr Duration Seconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:419
absl::Mutex::ReaderUnlock
void ReaderUnlock() ABSL_UNLOCK_FUNCTION()
absl::hash_internal::c1
static const uint32_t c1
Definition: abseil-cpp/absl/hash/internal/city.cc:58
absl::Now
ABSL_NAMESPACE_BEGIN Time Now()
Definition: abseil-cpp/absl/time/clock.cc:39
absl::ReaderMutexLock
Definition: abseil-cpp/absl/synchronization/mutex.h:560
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
cv
unsigned cv
Definition: cxa_demangle.cpp:4908
absl::CondVar
Definition: abseil-cpp/absl/synchronization/mutex.h:798
absl::str_format_internal::LengthMod::t
@ t
testing::PrintToStringParamName
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-param-util.h:66
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
google::protobuf.internal::Mutex
WrappedMutex Mutex
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/mutex.h:113
values
std::array< int64_t, Size > values
Definition: abseil-cpp/absl/container/btree_benchmark.cc:608
testing::WithParamInterface::GetParam
static const ParamType & GetParam()
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1855
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
absl::CondVar::SignalAll
void SignalAll()
Definition: abseil-cpp/absl/synchronization/mutex.cc:2689
absl::ABSL_NAMESPACE_BEGIN::dummy
int dummy
Definition: function_type_benchmark.cc:28
release
return ret release()
Definition: doc/python/sphinx/conf.py:37
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
pool
InternalDescriptorPool * pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:807
absl::EnableMutexInvariantDebugging
void EnableMutexInvariantDebugging(bool enabled)
Definition: abseil-cpp/absl/synchronization/mutex.cc:747
RunTest
static void RunTest(RandomDistInterface &&r, int threads, const std::string &title)
Definition: qps_interarrival_test.cc:31
testing::ValuesIn
internal::ParamGenerator< typename std::iterator_traits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:297
absl::CondVar::Signal
void Signal()
Definition: abseil-cpp/absl/synchronization/mutex.cc:2649
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
grpc::operator<<
std::ostream & operator<<(std::ostream &out, const string_ref &string)
Definition: grpcpp/impl/codegen/string_ref.h:145
absl::InfiniteDuration
constexpr Duration InfiniteDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:1573
absl::OnDeadlockCycle::kAbort
@ kAbort
t1
Table t1
Definition: abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc:185
getenv
#define getenv(ptr)
Definition: ares_private.h:106
absl::Mutex::TryLock
bool TryLock() ABSL_EXCLUSIVE_TRYLOCK_FUNCTION(true)
ABSL_RAW_LOG
#define ABSL_RAW_LOG(severity,...)
Definition: abseil-cpp/absl/base/internal/raw_logging.h:44
absl::SetMutexDeadlockDetectionMode
void SetMutexDeadlockDetectionMode(OnDeadlockCycle mode)
Definition: abseil-cpp/absl/synchronization/mutex.cc:762
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179
absl::CondVar::WaitWithTimeout
bool WaitWithTimeout(Mutex *mu, absl::Duration timeout)
Definition: abseil-cpp/absl/synchronization/mutex.cc:2620
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
Test
Definition: hpack_parser_test.cc:43
timeout
uv_timer_t timeout
Definition: libuv/docs/code/uvwget/main.c:9
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
state
static struct rpc_state state
Definition: bad_server_response_test.cc:87
absl::OnDeadlockCycle::kReport
@ kReport
absl::synchronization_internal::ThreadPool::Schedule
void Schedule(std::function< void()> func)
Definition: third_party/abseil-cpp/absl/synchronization/internal/thread_pool.h:57
ABSL_NO_THREAD_SAFETY_ANALYSIS
#define ABSL_NO_THREAD_SAFETY_ANALYSIS
Definition: abseil-cpp/absl/base/thread_annotations.h:280
INSTANTIATE_TEST_SUITE_P
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name,...)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:460


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:31