| 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 DidRunTask(TaskPriority task_priority, |
| 50 const TimeDelta& task_latency) override { |
| 50 ADD_FAILURE() << "Unexpected call to DidRunTask()"; | 51 ADD_FAILURE() << "Unexpected call to DidRunTask()"; |
| 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); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 ExpectCallToDidRunTask(sequence->GetFrontTaskTraits().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 DidRunTask(TaskPriority task_priority, |
| 190 const TimeDelta& task_latency) override { |
| 189 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); | 191 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
| 190 EXPECT_EQ(expect_did_run_task_, task); | 192 EXPECT_TRUE(expect_did_run_task_); |
| 191 expect_did_run_task_ = nullptr; | 193 EXPECT_EQ(expect_did_run_task_with_priority_, task_priority); |
| 192 EXPECT_FALSE(task_latency.is_max()); | 194 EXPECT_FALSE(task_latency.is_max()); |
| 195 expect_did_run_task_ = 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(IsCallToDidRunTaskExpected()); |
| 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 sequence->RemoveFrontSlot(); |
| 207 } | 210 } |
| 208 EXPECT_FALSE(sequence->PeekTask()); | 211 EXPECT_FALSE(sequence->TakeTask()); |
| 209 | 212 |
| 210 // Add |sequence| to |re_enqueued_sequences_|. | 213 // Add |sequence| to |re_enqueued_sequences_|. |
| 211 AutoSchedulerLock auto_lock(outer_->lock_); | 214 AutoSchedulerLock auto_lock(outer_->lock_); |
| 212 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); | 215 outer_->re_enqueued_sequences_.push_back(std::move(sequence)); |
| 213 EXPECT_LE(outer_->re_enqueued_sequences_.size(), | 216 EXPECT_LE(outer_->re_enqueued_sequences_.size(), |
| 214 outer_->created_sequences_.size()); | 217 outer_->created_sequences_.size()); |
| 215 } | 218 } |
| 216 | 219 |
| 217 private: | 220 private: |
| 218 // Expect a call to DidRunTask() with |task| as argument before the next | 221 // Expect a call to DidRunTask() with |task_priority| as argument before the |
| 219 // call to any other method of this delegate. | 222 // next call to any other method of this delegate. |
| 220 void ExpectCallToDidRunTask(const Task* task) { | 223 void ExpectCallToDidRunTask(TaskPriority task_priority) { |
| 221 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); | 224 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
| 222 expect_did_run_task_ = task; | 225 expect_did_run_task_ = true; |
| 226 expect_did_run_task_with_priority_ = task_priority; |
| 223 } | 227 } |
| 224 | 228 |
| 225 bool IsCallToDidRunTaskExpected() const { | 229 bool IsCallToDidRunTaskExpected() const { |
| 226 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); | 230 AutoSchedulerLock auto_lock(expect_did_run_task_lock_); |
| 227 return expect_did_run_task_ != nullptr; | 231 return expect_did_run_task_; |
| 228 } | 232 } |
| 229 | 233 |
| 230 TaskSchedulerWorkerTest* outer_; | 234 TaskSchedulerWorkerTest* outer_; |
| 231 | 235 |
| 232 // Synchronizes access to |expect_did_run_task_|. | 236 // Synchronizes access to |expect_did_run_task_| and |
| 237 // |expect_did_run_task_with_priority_|. |
| 233 mutable SchedulerLock expect_did_run_task_lock_; | 238 mutable SchedulerLock expect_did_run_task_lock_; |
| 234 | 239 |
| 235 // Expected task for the next call to DidRunTask(). DidRunTask() should not | 240 // When this is true, the next method called on this delegate should be |
| 236 // be called when this is nullptr. No method other than DidRunTask() should | 241 // DidRunTask(). |
| 237 // be called on this delegate when this is not nullptr. | 242 bool expect_did_run_task_ = false; |
| 238 const Task* expect_did_run_task_ = nullptr; | 243 |
| 244 // Expected priority for the next call to DidRunTask(). |
| 245 TaskPriority expect_did_run_task_with_priority_ = TaskPriority::BACKGROUND; |
| 239 }; | 246 }; |
| 240 | 247 |
| 241 void RunTaskCallback() { | 248 void RunTaskCallback() { |
| 242 AutoSchedulerLock auto_lock(lock_); | 249 AutoSchedulerLock auto_lock(lock_); |
| 243 ++num_run_tasks_; | 250 ++num_run_tasks_; |
| 244 EXPECT_LE(num_run_tasks_, created_sequences_.size()); | 251 EXPECT_LE(num_run_tasks_, created_sequences_.size()); |
| 245 } | 252 } |
| 246 | 253 |
| 247 TaskTracker task_tracker_; | 254 TaskTracker task_tracker_; |
| 248 | 255 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 work_requested_ = true; | 384 work_requested_ = true; |
| 378 scoped_refptr<Sequence> sequence(new Sequence); | 385 scoped_refptr<Sequence> sequence(new Sequence); |
| 379 std::unique_ptr<Task> task(new Task( | 386 std::unique_ptr<Task> task(new Task( |
| 380 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), | 387 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&work_processed_)), |
| 381 TaskTraits(), TimeDelta())); | 388 TaskTraits(), TimeDelta())); |
| 382 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); | 389 EXPECT_TRUE(task_tracker_->WillPostTask(task.get())); |
| 383 sequence->PushTask(std::move(task)); | 390 sequence->PushTask(std::move(task)); |
| 384 return sequence; | 391 return sequence; |
| 385 } | 392 } |
| 386 | 393 |
| 387 void DidRunTask(const Task* task, const TimeDelta& task_latency) override {} | 394 void DidRunTask(TaskPriority task, 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 |