Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: base/task_scheduler/scheduler_worker_thread_unittest.cc

Issue 1704113002: TaskScheduler [6] SchedulerWorkerThread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s_4_shutdown
Patch Set: add main entry callback Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/task_scheduler/scheduler_worker_thread.h"
6
7 #include <stddef.h>
8
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/macros.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/synchronization/condition_variable.h"
16 #include "base/task_scheduler/scheduler_lock.h"
17 #include "base/task_scheduler/sequence.h"
18 #include "base/task_scheduler/task.h"
19 #include "base/task_scheduler/task_tracker.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace base {
23 namespace internal {
24 namespace {
25
26 const size_t kNumSequencesPerTest = 150;
27
28 class TaskSchedulerWorkerThreadTest : public testing::Test {
29 protected:
30 TaskSchedulerWorkerThreadTest()
31 : num_main_entry_callback_cv_(lock_.CreateConditionVariable()),
32 num_get_work_callback_cv_(lock_.CreateConditionVariable()),
33 run_sequences_cv_(lock_.CreateConditionVariable()) {}
34
35 void SetUp() override {
36 worker_thread_ = SchedulerWorkerThread::CreateSchedulerWorkerThread(
37 ThreadPriority::NORMAL,
38 Bind(&TaskSchedulerWorkerThreadTest::MainEntryCallback,
39 Unretained(this)),
40 Bind(&TaskSchedulerWorkerThreadTest::GetWorkCallback, Unretained(this)),
41 Bind(&TaskSchedulerWorkerThreadTest::RanTaskFromSequenceCallback,
42 Unretained(this)),
43 &task_tracker_);
44 ASSERT_TRUE(worker_thread_);
45 WaitForNumMainEntryCallback(1);
46 }
47
48 void TearDown() override {
49 worker_thread_->JoinForTesting();
50
51 AutoSchedulerLock auto_lock(lock_);
52 EXPECT_EQ(1U, num_main_entry_callback_);
53 }
gab 2016/04/05 23:35:20 Would be nice to test that the tests observed ever
fdoray 2016/04/07 13:56:47 Added "EXPECT_LE(num_run_tasks_, created_sequences
54
55 // Wait until MainEntryCallback() has been called |num_main_entry_callback|
56 // times.
57 void WaitForNumMainEntryCallback(size_t num_main_entry_callback) {
58 AutoSchedulerLock auto_lock(lock_);
59 while (num_main_entry_callback_ < num_main_entry_callback)
60 num_main_entry_callback_cv_->Wait();
61 }
62
63 // Wait until GetWorkCallback() has been called |num_get_work_callback| times.
64 void WaitForNumGetWorkCallback(size_t num_get_work_callback) {
65 AutoSchedulerLock auto_lock(lock_);
66 while (num_get_work_callback_ < num_get_work_callback)
67 num_get_work_callback_cv_->Wait();
68 }
69
70 // Wait until there is no more Sequences to create and
71 // RanTaskFromSequenceCallback() has been invoked once for each Sequence
72 // returned by GetWorkCallback().
73 void WaitForAllSequencesToRun() {
74 AutoSchedulerLock auto_lock(lock_);
75
76 while (num_sequences_to_create_ > 0 ||
77 run_sequences_.size() < created_sequences_.size()) {
78 run_sequences_cv_->Wait();
79 }
80
81 // Verify that RanTaskFromSequenceCallback() has been invoked with the
82 // same Sequences that were returned by GetWorkCallback().
83 EXPECT_EQ(created_sequences_, run_sequences_);
84
85 // Verify that RunTaskCallback() has been invoked once for each Sequence
86 // returned by GetWorkCallback().
87 EXPECT_EQ(created_sequences_.size(), num_run_tasks_);
88 }
89
90 void SetNumSequencesToCreate(size_t num_sequences_to_create) {
91 AutoSchedulerLock auto_lock(lock_);
92 EXPECT_EQ(0U, num_sequences_to_create_);
93 num_sequences_to_create_ = num_sequences_to_create;
94 }
95
96 size_t NumGetWorkCallback() const {
97 AutoSchedulerLock auto_lock(lock_);
98 return num_get_work_callback_;
99 }
100
101 scoped_ptr<SchedulerWorkerThread> worker_thread_;
102
103 private:
104 void MainEntryCallback() {
105 AutoSchedulerLock auto_lock(lock_);
106 ++num_main_entry_callback_;
107 num_main_entry_callback_cv_->Signal();
108 }
109
110 // Returns a Sequence that contains 1 Task if |num_sequences_to_create_| is
111 // greater than 0.
112 scoped_refptr<Sequence> GetWorkCallback(
113 SchedulerWorkerThread* worker_thread) {
114 EXPECT_EQ(worker_thread_.get(), worker_thread);
115
116 {
117 AutoSchedulerLock auto_lock(lock_);
118
119 // Increment the number of times that this callback has been invoked.
120 ++num_get_work_callback_;
121 num_get_work_callback_cv_->Signal();
122
123 // Check if a Sequence should be returned.
124 if (num_sequences_to_create_ == 0)
125 return nullptr;
126 --num_sequences_to_create_;
127 }
128
129 // Create a Sequence that contains 1 Task.
130 scoped_refptr<Sequence> sequence(new Sequence);
131 task_tracker_.PostTask(
132 Bind(IgnoreResult(&Sequence::PushTask), Unretained(sequence.get())),
133 make_scoped_ptr(new Task(
134 FROM_HERE, Bind(&TaskSchedulerWorkerThreadTest::RunTaskCallback,
135 Unretained(this)),
136 TaskTraits())));
137
138 {
139 // Add the Sequence to the vector of created Sequences.
140 AutoSchedulerLock auto_lock(lock_);
141 created_sequences_.push_back(sequence);
142 }
143
144 return sequence;
145 }
146
147 void RanTaskFromSequenceCallback(const SchedulerWorkerThread* worker_thread,
148 scoped_refptr<Sequence> sequence) {
149 EXPECT_EQ(worker_thread_.get(), worker_thread);
150
151 AutoSchedulerLock auto_lock(lock_);
152 run_sequences_.push_back(std::move(sequence));
153 run_sequences_cv_->Signal();
154 }
155
156 void RunTaskCallback() {
157 AutoSchedulerLock auto_lock(lock_);
158 ++num_run_tasks_;
159 }
160
161 TaskTracker task_tracker_;
162
163 // Synchronizes access to all members below.
164 mutable SchedulerLock lock_;
165
166 // Number of times that MainEntryCallback() has been called.
167 size_t num_main_entry_callback_ = 0;
168
169 // Condition variable signaled when |num_main_entry_callback_| is incremented.
170 scoped_ptr<ConditionVariable> num_main_entry_callback_cv_;
171
172 // Number of Sequences that should be created by GetWorkCallback(). When this
173 // is 0, GetWorkCallback() returns nullptr.
174 size_t num_sequences_to_create_ = 0;
175
176 // Number of times that GetWorkCallback() has been called.
177 size_t num_get_work_callback_ = 0;
178
179 // Condition variable signaled when |num_get_work_callback_| is incremented.
180 scoped_ptr<ConditionVariable> num_get_work_callback_cv_;
181
182 // Sequences created by GetWorkCallback().
183 std::vector<scoped_refptr<Sequence>> created_sequences_;
184
185 // Sequences passed to RanTaskFromSequenceCallback().
186 std::vector<scoped_refptr<Sequence>> run_sequences_;
187
188 // Condition variable signaled when a Sequence is added to |run_sequences_|.
189 scoped_ptr<ConditionVariable> run_sequences_cv_;
190
191 // Number of times that RunTaskCallback() has been called.
192 size_t num_run_tasks_ = 0;
193
194 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerThreadTest);
195 };
196
197 // Verify that when GetWorkCallback() continuously returns Sequences, all Tasks
198 // in these Sequences run successfully. The SchedulerWorkerThread is woken up
199 // once.
200 TEST_F(TaskSchedulerWorkerThreadTest, ContinousWork) {
gab 2016/04/05 23:35:20 Continuous Work ^
fdoray 2016/04/07 13:56:47 Done.
201 // Set GetWorkCallback() to return |kNumSequencesPerTest| Sequences before
202 // starting to return nullptr.
203 SetNumSequencesToCreate(kNumSequencesPerTest);
204
205 // Wake up |worker_thread_| and wait until it has run all the Tasks returned
206 // by GetWorkCallback().
207 worker_thread_->WakeUp();
208 WaitForAllSequencesToRun();
209
210 // Expect |kNumSequencesPerTest| calls to GetWorkCallback() in which it
211 // returned a Sequence and 1 call in which it returned nullptr.
212 const size_t expected_num_get_work_callback = kNumSequencesPerTest + 1;
gab 2016/04/05 23:35:20 kExpectedNumGetWorkCallback
fdoray 2016/04/07 13:56:47 Done.
213 WaitForNumGetWorkCallback(expected_num_get_work_callback);
gab 2016/04/05 23:35:20 If all sequences ran we shouldn't need to wait her
fdoray 2016/04/07 13:56:47 Yes, we need to wait for the call to GetWork() tha
214 EXPECT_EQ(expected_num_get_work_callback, NumGetWorkCallback());
gab 2016/04/05 23:35:20 if we don't need to wait above maybe make |num_get
fdoray 2016/04/07 13:56:47 We do need to wait above.
215 }
gab 2016/04/05 23:35:20 Test num wakeups? Since it's stated in test descri
fdoray 2016/04/07 13:56:47 I updated the test description. The test calls Wak
216
217 // Verify that when GetWorkCallback() alternates between returning a Sequence
218 // and returning nullptr, all Tasks in the returned Sequences run successfully.
219 // The SchedulerWorkerThread is woken up once for each Sequence.
220 TEST_F(TaskSchedulerWorkerThreadTest, IntermittentWork) {
221 for (size_t i = 0; i < kNumSequencesPerTest; ++i) {
222 // Set GetWorkCallback() to return 1 Sequence before starting to return
223 // nullptr.
224 SetNumSequencesToCreate(1);
225
226 // Wake up |worker_thread_| and wait until it has run all the Tasks returned
227 // by GetWorkCallback().
228 worker_thread_->WakeUp();
229 WaitForAllSequencesToRun();
230
231 // Expect |i| calls to GetWorkCallback() in which it returned a Sequence and
232 // |i| calls in which it returned nullptr.
233 const size_t expected_num_get_work_callback = 2 * (i + 1);
234 WaitForNumGetWorkCallback(expected_num_get_work_callback);
235 EXPECT_EQ(expected_num_get_work_callback, NumGetWorkCallback());
236 }
237 }
gab 2016/04/05 23:35:20 Test num wakeups?
fdoray 2016/04/07 13:56:47 ditto
238
239 } // namespace
240 } // namespace internal
241 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698