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