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