xref: /aosp_15_r20/external/cronet/base/task/post_job_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/task/post_job.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <atomic>
8*6777b538SAndroid Build Coastguard Worker #include <iterator>
9*6777b538SAndroid Build Coastguard Worker #include <numeric>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/barrier_closure.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/test/test_waitable_event.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
18*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace base {
22*6777b538SAndroid Build Coastguard Worker 
TEST(PostJobTest,PostJobSimple)23*6777b538SAndroid Build Coastguard Worker TEST(PostJobTest, PostJobSimple) {
24*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment;
25*6777b538SAndroid Build Coastguard Worker   std::atomic_size_t num_tasks_to_run(4);
26*6777b538SAndroid Build Coastguard Worker   auto handle = PostJob(
27*6777b538SAndroid Build Coastguard Worker       FROM_HERE, {},
28*6777b538SAndroid Build Coastguard Worker       BindLambdaForTesting([&](JobDelegate* delegate) { --num_tasks_to_run; }),
29*6777b538SAndroid Build Coastguard Worker       BindLambdaForTesting(
30*6777b538SAndroid Build Coastguard Worker           [&](size_t /*worker_count*/) -> size_t { return num_tasks_to_run; }));
31*6777b538SAndroid Build Coastguard Worker   handle.Join();
32*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(num_tasks_to_run, 0U);
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker 
TEST(PostJobTest,CreateJobSimple)35*6777b538SAndroid Build Coastguard Worker TEST(PostJobTest, CreateJobSimple) {
36*6777b538SAndroid Build Coastguard Worker   test::TaskEnvironment task_environment;
37*6777b538SAndroid Build Coastguard Worker   std::atomic_size_t num_tasks_to_run(4);
38*6777b538SAndroid Build Coastguard Worker   TestWaitableEvent threads_continue;
39*6777b538SAndroid Build Coastguard Worker   RepeatingClosure barrier = BarrierClosure(
40*6777b538SAndroid Build Coastguard Worker       num_tasks_to_run, BindLambdaForTesting([&threads_continue]() {
41*6777b538SAndroid Build Coastguard Worker         threads_continue.Signal();
42*6777b538SAndroid Build Coastguard Worker       }));
43*6777b538SAndroid Build Coastguard Worker   bool job_started = false;
44*6777b538SAndroid Build Coastguard Worker   auto handle =
45*6777b538SAndroid Build Coastguard Worker       CreateJob(FROM_HERE, {}, BindLambdaForTesting([&](JobDelegate* delegate) {
46*6777b538SAndroid Build Coastguard Worker                   EXPECT_TRUE(job_started);
47*6777b538SAndroid Build Coastguard Worker                   barrier.Run();
48*6777b538SAndroid Build Coastguard Worker                   threads_continue.Wait();
49*6777b538SAndroid Build Coastguard Worker                   --num_tasks_to_run;
50*6777b538SAndroid Build Coastguard Worker                 }),
51*6777b538SAndroid Build Coastguard Worker                 BindLambdaForTesting([&](size_t /*worker_count*/) -> size_t {
52*6777b538SAndroid Build Coastguard Worker                   EXPECT_TRUE(job_started);
53*6777b538SAndroid Build Coastguard Worker                   return num_tasks_to_run;
54*6777b538SAndroid Build Coastguard Worker                 }));
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
57*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(num_tasks_to_run, 4U);
58*6777b538SAndroid Build Coastguard Worker   job_started = true;
59*6777b538SAndroid Build Coastguard Worker   handle.Join();
60*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(num_tasks_to_run, 0U);
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker // Verify that concurrent accesses with task_id as the only form of
64*6777b538SAndroid Build Coastguard Worker // synchronisation doesn't trigger a race.
TEST(PostJobTest,TaskIds)65*6777b538SAndroid Build Coastguard Worker TEST(PostJobTest, TaskIds) {
66*6777b538SAndroid Build Coastguard Worker   static constexpr size_t kNumConcurrentThreads = 2;
67*6777b538SAndroid Build Coastguard Worker   static constexpr size_t kNumTasksToRun = 1000;
68*6777b538SAndroid Build Coastguard Worker   base::test::TaskEnvironment task_environment;
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker   size_t concurrent_array[kNumConcurrentThreads] = {0};
71*6777b538SAndroid Build Coastguard Worker   std::atomic_size_t remaining_tasks{kNumTasksToRun};
72*6777b538SAndroid Build Coastguard Worker   base::JobHandle handle = base::PostJob(
73*6777b538SAndroid Build Coastguard Worker       FROM_HERE, {}, BindLambdaForTesting([&](base::JobDelegate* job) {
74*6777b538SAndroid Build Coastguard Worker         uint8_t id = job->GetTaskId();
75*6777b538SAndroid Build Coastguard Worker         size_t& slot = concurrent_array[id];
76*6777b538SAndroid Build Coastguard Worker         slot++;
77*6777b538SAndroid Build Coastguard Worker         --remaining_tasks;
78*6777b538SAndroid Build Coastguard Worker       }),
79*6777b538SAndroid Build Coastguard Worker       BindLambdaForTesting([&remaining_tasks](size_t) {
80*6777b538SAndroid Build Coastguard Worker         return std::min(remaining_tasks.load(), kNumConcurrentThreads);
81*6777b538SAndroid Build Coastguard Worker       }));
82*6777b538SAndroid Build Coastguard Worker   handle.Join();
83*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kNumTasksToRun, std::accumulate(std::begin(concurrent_array),
84*6777b538SAndroid Build Coastguard Worker                                             std::end(concurrent_array), 0U));
85*6777b538SAndroid Build Coastguard Worker }
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker }  // namespace base
88