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/barrier.h" 16 17 #include <thread> // NOLINT(build/c++11) 18 #include <vector> 19 20 #include "gtest/gtest.h" 21 #include "absl/synchronization/mutex.h" 22 #include "absl/time/clock.h" 23 24 TEST(Barrier,SanityTest)25TEST(Barrier, SanityTest) { 26 constexpr int kNumThreads = 10; 27 absl::Barrier* barrier = new absl::Barrier(kNumThreads); 28 29 absl::Mutex mutex; 30 int counter = 0; // Guarded by mutex. 31 32 auto thread_func = [&] { 33 if (barrier->Block()) { 34 // This thread is the last thread to reach the barrier so it is 35 // responsible for deleting it. 36 delete barrier; 37 } 38 39 // Increment the counter. 40 absl::MutexLock lock(&mutex); 41 ++counter; 42 }; 43 44 // Start (kNumThreads - 1) threads running thread_func. 45 std::vector<std::thread> threads; 46 for (int i = 0; i < kNumThreads - 1; ++i) { 47 threads.push_back(std::thread(thread_func)); 48 } 49 50 // Give (kNumThreads - 1) threads a chance to reach the barrier. 51 // This test assumes at least one thread will have run after the 52 // sleep has elapsed. Sleeping in a test is usually bad form, but we 53 // need to make sure that we are testing the barrier instead of some 54 // other synchronization method. 55 absl::SleepFor(absl::Seconds(1)); 56 57 // The counter should still be zero since no thread should have 58 // been able to pass the barrier yet. 59 { 60 absl::MutexLock lock(&mutex); 61 EXPECT_EQ(counter, 0); 62 } 63 64 // Start 1 more thread. This should make all threads pass the barrier. 65 threads.push_back(std::thread(thread_func)); 66 67 // All threads should now be able to proceed and finish. 68 for (auto& thread : threads) { 69 thread.join(); 70 } 71 72 // All threads should now have incremented the counter. 73 absl::MutexLock lock(&mutex); 74 EXPECT_EQ(counter, kNumThreads); 75 } 76