about summary refs log tree commit diff
path: root/absl/synchronization/barrier_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/synchronization/barrier_test.cc')
-rw-r--r--absl/synchronization/barrier_test.cc75
1 files changed, 75 insertions, 0 deletions
diff --git a/absl/synchronization/barrier_test.cc b/absl/synchronization/barrier_test.cc
new file mode 100644
index 000000000000..d6cababdf733
--- /dev/null
+++ b/absl/synchronization/barrier_test.cc
@@ -0,0 +1,75 @@
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/synchronization/barrier.h"
+
+#include <thread>  // NOLINT(build/c++11)
+#include <vector>
+
+#include "gtest/gtest.h"
+#include "absl/synchronization/mutex.h"
+#include "absl/time/clock.h"
+
+
+TEST(Barrier, SanityTest) {
+  constexpr int kNumThreads = 10;
+  absl::Barrier* barrier = new absl::Barrier(kNumThreads);
+
+  absl::Mutex mutex;
+  int counter = 0;  // Guarded by mutex.
+
+  auto thread_func = [&] {
+    if (barrier->Block()) {
+      // This thread is the last thread to reach the barrier so it is
+      // responsible for deleting it.
+      delete barrier;
+    }
+
+    // Increment the counter.
+    absl::MutexLock lock(&mutex);
+    ++counter;
+  };
+
+  // Start (kNumThreads - 1) threads running thread_func.
+  std::vector<std::thread> threads;
+  for (int i = 0; i < kNumThreads - 1; ++i) {
+    threads.push_back(std::thread(thread_func));
+  }
+
+  // Give (kNumThreads - 1) threads a chance to reach the barrier.
+  // This test assumes at least one thread will have run after the
+  // sleep has elapsed. Sleeping in a test is usually bad form, but we
+  // need to make sure that we are testing the barrier instead of some
+  // other synchronization method.
+  absl::SleepFor(absl::Seconds(1));
+
+  // The counter should still be zero since no thread should have
+  // been able to pass the barrier yet.
+  {
+    absl::MutexLock lock(&mutex);
+    EXPECT_EQ(counter, 0);
+  }
+
+  // Start 1 more thread. This should make all threads pass the barrier.
+  threads.push_back(std::thread(thread_func));
+
+  // All threads should now be able to proceed and finish.
+  for (auto& thread : threads) {
+    thread.join();
+  }
+
+  // All threads should now have incremented the counter.
+  absl::MutexLock lock(&mutex);
+  EXPECT_EQ(counter, kNumThreads);
+}