barrier_test.cc 2.3 KB

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