| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/scheduler/base/task_queue_selector.h" | 5 #include "components/scheduler/base/task_queue_selector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 for (size_t i = 0; i < kTaskQueueCount; i++) { | 119 for (size_t i = 0; i < kTaskQueueCount; i++) { |
| 120 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[i]->GetQueuePriority()) | 120 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[i]->GetQueuePriority()) |
| 121 << i; | 121 << i; |
| 122 queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i)); | 122 queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i)); |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 | 125 |
| 126 void TearDown() final { | 126 void TearDown() final { |
| 127 for (scoped_refptr<TaskQueueImpl>& task_queue : task_queues_) { | 127 for (scoped_refptr<TaskQueueImpl>& task_queue : task_queues_) { |
| 128 task_queue->UnregisterTaskQueue(); | 128 task_queue->UnregisterTaskQueue(); |
| 129 // Note since this test doesn't have a TaskQueueManager we need to |
| 130 // manually remove |task_queue| from the |selector_|. Normally |
| 131 // UnregisterTaskQueue would do that. |
| 132 selector_.RemoveQueue(task_queue.get()); |
| 129 } | 133 } |
| 130 } | 134 } |
| 131 | 135 |
| 132 scoped_refptr<TaskQueueImpl> NewTaskQueueWithBlockReporting() { | 136 scoped_refptr<TaskQueueImpl> NewTaskQueueWithBlockReporting() { |
| 133 return make_scoped_refptr(new TaskQueueImpl( | 137 return make_scoped_refptr(new TaskQueueImpl( |
| 134 nullptr, virtual_time_domain_.get(), | 138 nullptr, virtual_time_domain_.get(), |
| 135 TaskQueue::Spec("test queue").SetShouldReportWhenExecutionBlocked(true), | 139 TaskQueue::Spec("test queue").SetShouldReportWhenExecutionBlocked(true), |
| 136 "test", "test")); | 140 "test", "test")); |
| 137 } | 141 } |
| 138 | 142 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) { | 184 TEST_F(TaskQueueSelectorTest, TestObserverWithEnabledQueue) { |
| 181 DisableQueue(task_queues_[1].get()); | 185 DisableQueue(task_queues_[1].get()); |
| 182 MockObserver mock_observer; | 186 MockObserver mock_observer; |
| 183 selector_.SetTaskQueueSelectorObserver(&mock_observer); | 187 selector_.SetTaskQueueSelectorObserver(&mock_observer); |
| 184 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); | 188 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); |
| 185 EnableQueue(task_queues_[1].get()); | 189 EnableQueue(task_queues_[1].get()); |
| 186 } | 190 } |
| 187 | 191 |
| 188 TEST_F(TaskQueueSelectorTest, | 192 TEST_F(TaskQueueSelectorTest, |
| 189 TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) { | 193 TestObserverWithSetQueuePriorityAndQueueAlreadyEnabled) { |
| 190 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); | 194 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY); |
| 191 MockObserver mock_observer; | 195 MockObserver mock_observer; |
| 192 selector_.SetTaskQueueSelectorObserver(&mock_observer); | 196 selector_.SetTaskQueueSelectorObserver(&mock_observer); |
| 193 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0); | 197 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(0); |
| 194 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); | 198 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); |
| 195 } | 199 } |
| 196 | 200 |
| 197 TEST_F(TaskQueueSelectorTest, TestDisableEnable) { | 201 TEST_F(TaskQueueSelectorTest, TestDisableEnable) { |
| 198 MockObserver mock_observer; | 202 MockObserver mock_observer; |
| 199 selector_.SetTaskQueueSelectorObserver(&mock_observer); | 203 selector_.SetTaskQueueSelectorObserver(&mock_observer); |
| 200 | 204 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal. | 291 EXPECT_GT(counts[0], 0ul); // Check high doesn't starve normal. |
| 288 EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run. | 292 EXPECT_GT(counts[2], counts[0]); // Check high gets more chance to run. |
| 289 EXPECT_EQ(0ul, counts[1]); // Check best effort is starved. | 293 EXPECT_EQ(0ul, counts[1]); // Check best effort is starved. |
| 290 } | 294 } |
| 291 | 295 |
| 292 TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) { | 296 TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) { |
| 293 size_t queue_order[] = {0, 1}; | 297 size_t queue_order[] = {0, 1}; |
| 294 PushTasks(queue_order, 2); | 298 PushTasks(queue_order, 2); |
| 295 selector_.SetQueuePriority(task_queues_[0].get(), | 299 selector_.SetQueuePriority(task_queues_[0].get(), |
| 296 TaskQueue::BEST_EFFORT_PRIORITY); | 300 TaskQueue::BEST_EFFORT_PRIORITY); |
| 297 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::NORMAL_PRIORITY); | 301 EXPECT_EQ(TaskQueue::NORMAL_PRIORITY, task_queues_[1]->GetQueuePriority()); |
| 298 WorkQueue* chosen_work_queue = nullptr; | 302 WorkQueue* chosen_work_queue = nullptr; |
| 299 for (int i = 0; i < 100; i++) { | 303 for (int i = 0; i < 100; i++) { |
| 300 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); | 304 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); |
| 301 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); | 305 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); |
| 302 // Don't remove task from queue to simulate all queues still being full. | 306 // Don't remove task from queue to simulate all queues still being full. |
| 303 } | 307 } |
| 304 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY); | 308 selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::HIGH_PRIORITY); |
| 305 for (int i = 0; i < 100; i++) { | 309 for (int i = 0; i < 100; i++) { |
| 306 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); | 310 EXPECT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); |
| 307 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); | 311 EXPECT_EQ(task_queues_[1].get(), chosen_work_queue->task_queue()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 387 |
| 384 task_queue->immediate_work_queue()->PushAndSetEnqueueOrder( | 388 task_queue->immediate_work_queue()->PushAndSetEnqueueOrder( |
| 385 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true), | 389 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, true), |
| 386 0); | 390 0); |
| 387 | 391 |
| 388 WorkQueue* chosen_work_queue; | 392 WorkQueue* chosen_work_queue; |
| 389 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); | 393 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); |
| 390 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); | 394 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); |
| 391 | 395 |
| 392 task_queue->UnregisterTaskQueue(); | 396 task_queue->UnregisterTaskQueue(); |
| 397 selector.RemoveQueue(task_queue.get()); |
| 393 } | 398 } |
| 394 | 399 |
| 395 TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) { | 400 TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) { |
| 396 TaskQueueSelectorForTest selector; | 401 TaskQueueSelectorForTest selector; |
| 397 MockObserver mock_observer; | 402 MockObserver mock_observer; |
| 398 selector.SetTaskQueueSelectorObserver(&mock_observer); | 403 selector.SetTaskQueueSelectorObserver(&mock_observer); |
| 399 | 404 |
| 400 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); | 405 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); |
| 401 scoped_refptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting()); | 406 scoped_refptr<TaskQueueImpl> task_queue2(NewTaskQueueWithBlockReporting()); |
| 402 selector.AddQueue(task_queue.get()); | 407 selector.AddQueue(task_queue.get()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 415 0); | 420 0); |
| 416 | 421 |
| 417 // Should still only see one call to OnTriedToSelectBlockedWorkQueue. | 422 // Should still only see one call to OnTriedToSelectBlockedWorkQueue. |
| 418 WorkQueue* chosen_work_queue; | 423 WorkQueue* chosen_work_queue; |
| 419 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); | 424 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); |
| 420 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); | 425 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); |
| 421 testing::Mock::VerifyAndClearExpectations(&mock_observer); | 426 testing::Mock::VerifyAndClearExpectations(&mock_observer); |
| 422 | 427 |
| 423 // Removing the second queue and selecting again should result in another | 428 // Removing the second queue and selecting again should result in another |
| 424 // notification. | 429 // notification. |
| 430 task_queue->UnregisterTaskQueue(); |
| 425 selector.RemoveQueue(task_queue.get()); | 431 selector.RemoveQueue(task_queue.get()); |
| 426 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); | 432 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); |
| 427 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); | 433 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); |
| 428 | 434 |
| 429 task_queue->UnregisterTaskQueue(); | |
| 430 task_queue2->UnregisterTaskQueue(); | 435 task_queue2->UnregisterTaskQueue(); |
| 436 selector.RemoveQueue(task_queue2.get()); |
| 431 } | 437 } |
| 432 | 438 |
| 433 struct ChooseOldestWithPriorityTestParam { | 439 struct ChooseOldestWithPriorityTestParam { |
| 434 int delayed_task_enqueue_order; | 440 int delayed_task_enqueue_order; |
| 435 int immediate_task_enqueue_order; | 441 int immediate_task_enqueue_order; |
| 436 int immediate_starvation_count; | 442 int immediate_starvation_count; |
| 437 const char* expected_work_queue_name; | 443 const char* expected_work_queue_name; |
| 438 bool expected_did_starve_immediate_queue; | 444 bool expected_did_starve_immediate_queue; |
| 439 }; | 445 }; |
| 440 | 446 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 EXPECT_EQ(chose_delayed_over_immediate, | 483 EXPECT_EQ(chose_delayed_over_immediate, |
| 478 GetParam().expected_did_starve_immediate_queue); | 484 GetParam().expected_did_starve_immediate_queue); |
| 479 } | 485 } |
| 480 | 486 |
| 481 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, | 487 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, |
| 482 ChooseOldestWithPriorityTest, | 488 ChooseOldestWithPriorityTest, |
| 483 testing::ValuesIn(kChooseOldestWithPriorityTestCases)); | 489 testing::ValuesIn(kChooseOldestWithPriorityTestCases)); |
| 484 | 490 |
| 485 } // namespace internal | 491 } // namespace internal |
| 486 } // namespace scheduler | 492 } // namespace scheduler |
| OLD | NEW |