| 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 |