xref: /aosp_15_r20/external/abseil-cpp/absl/synchronization/blocking_counter_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2017 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/synchronization/blocking_counter.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <thread>  // NOLINT(build/c++11)
18*9356374aSAndroid Build Coastguard Worker #include <vector>
19*9356374aSAndroid Build Coastguard Worker 
20*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
21*9356374aSAndroid Build Coastguard Worker #include "absl/time/clock.h"
22*9356374aSAndroid Build Coastguard Worker #include "absl/time/time.h"
23*9356374aSAndroid Build Coastguard Worker 
24*9356374aSAndroid Build Coastguard Worker namespace absl {
25*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_BEGIN
26*9356374aSAndroid Build Coastguard Worker namespace {
27*9356374aSAndroid Build Coastguard Worker 
PauseAndDecreaseCounter(BlockingCounter * counter,int * done)28*9356374aSAndroid Build Coastguard Worker void PauseAndDecreaseCounter(BlockingCounter* counter, int* done) {
29*9356374aSAndroid Build Coastguard Worker   absl::SleepFor(absl::Seconds(1));
30*9356374aSAndroid Build Coastguard Worker   *done = 1;
31*9356374aSAndroid Build Coastguard Worker   counter->DecrementCount();
32*9356374aSAndroid Build Coastguard Worker }
33*9356374aSAndroid Build Coastguard Worker 
TEST(BlockingCounterTest,BasicFunctionality)34*9356374aSAndroid Build Coastguard Worker TEST(BlockingCounterTest, BasicFunctionality) {
35*9356374aSAndroid Build Coastguard Worker   // This test verifies that BlockingCounter functions correctly. Starts a
36*9356374aSAndroid Build Coastguard Worker   // number of threads that just sleep for a second and decrement a counter.
37*9356374aSAndroid Build Coastguard Worker 
38*9356374aSAndroid Build Coastguard Worker   // Initialize the counter.
39*9356374aSAndroid Build Coastguard Worker   const int num_workers = 10;
40*9356374aSAndroid Build Coastguard Worker   BlockingCounter counter(num_workers);
41*9356374aSAndroid Build Coastguard Worker 
42*9356374aSAndroid Build Coastguard Worker   std::vector<std::thread> workers;
43*9356374aSAndroid Build Coastguard Worker   std::vector<int> done(num_workers, 0);
44*9356374aSAndroid Build Coastguard Worker 
45*9356374aSAndroid Build Coastguard Worker   // Start a number of parallel tasks that will just wait for a seconds and
46*9356374aSAndroid Build Coastguard Worker   // then decrement the count.
47*9356374aSAndroid Build Coastguard Worker   workers.reserve(num_workers);
48*9356374aSAndroid Build Coastguard Worker   for (int k = 0; k < num_workers; k++) {
49*9356374aSAndroid Build Coastguard Worker     workers.emplace_back(
50*9356374aSAndroid Build Coastguard Worker         [&counter, &done, k] { PauseAndDecreaseCounter(&counter, &done[k]); });
51*9356374aSAndroid Build Coastguard Worker   }
52*9356374aSAndroid Build Coastguard Worker 
53*9356374aSAndroid Build Coastguard Worker   // Wait for the threads to have all finished.
54*9356374aSAndroid Build Coastguard Worker   counter.Wait();
55*9356374aSAndroid Build Coastguard Worker 
56*9356374aSAndroid Build Coastguard Worker   // Check that all the workers have completed.
57*9356374aSAndroid Build Coastguard Worker   for (int k = 0; k < num_workers; k++) {
58*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(1, done[k]);
59*9356374aSAndroid Build Coastguard Worker   }
60*9356374aSAndroid Build Coastguard Worker 
61*9356374aSAndroid Build Coastguard Worker   for (std::thread& w : workers) {
62*9356374aSAndroid Build Coastguard Worker     w.join();
63*9356374aSAndroid Build Coastguard Worker   }
64*9356374aSAndroid Build Coastguard Worker }
65*9356374aSAndroid Build Coastguard Worker 
TEST(BlockingCounterTest,WaitZeroInitialCount)66*9356374aSAndroid Build Coastguard Worker TEST(BlockingCounterTest, WaitZeroInitialCount) {
67*9356374aSAndroid Build Coastguard Worker   BlockingCounter counter(0);
68*9356374aSAndroid Build Coastguard Worker   counter.Wait();
69*9356374aSAndroid Build Coastguard Worker }
70*9356374aSAndroid Build Coastguard Worker 
71*9356374aSAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST
TEST(BlockingCounterTest,WaitNegativeInitialCount)72*9356374aSAndroid Build Coastguard Worker TEST(BlockingCounterTest, WaitNegativeInitialCount) {
73*9356374aSAndroid Build Coastguard Worker   EXPECT_DEATH(BlockingCounter counter(-1),
74*9356374aSAndroid Build Coastguard Worker                "BlockingCounter initial_count negative");
75*9356374aSAndroid Build Coastguard Worker }
76*9356374aSAndroid Build Coastguard Worker #endif
77*9356374aSAndroid Build Coastguard Worker 
78*9356374aSAndroid Build Coastguard Worker }  // namespace
79*9356374aSAndroid Build Coastguard Worker ABSL_NAMESPACE_END
80*9356374aSAndroid Build Coastguard Worker }  // namespace absl
81