about summary refs log tree commit diff
path: root/absl/synchronization/mutex_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/synchronization/mutex_test.cc')
-rw-r--r--absl/synchronization/mutex_test.cc103
1 files changed, 54 insertions, 49 deletions
diff --git a/absl/synchronization/mutex_test.cc b/absl/synchronization/mutex_test.cc
index cfe81096dc98..5a5874def72d 100644
--- a/absl/synchronization/mutex_test.cc
+++ b/absl/synchronization/mutex_test.cc
@@ -89,8 +89,6 @@ static void CheckSumG0G1(void *v) {
 }
 
 static void TestMu(TestContext *cxt, int c) {
-  SetInvariantChecked(false);
-  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
   for (int i = 0; i != cxt->iterations; i++) {
     absl::MutexLock l(&cxt->mu);
     int a = cxt->g0 + 1;
@@ -100,8 +98,6 @@ static void TestMu(TestContext *cxt, int c) {
 }
 
 static void TestTry(TestContext *cxt, int c) {
-  SetInvariantChecked(false);
-  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
   for (int i = 0; i != cxt->iterations; i++) {
     do {
       std::this_thread::yield();
@@ -122,8 +118,6 @@ static void TestR20ms(TestContext *cxt, int c) {
 }
 
 static void TestRW(TestContext *cxt, int c) {
-  SetInvariantChecked(false);
-  cxt->mu.EnableInvariantDebugging(CheckSumG0G1, cxt);
   if ((c & 1) == 0) {
     for (int i = 0; i != cxt->iterations; i++) {
       absl::WriterMutexLock l(&cxt->mu);
@@ -356,67 +350,57 @@ static void EndTest(int *c0, int *c1, absl::Mutex *mu, absl::CondVar *cv,
   cv->Signal();
 }
 
-// Basis for the parameterized tests configured below.
-static int RunTest(void (*test)(TestContext *cxt, int), int threads,
-                   int iterations, int operations) {
-  TestContext cxt;
+// 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;
-  int c1;
-
-  // run with large thread count for full test and to get timing
-
-#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
-  absl::EnableMutexInvariantDebugging(false);
-#endif
-  c0 = 0;
-  c1 = 0;
-  cxt.g0 = 0;
-  cxt.g1 = 0;
-  cxt.iterations = iterations;
-  cxt.threads = threads;
+  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))));
+                              std::bind(test, cxt, std::placeholders::_1))));
   }
   mu2.Lock();
   while (c1 != threads) {
     cv2.Wait(&mu2);
   }
   mu2.Unlock();
-  int saved_g0 = cxt.g0;
+  return cxt->g0;
+}
 
-  // run again with small number of iterations to test invariant checking
+// 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);
-#endif
-  SetInvariantChecked(true);
-  c0 = 0;
-  c1 = 0;
-  cxt.g0 = 0;
-  cxt.g1 = 0;
-  cxt.iterations = (iterations > 10 ? 10 : iterations);
-  cxt.threads = 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();
-#if !defined(ABSL_MUTEX_ENABLE_INVARIANT_DEBUGGING_NOT_IMPLEMENTED)
+  SetInvariantChecked(false);
+  TestContext cxt;
+  cxt.mu.EnableInvariantDebugging(invariant, &cxt);
+  int ret = RunTestCommon(&cxt, test, threads, iterations, operations);
   ABSL_RAW_CHECK(GetInvariantChecked(), "Invariant not checked");
-#endif
-
-  return saved_g0;
+  absl::EnableMutexInvariantDebugging(false);  // Restore.
+  return ret;
 }
+#endif
 
 // --------------------------------------------------------
 // Test for fix of bug in TryRemove()
@@ -1463,6 +1447,13 @@ TEST_P(MutexVariableThreadCountTest, Mutex) {
   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) {
@@ -1470,6 +1461,13 @@ TEST_P(MutexVariableThreadCountTest, Try) {
   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) {
@@ -1484,6 +1482,13 @@ TEST_P(MutexVariableThreadCountTest, RW) {
   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) {