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