OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/task_scheduler/scheduler_worker.h" | 5 #include "base/task_scheduler/scheduler_worker.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <vector> | 10 #include <vector> |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 class SchedulerWorkerDefaultDelegate : public SchedulerWorker::Delegate { | 39 class SchedulerWorkerDefaultDelegate : public SchedulerWorker::Delegate { |
40 public: | 40 public: |
41 SchedulerWorkerDefaultDelegate() = default; | 41 SchedulerWorkerDefaultDelegate() = default; |
42 | 42 |
43 // SchedulerWorker::Delegate: | 43 // SchedulerWorker::Delegate: |
44 void OnMainEntry(SchedulerWorker* worker) override {} | 44 void OnMainEntry(SchedulerWorker* worker) override {} |
45 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override { | 45 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override { |
46 return nullptr; | 46 return nullptr; |
47 } | 47 } |
48 void DidRunTaskWithPriority(TaskPriority task_priority, | 48 void DidRunTask() override { |
49 TimeDelta task_latency) override { | 49 ADD_FAILURE() << "Unexpected call to DidRunTask()"; |
50 ADD_FAILURE() << "Unexpected call to DidRunTaskWithPriority()"; | |
51 } | 50 } |
52 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override { | 51 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override { |
53 ADD_FAILURE() << "Unexpected call to ReEnqueueSequence()"; | 52 ADD_FAILURE() << "Unexpected call to ReEnqueueSequence()"; |
54 } | 53 } |
55 TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); } | 54 TimeDelta GetSleepTimeout() override { return TimeDelta::Max(); } |
56 bool CanDetach(SchedulerWorker* worker) override { return false; } | 55 bool CanDetach(SchedulerWorker* worker) override { return false; } |
57 void OnDetach() override { ADD_FAILURE() << "Unexpected call to OnDetach()"; } | 56 void OnDetach() override { ADD_FAILURE() << "Unexpected call to OnDetach()"; } |
58 | 57 |
59 private: | 58 private: |
60 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDefaultDelegate); | 59 DISALLOW_COPY_AND_ASSIGN(SchedulerWorkerDefaultDelegate); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 | 119 |
121 std::unique_ptr<SchedulerWorker> worker_; | 120 std::unique_ptr<SchedulerWorker> worker_; |
122 | 121 |
123 private: | 122 private: |
124 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate { | 123 class TestSchedulerWorkerDelegate : public SchedulerWorkerDefaultDelegate { |
125 public: | 124 public: |
126 TestSchedulerWorkerDelegate(TaskSchedulerWorkerTest* outer) | 125 TestSchedulerWorkerDelegate(TaskSchedulerWorkerTest* outer) |
127 : outer_(outer) {} | 126 : outer_(outer) {} |
128 | 127 |
129 ~TestSchedulerWorkerDelegate() override { | 128 ~TestSchedulerWorkerDelegate() override { |
130 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected()); | 129 EXPECT_FALSE(IsCallToDidRunTaskExpected()); |
131 } | 130 } |
132 | 131 |
133 // SchedulerWorker::Delegate: | 132 // SchedulerWorker::Delegate: |
134 void OnMainEntry(SchedulerWorker* worker) override { | 133 void OnMainEntry(SchedulerWorker* worker) override { |
135 outer_->worker_set_.Wait(); | 134 outer_->worker_set_.Wait(); |
136 EXPECT_EQ(outer_->worker_.get(), worker); | 135 EXPECT_EQ(outer_->worker_.get(), worker); |
137 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected()); | 136 EXPECT_FALSE(IsCallToDidRunTaskExpected()); |
138 | 137 |
139 // Without synchronization, OnMainEntry() could be called twice without | 138 // Without synchronization, OnMainEntry() could be called twice without |
140 // generating an error. | 139 // generating an error. |
141 AutoSchedulerLock auto_lock(outer_->lock_); | 140 AutoSchedulerLock auto_lock(outer_->lock_); |
142 EXPECT_FALSE(outer_->main_entry_called_.IsSignaled()); | 141 EXPECT_FALSE(outer_->main_entry_called_.IsSignaled()); |
143 outer_->main_entry_called_.Signal(); | 142 outer_->main_entry_called_.Signal(); |
144 } | 143 } |
145 | 144 |
146 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override { | 145 scoped_refptr<Sequence> GetWork(SchedulerWorker* worker) override { |
147 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected()); | 146 EXPECT_FALSE(IsCallToDidRunTaskExpected()); |
148 EXPECT_EQ(outer_->worker_.get(), worker); | 147 EXPECT_EQ(outer_->worker_.get(), worker); |
149 | 148 |
150 { | 149 { |
151 AutoSchedulerLock auto_lock(outer_->lock_); | 150 AutoSchedulerLock auto_lock(outer_->lock_); |
152 | 151 |
153 // Increment the number of times that this method has been called. | 152 // Increment the number of times that this method has been called. |
154 ++outer_->num_get_work_; | 153 ++outer_->num_get_work_; |
155 outer_->num_get_work_cv_->Signal(); | 154 outer_->num_get_work_cv_->Signal(); |
156 | 155 |
157 // Verify that this method isn't called more times than expected. | 156 // Verify that this method isn't called more times than expected. |
158 EXPECT_LE(outer_->num_get_work_, outer_->max_get_work_); | 157 EXPECT_LE(outer_->num_get_work_, outer_->max_get_work_); |
159 | 158 |
160 // Check if a Sequence should be returned. | 159 // Check if a Sequence should be returned. |
161 if (outer_->num_sequences_to_create_ == 0) | 160 if (outer_->num_sequences_to_create_ == 0) |
162 return nullptr; | 161 return nullptr; |
163 --outer_->num_sequences_to_create_; | 162 --outer_->num_sequences_to_create_; |
164 } | 163 } |
165 | 164 |
166 // Create a Sequence with TasksPerSequence() Tasks. | 165 // Create a Sequence with TasksPerSequence() Tasks. |
167 scoped_refptr<Sequence> sequence(new Sequence); | 166 scoped_refptr<Sequence> sequence(new Sequence); |
168 for (size_t i = 0; i < outer_->TasksPerSequence(); ++i) { | 167 for (size_t i = 0; i < outer_->TasksPerSequence(); ++i) { |
169 std::unique_ptr<Task> task(new Task( | 168 std::unique_ptr<Task> task(new Task( |
170 FROM_HERE, Bind(&TaskSchedulerWorkerTest::RunTaskCallback, | 169 FROM_HERE, Bind(&TaskSchedulerWorkerTest::RunTaskCallback, |
171 Unretained(outer_)), | 170 Unretained(outer_)), |
172 TaskTraits(), TimeDelta())); | 171 TaskTraits(), TimeDelta())); |
173 EXPECT_TRUE(outer_->task_tracker_.WillPostTask(task.get())); | 172 EXPECT_TRUE(outer_->task_tracker_.WillPostTask(task.get())); |
174 sequence->PushTask(std::move(task)); | 173 sequence->PushTask(std::move(task)); |
175 } | 174 } |
176 | 175 |
177 ExpectCallToDidRunTaskWithPriority(sequence->PeekTaskTraits().priority()); | 176 ExpectCallToDidRunTask(); |
178 | 177 |
179 { | 178 { |
180 // Add the Sequence to the vector of created Sequences. | 179 // Add the Sequence to the vector of created Sequences. |
181 AutoSchedulerLock auto_lock(outer_->lock_); | 180 AutoSchedulerLock auto_lock(outer_->lock_); |
182 outer_->created_sequences_.push_back(sequence); | 181 outer_->created_sequences_.push_back(sequence); |
183 } | 182 } |
184 | 183 |
185 return sequence; | 184 return sequence; |
186 } | 185 } |
187 | 186 |
188 void DidRunTaskWithPriority(TaskPriority task_priority, | 187 void DidRunTask() override { |
189 TimeDelta task_latency) override { | 188 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
190 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_); | 189 EXPECT_TRUE(expect_did_run_task_); |
191 EXPECT_TRUE(expect_did_run_task_with_priority_); | 190 expect_did_run_task_ = false; |
192 EXPECT_EQ(expected_task_priority_, task_priority); | |
193 EXPECT_FALSE(task_latency.is_max()); | |
194 expect_did_run_task_with_priority_ = false; | |
195 } | 191 } |
196 | 192 |
197 // This override verifies that |sequence| contains the expected number of | 193 // This override verifies that |sequence| contains the expected number of |
198 // Tasks and adds it to |enqueued_sequences_|. Unlike a normal | 194 // Tasks and adds it to |enqueued_sequences_|. Unlike a normal |
199 // EnqueueSequence implementation, it doesn't reinsert |sequence| into a | 195 // EnqueueSequence implementation, it doesn't reinsert |sequence| into a |
200 // queue for further execution. | 196 // queue for further execution. |
201 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override { | 197 void ReEnqueueSequence(scoped_refptr<Sequence> sequence) override { |
202 EXPECT_FALSE(IsCallToDidRunTaskWithPriorityExpected()); | 198 EXPECT_FALSE(IsCallToDidRunTaskExpected()); |
203 EXPECT_GT(outer_->TasksPerSequence(), 1U); | 199 EXPECT_GT(outer_->TasksPerSequence(), 1U); |
204 | 200 |
205 // Verify that |sequence| contains TasksPerSequence() - 1 Tasks. | 201 // Verify that |sequence| contains TasksPerSequence() - 1 Tasks. |
206 for (size_t i = 0; i < outer_->TasksPerSequence() - 1; ++i) { | 202 for (size_t i = 0; i < outer_->TasksPerSequence() - 1; ++i) { |
207 EXPECT_TRUE(sequence->TakeTask()); | 203 EXPECT_TRUE(sequence->TakeTask()); |
208 EXPECT_EQ(i == outer_->TasksPerSequence() - 2, sequence->Pop()); | 204 EXPECT_EQ(i == outer_->TasksPerSequence() - 2, sequence->Pop()); |
209 } | 205 } |
210 | 206 |
211 // Add |sequence| to |re_enqueued_sequences_|. | 207 // Add |sequence| to |re_enqueued_sequences_|. |
212 AutoSchedulerLock auto_lock(outer_->lock_); | 208 AutoSchedulerLock auto_lock(outer_->lock_); |
213 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); | 209 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); |
214 EXPECT_LE(outer_->re_enqueued_sequences_.size(), | 210 EXPECT_LE(outer_->re_enqueued_sequences_.size(), |
215 outer_->created_sequences_.size()); | 211 outer_->created_sequences_.size()); |
216 } | 212 } |
217 | 213 |
218 private: | 214 private: |
219 // Expect a call to DidRunTaskWithPriority() with |task_priority| as | 215 // Expect a call to DidRunTask() before the next call to any other method of |
220 // argument before the next call to any other method of this delegate. | 216 // this delegate. |
221 void ExpectCallToDidRunTaskWithPriority(TaskPriority task_priority) { | 217 void ExpectCallToDidRunTask() { |
222 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_); | 218 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
223 expect_did_run_task_with_priority_ = true; | 219 expect_did_run_task_ = true; |
224 expected_task_priority_ = task_priority; | |
225 } | 220 } |
226 | 221 |
227 bool IsCallToDidRunTaskWithPriorityExpected() const { | 222 bool IsCallToDidRunTaskExpected() const { |
228 AutoSchedulerLock auto_lock(expect_did_run_task_with_priority_lock_); | 223 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
229 return expect_did_run_task_with_priority_; | 224 return expect_did_run_task_; |
230 } | 225 } |
231 | 226 |
232 TaskSchedulerWorkerTest* outer_; | 227 TaskSchedulerWorkerTest* outer_; |
233 | 228 |
234 // Synchronizes access to |expect_did_run_task_with_priority_| and | 229 // Synchronizes access to |expect_did_run_task_|. |
235 // |expected_task_priority_|. | 230 mutable SchedulerLock expect_did_run_task_lock_; |
236 mutable SchedulerLock expect_did_run_task_with_priority_lock_; | |
237 | 231 |
238 // Whether the next method called on this delegate should be | 232 // Whether the next method called on this delegate should be DidRunTask(). |
239 // DidRunTaskWithPriority(). | 233 bool expect_did_run_task_ = false; |
240 bool expect_did_run_task_with_priority_ = false; | |
241 | 234 |
242 // Expected priority for the next call to DidRunTaskWithPriority(). | 235 DISALLOW_COPY_AND_ASSIGN(TestSchedulerWorkerDelegate); |
243 TaskPriority expected_task_priority_ = TaskPriority::BACKGROUND; | |
244 }; | 236 }; |
245 | 237 |
246 void RunTaskCallback() { | 238 void RunTaskCallback() { |
247 AutoSchedulerLock auto_lock(lock_); | 239 AutoSchedulerLock auto_lock(lock_); |
248 ++num_run_tasks_; | 240 ++num_run_tasks_; |
249 EXPECT_LE(num_run_tasks_, created_sequences_.size()); | 241 EXPECT_LE(num_run_tasks_, created_sequences_.size()); |
250 } | 242 } |
251 | 243 |
252 TaskTracker task_tracker_; | 244 TaskTracker task_tracker_; |
253 | 245 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 work_requested_ = true; | 375 work_requested_ = true; |
384 scoped_refptr<Sequence> sequence(new Sequence); | 376 scoped_refptr<Sequence> sequence(new Sequence); |
385 std::unique_ptr<Task> task(new Task( | 377 std::unique_ptr<Task> task(new Task( |
386 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), | 378 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), |
387 TaskTraits(), TimeDelta())); | 379 TaskTraits(), TimeDelta())); |
388 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); | 380 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); |
389 sequence->PushTask(std::move(task)); | 381 sequence->PushTask(std::move(task)); |
390 return sequence; | 382 return sequence; |
391 } | 383 } |
392 | 384 |
393 void DidRunTaskWithPriority(TaskPriority task, | 385 void DidRunTask() override {} |
394 TimeDelta task_latency) override {} | |
395 | 386 |
396 bool CanDetach(SchedulerWorker* worker) override { | 387 bool CanDetach(SchedulerWorker* worker) override { |
397 detach_requested_.Signal(); | 388 detach_requested_.Signal(); |
398 return can_detach_; | 389 return can_detach_; |
399 } | 390 } |
400 | 391 |
401 void OnDetach() override { | 392 void OnDetach() override { |
402 EXPECT_TRUE(can_detach_); | 393 EXPECT_TRUE(can_detach_); |
403 EXPECT_TRUE(detach_requested_.IsSignaled()); | 394 EXPECT_TRUE(detach_requested_.IsSignaled()); |
404 detached_.Signal(); | 395 detached_.Signal(); |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 // OnMainEntry() and GetWork() are called. | 592 // OnMainEntry() and GetWork() are called. |
602 worker->WakeUp(); | 593 worker->WakeUp(); |
603 delegate_raw->WaitForPriorityVerifiedInGetWork(); | 594 delegate_raw->WaitForPriorityVerifiedInGetWork(); |
604 | 595 |
605 worker->JoinForTesting(); | 596 worker->JoinForTesting(); |
606 } | 597 } |
607 | 598 |
608 } // namespace | 599 } // namespace |
609 } // namespace internal | 600 } // namespace internal |
610 } // namespace base | 601 } // namespace base |
OLD | NEW |