xref: /aosp_15_r20/external/libgav1/src/utils/blocking_counter_test.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2021 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop //      http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop 
15*09537850SAkhilesh Sanikop #include "src/utils/blocking_counter.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <array>
18*09537850SAkhilesh Sanikop #include <memory>
19*09537850SAkhilesh Sanikop 
20*09537850SAkhilesh Sanikop #include "absl/time/clock.h"
21*09537850SAkhilesh Sanikop #include "absl/time/time.h"
22*09537850SAkhilesh Sanikop #include "gtest/gtest.h"
23*09537850SAkhilesh Sanikop #include "src/utils/threadpool.h"
24*09537850SAkhilesh Sanikop 
25*09537850SAkhilesh Sanikop namespace libgav1 {
26*09537850SAkhilesh Sanikop namespace {
27*09537850SAkhilesh Sanikop 
28*09537850SAkhilesh Sanikop constexpr int kNumWorkers = 10;
29*09537850SAkhilesh Sanikop constexpr int kNumJobs = 20;
30*09537850SAkhilesh Sanikop 
TEST(BlockingCounterTest,BasicFunctionality)31*09537850SAkhilesh Sanikop TEST(BlockingCounterTest, BasicFunctionality) {
32*09537850SAkhilesh Sanikop   std::unique_ptr<ThreadPool> pool = ThreadPool::Create(kNumWorkers);
33*09537850SAkhilesh Sanikop   BlockingCounter counter(kNumJobs);
34*09537850SAkhilesh Sanikop   std::array<bool, kNumJobs> done = {};
35*09537850SAkhilesh Sanikop 
36*09537850SAkhilesh Sanikop   // Schedule the jobs.
37*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumJobs; ++i) {
38*09537850SAkhilesh Sanikop     pool->Schedule([&counter, &done, i]() {
39*09537850SAkhilesh Sanikop       absl::SleepFor(absl::Seconds(1));
40*09537850SAkhilesh Sanikop       done[i] = true;
41*09537850SAkhilesh Sanikop       counter.Decrement();
42*09537850SAkhilesh Sanikop     });
43*09537850SAkhilesh Sanikop   }
44*09537850SAkhilesh Sanikop 
45*09537850SAkhilesh Sanikop   // Wait for the jobs to complete. This should always return true.
46*09537850SAkhilesh Sanikop   ASSERT_TRUE(counter.Wait());
47*09537850SAkhilesh Sanikop 
48*09537850SAkhilesh Sanikop   // Make sure the jobs were actually complete.
49*09537850SAkhilesh Sanikop   for (const auto& job_done : done) {
50*09537850SAkhilesh Sanikop     EXPECT_TRUE(job_done);
51*09537850SAkhilesh Sanikop   }
52*09537850SAkhilesh Sanikop }
53*09537850SAkhilesh Sanikop 
TEST(BlockingCounterTest,IncrementBy)54*09537850SAkhilesh Sanikop TEST(BlockingCounterTest, IncrementBy) {
55*09537850SAkhilesh Sanikop   std::unique_ptr<ThreadPool> pool = ThreadPool::Create(kNumWorkers);
56*09537850SAkhilesh Sanikop   BlockingCounter counter(0);
57*09537850SAkhilesh Sanikop   std::array<bool, kNumJobs> done = {};
58*09537850SAkhilesh Sanikop 
59*09537850SAkhilesh Sanikop   // Schedule the jobs.
60*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumJobs; ++i) {
61*09537850SAkhilesh Sanikop     counter.IncrementBy(1);
62*09537850SAkhilesh Sanikop     pool->Schedule([&counter, &done, i]() {
63*09537850SAkhilesh Sanikop       absl::SleepFor(absl::Seconds(1));
64*09537850SAkhilesh Sanikop       done[i] = true;
65*09537850SAkhilesh Sanikop       counter.Decrement();
66*09537850SAkhilesh Sanikop     });
67*09537850SAkhilesh Sanikop   }
68*09537850SAkhilesh Sanikop 
69*09537850SAkhilesh Sanikop   // Wait for the jobs to complete. This should always return true.
70*09537850SAkhilesh Sanikop   ASSERT_TRUE(counter.Wait());
71*09537850SAkhilesh Sanikop 
72*09537850SAkhilesh Sanikop   // Make sure the jobs were actually complete.
73*09537850SAkhilesh Sanikop   for (const auto& job_done : done) {
74*09537850SAkhilesh Sanikop     EXPECT_TRUE(job_done);
75*09537850SAkhilesh Sanikop   }
76*09537850SAkhilesh Sanikop }
77*09537850SAkhilesh Sanikop 
TEST(BlockingCounterWithStatusTest,BasicFunctionality)78*09537850SAkhilesh Sanikop TEST(BlockingCounterWithStatusTest, BasicFunctionality) {
79*09537850SAkhilesh Sanikop   std::unique_ptr<ThreadPool> pool = ThreadPool::Create(kNumWorkers);
80*09537850SAkhilesh Sanikop   BlockingCounterWithStatus counter(kNumJobs);
81*09537850SAkhilesh Sanikop   std::array<bool, kNumJobs> done = {};
82*09537850SAkhilesh Sanikop 
83*09537850SAkhilesh Sanikop   // Schedule the jobs.
84*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumJobs; ++i) {
85*09537850SAkhilesh Sanikop     pool->Schedule([&counter, &done, i]() {
86*09537850SAkhilesh Sanikop       absl::SleepFor(absl::Seconds(1));
87*09537850SAkhilesh Sanikop       done[i] = true;
88*09537850SAkhilesh Sanikop       counter.Decrement(true);
89*09537850SAkhilesh Sanikop     });
90*09537850SAkhilesh Sanikop   }
91*09537850SAkhilesh Sanikop 
92*09537850SAkhilesh Sanikop   // Wait for the jobs to complete. This should return true since all the jobs
93*09537850SAkhilesh Sanikop   // reported |job_succeeded| as true.
94*09537850SAkhilesh Sanikop   ASSERT_TRUE(counter.Wait());
95*09537850SAkhilesh Sanikop 
96*09537850SAkhilesh Sanikop   // Make sure the jobs were actually complete.
97*09537850SAkhilesh Sanikop   for (const auto& job_done : done) {
98*09537850SAkhilesh Sanikop     EXPECT_TRUE(job_done);
99*09537850SAkhilesh Sanikop   }
100*09537850SAkhilesh Sanikop }
101*09537850SAkhilesh Sanikop 
TEST(BlockingCounterWithStatusTest,BasicFunctionalityWithStatus)102*09537850SAkhilesh Sanikop TEST(BlockingCounterWithStatusTest, BasicFunctionalityWithStatus) {
103*09537850SAkhilesh Sanikop   std::unique_ptr<ThreadPool> pool = ThreadPool::Create(kNumWorkers);
104*09537850SAkhilesh Sanikop   BlockingCounterWithStatus counter(kNumJobs);
105*09537850SAkhilesh Sanikop   std::array<bool, kNumJobs> done = {};
106*09537850SAkhilesh Sanikop 
107*09537850SAkhilesh Sanikop   // Schedule the jobs.
108*09537850SAkhilesh Sanikop   for (int i = 0; i < kNumJobs; ++i) {
109*09537850SAkhilesh Sanikop     pool->Schedule([&counter, &done, i]() {
110*09537850SAkhilesh Sanikop       absl::SleepFor(absl::Seconds(1));
111*09537850SAkhilesh Sanikop       done[i] = true;
112*09537850SAkhilesh Sanikop       counter.Decrement(i != 10);
113*09537850SAkhilesh Sanikop     });
114*09537850SAkhilesh Sanikop   }
115*09537850SAkhilesh Sanikop 
116*09537850SAkhilesh Sanikop   // Wait for the jobs to complete. This should return false since one of the
117*09537850SAkhilesh Sanikop   // jobs reported |job_succeeded| as false.
118*09537850SAkhilesh Sanikop   ASSERT_FALSE(counter.Wait());
119*09537850SAkhilesh Sanikop 
120*09537850SAkhilesh Sanikop   // Make sure the jobs were actually complete.
121*09537850SAkhilesh Sanikop   for (const auto& job_done : done) {
122*09537850SAkhilesh Sanikop     EXPECT_TRUE(job_done);
123*09537850SAkhilesh Sanikop   }
124*09537850SAkhilesh Sanikop }
125*09537850SAkhilesh Sanikop 
126*09537850SAkhilesh Sanikop }  // namespace
127*09537850SAkhilesh Sanikop }  // namespace libgav1
128