| 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 "platform/scheduler/base/task_queue_selector.h" | 5 #include "platform/scheduler/base/task_queue_selector.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 } | 59 } |
| 60 WorkQueueSets* immediate_work_queue_sets() { | 60 WorkQueueSets* immediate_work_queue_sets() { |
| 61 return enabled_selector()->immediate_work_queue_sets(); | 61 return enabled_selector()->immediate_work_queue_sets(); |
| 62 } | 62 } |
| 63 | 63 |
| 64 void PushTasks(const size_t queue_indices[], size_t num_tasks) { | 64 void PushTasks(const size_t queue_indices[], size_t num_tasks) { |
| 65 std::set<size_t> changed_queue_set; | 65 std::set<size_t> changed_queue_set; |
| 66 for (size_t i = 0; i < num_tasks; i++) { | 66 for (size_t i = 0; i < num_tasks; i++) { |
| 67 changed_queue_set.insert(queue_indices[i]); | 67 changed_queue_set.insert(queue_indices[i]); |
| 68 task_queues_[queue_indices[i]]->immediate_work_queue()->Push( | 68 task_queues_[queue_indices[i]]->immediate_work_queue()->Push( |
| 69 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, | 69 TaskQueueImpl::Task(FROM_HERE, test_closure_, {base::TimeTicks(), i}, |
| 70 true, i)); | 70 true)); |
| 71 } | 71 } |
| 72 } | 72 } |
| 73 | 73 |
| 74 void PushTasksWithEnqueueOrder(const size_t queue_indices[], | 74 void PushTasksWithEnqueueOrder(const size_t queue_indices[], |
| 75 const size_t enqueue_orders[], | 75 const size_t enqueue_orders[], |
| 76 size_t num_tasks) { | 76 size_t num_tasks) { |
| 77 std::set<size_t> changed_queue_set; | 77 std::set<size_t> changed_queue_set; |
| 78 for (size_t i = 0; i < num_tasks; i++) { | 78 for (size_t i = 0; i < num_tasks; i++) { |
| 79 changed_queue_set.insert(queue_indices[i]); | 79 changed_queue_set.insert(queue_indices[i]); |
| 80 task_queues_[queue_indices[i]]->immediate_work_queue()->Push( | 80 task_queues_[queue_indices[i]]->immediate_work_queue()->Push( |
| 81 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), 0, | 81 TaskQueueImpl::Task(FROM_HERE, test_closure_, |
| 82 true, enqueue_orders[i])); | 82 {base::TimeTicks(), enqueue_orders[i]}, true)); |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 std::vector<size_t> PopTasks() { | 86 std::vector<size_t> PopTasks() { |
| 87 std::vector<size_t> order; | 87 std::vector<size_t> order; |
| 88 WorkQueue* chosen_work_queue; | 88 WorkQueue* chosen_work_queue; |
| 89 while (selector_.SelectWorkQueueToService(&chosen_work_queue)) { | 89 while (selector_.SelectWorkQueueToService(&chosen_work_queue)) { |
| 90 size_t chosen_queue_index = | 90 size_t chosen_queue_index = |
| 91 queue_to_index_map_.find(chosen_work_queue->task_queue())->second; | 91 queue_to_index_map_.find(chosen_work_queue->task_queue())->second; |
| 92 order.push_back(chosen_queue_index); | 92 order.push_back(chosen_queue_index); |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 WorkQueue* chosen_work_queue = nullptr; | 372 WorkQueue* chosen_work_queue = nullptr; |
| 373 bool chose_delayed_over_immediate = false; | 373 bool chose_delayed_over_immediate = false; |
| 374 EXPECT_FALSE(enabled_selector()->ChooseOldestWithPriority( | 374 EXPECT_FALSE(enabled_selector()->ChooseOldestWithPriority( |
| 375 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, | 375 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, |
| 376 &chosen_work_queue)); | 376 &chosen_work_queue)); |
| 377 EXPECT_FALSE(chose_delayed_over_immediate); | 377 EXPECT_FALSE(chose_delayed_over_immediate); |
| 378 } | 378 } |
| 379 | 379 |
| 380 TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) { | 380 TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) { |
| 381 task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task( | 381 task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task( |
| 382 FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0)); | 382 FROM_HERE, test_closure_, {base::TimeTicks(), 0}, true)); |
| 383 | 383 |
| 384 WorkQueue* chosen_work_queue = nullptr; | 384 WorkQueue* chosen_work_queue = nullptr; |
| 385 bool chose_delayed_over_immediate = false; | 385 bool chose_delayed_over_immediate = false; |
| 386 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( | 386 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( |
| 387 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, | 387 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, |
| 388 &chosen_work_queue)); | 388 &chosen_work_queue)); |
| 389 EXPECT_EQ(chosen_work_queue, task_queues_[0]->delayed_work_queue()); | 389 EXPECT_EQ(chosen_work_queue, task_queues_[0]->delayed_work_queue()); |
| 390 EXPECT_FALSE(chose_delayed_over_immediate); | 390 EXPECT_FALSE(chose_delayed_over_immediate); |
| 391 } | 391 } |
| 392 | 392 |
| 393 TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyImmediate) { | 393 TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyImmediate) { |
| 394 task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task( | 394 task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task( |
| 395 FROM_HERE, test_closure_, base::TimeTicks(), 0, true, 0)); | 395 FROM_HERE, test_closure_, {base::TimeTicks(), 0}, true)); |
| 396 | 396 |
| 397 WorkQueue* chosen_work_queue = nullptr; | 397 WorkQueue* chosen_work_queue = nullptr; |
| 398 bool chose_delayed_over_immediate = false; | 398 bool chose_delayed_over_immediate = false; |
| 399 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( | 399 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( |
| 400 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, | 400 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, |
| 401 &chosen_work_queue)); | 401 &chosen_work_queue)); |
| 402 EXPECT_EQ(chosen_work_queue, task_queues_[0]->immediate_work_queue()); | 402 EXPECT_EQ(chosen_work_queue, task_queues_[0]->immediate_work_queue()); |
| 403 EXPECT_FALSE(chose_delayed_over_immediate); | 403 EXPECT_FALSE(chose_delayed_over_immediate); |
| 404 } | 404 } |
| 405 | 405 |
| 406 TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) { | 406 TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) { |
| 407 TaskQueueSelectorForTest selector; | 407 TaskQueueSelectorForTest selector; |
| 408 MockObserver mock_observer; | 408 MockObserver mock_observer; |
| 409 selector.SetTaskQueueSelectorObserver(&mock_observer); | 409 selector.SetTaskQueueSelectorObserver(&mock_observer); |
| 410 | 410 |
| 411 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); | 411 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(1); |
| 412 | 412 |
| 413 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); | 413 scoped_refptr<TaskQueueImpl> task_queue(NewTaskQueueWithBlockReporting()); |
| 414 selector.AddQueue(task_queue.get()); | 414 selector.AddQueue(task_queue.get()); |
| 415 std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = | 415 std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = |
| 416 task_queue->CreateQueueEnabledVoter(); | 416 task_queue->CreateQueueEnabledVoter(); |
| 417 | 417 |
| 418 voter->SetQueueEnabled(false); | 418 voter->SetQueueEnabled(false); |
| 419 selector.DisableQueue(task_queue.get()); | 419 selector.DisableQueue(task_queue.get()); |
| 420 | 420 |
| 421 TaskQueueImpl::Task task(FROM_HERE, test_closure_, base::TimeTicks(), 0, | 421 TaskQueueImpl::Task task(FROM_HERE, test_closure_, {base::TimeTicks(), 0}, |
| 422 true); | 422 true); |
| 423 task.set_enqueue_order(0); | |
| 424 task_queue->immediate_work_queue()->Push(std::move(task)); | 423 task_queue->immediate_work_queue()->Push(std::move(task)); |
| 425 | 424 |
| 426 WorkQueue* chosen_work_queue; | 425 WorkQueue* chosen_work_queue; |
| 427 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); | 426 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); |
| 428 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); | 427 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); |
| 429 | 428 |
| 430 voter.reset(); | 429 voter.reset(); |
| 431 selector.EnableQueue(task_queue.get()); | 430 selector.EnableQueue(task_queue.get()); |
| 432 task_queue->UnregisterTaskQueue(); | 431 task_queue->UnregisterTaskQueue(); |
| 433 selector.RemoveQueue(task_queue.get()); | 432 selector.RemoveQueue(task_queue.get()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 447 std::unique_ptr<TaskQueue::QueueEnabledVoter> voter2 = | 446 std::unique_ptr<TaskQueue::QueueEnabledVoter> voter2 = |
| 448 task_queue2->CreateQueueEnabledVoter(); | 447 task_queue2->CreateQueueEnabledVoter(); |
| 449 | 448 |
| 450 voter->SetQueueEnabled(false); | 449 voter->SetQueueEnabled(false); |
| 451 voter2->SetQueueEnabled(false); | 450 voter2->SetQueueEnabled(false); |
| 452 selector.DisableQueue(task_queue.get()); | 451 selector.DisableQueue(task_queue.get()); |
| 453 selector.DisableQueue(task_queue2.get()); | 452 selector.DisableQueue(task_queue2.get()); |
| 454 | 453 |
| 455 selector.SetQueuePriority(task_queue2.get(), TaskQueue::CONTROL_PRIORITY); | 454 selector.SetQueuePriority(task_queue2.get(), TaskQueue::CONTROL_PRIORITY); |
| 456 | 455 |
| 457 TaskQueueImpl::Task task1(FROM_HERE, test_closure_, base::TimeTicks(), 0, | 456 TaskQueueImpl::Task task1(FROM_HERE, test_closure_, {base::TimeTicks(), 0}, |
| 458 true); | 457 true); |
| 459 TaskQueueImpl::Task task2(FROM_HERE, test_closure_, base::TimeTicks(), 1, | 458 TaskQueueImpl::Task task2(FROM_HERE, test_closure_, {base::TimeTicks(), 1}, |
| 460 true); | 459 true); |
| 461 task1.set_enqueue_order(0); | |
| 462 task2.set_enqueue_order(1); | |
| 463 task_queue->immediate_work_queue()->Push(std::move(task1)); | 460 task_queue->immediate_work_queue()->Push(std::move(task1)); |
| 464 task_queue2->immediate_work_queue()->Push(std::move(task2)); | 461 task_queue2->immediate_work_queue()->Push(std::move(task2)); |
| 465 | 462 |
| 466 // Should still only see one call to OnTriedToSelectBlockedWorkQueue. | 463 // Should still only see one call to OnTriedToSelectBlockedWorkQueue. |
| 467 WorkQueue* chosen_work_queue; | 464 WorkQueue* chosen_work_queue; |
| 468 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); | 465 EXPECT_CALL(mock_observer, OnTriedToSelectBlockedWorkQueue(_)).Times(1); |
| 469 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); | 466 EXPECT_FALSE(selector.SelectWorkQueueToService(&chosen_work_queue)); |
| 470 testing::Mock::VerifyAndClearExpectations(&mock_observer); | 467 testing::Mock::VerifyAndClearExpectations(&mock_observer); |
| 471 | 468 |
| 472 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2); | 469 EXPECT_CALL(mock_observer, OnTaskQueueEnabled(_)).Times(2); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 501 {1, 2, 2, "delayed", true}, {1, 2, 3, "immediate", false}, | 498 {1, 2, 2, "delayed", true}, {1, 2, 3, "immediate", false}, |
| 502 {1, 2, 4, "immediate", false}, {2, 1, 4, "immediate", false}, | 499 {1, 2, 4, "immediate", false}, {2, 1, 4, "immediate", false}, |
| 503 {2, 1, 4, "immediate", false}, | 500 {2, 1, 4, "immediate", false}, |
| 504 }; | 501 }; |
| 505 | 502 |
| 506 class ChooseOldestWithPriorityTest | 503 class ChooseOldestWithPriorityTest |
| 507 : public TaskQueueSelectorTest, | 504 : public TaskQueueSelectorTest, |
| 508 public testing::WithParamInterface<ChooseOldestWithPriorityTestParam> {}; | 505 public testing::WithParamInterface<ChooseOldestWithPriorityTestParam> {}; |
| 509 | 506 |
| 510 TEST_P(ChooseOldestWithPriorityTest, RoundRobinTest) { | 507 TEST_P(ChooseOldestWithPriorityTest, RoundRobinTest) { |
| 511 task_queues_[0]->immediate_work_queue()->Push( | 508 task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task( |
| 512 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), | 509 FROM_HERE, test_closure_, |
| 513 GetParam().immediate_task_enqueue_order, true, | 510 {base::TimeTicks(), GetParam().immediate_task_enqueue_order}, true)); |
| 514 GetParam().immediate_task_enqueue_order)); | |
| 515 | 511 |
| 516 task_queues_[0]->delayed_work_queue()->Push( | 512 task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task( |
| 517 TaskQueueImpl::Task(FROM_HERE, test_closure_, base::TimeTicks(), | 513 FROM_HERE, test_closure_, |
| 518 GetParam().delayed_task_enqueue_order, true, | 514 {base::TimeTicks(), GetParam().delayed_task_enqueue_order}, true)); |
| 519 GetParam().delayed_task_enqueue_order)); | |
| 520 | 515 |
| 521 selector_.SetImmediateStarvationCountForTest( | 516 selector_.SetImmediateStarvationCountForTest( |
| 522 GetParam().immediate_starvation_count); | 517 GetParam().immediate_starvation_count); |
| 523 | 518 |
| 524 WorkQueue* chosen_work_queue = nullptr; | 519 WorkQueue* chosen_work_queue = nullptr; |
| 525 bool chose_delayed_over_immediate = false; | 520 bool chose_delayed_over_immediate = false; |
| 526 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( | 521 EXPECT_TRUE(enabled_selector()->ChooseOldestWithPriority( |
| 527 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, | 522 TaskQueue::NORMAL_PRIORITY, &chose_delayed_over_immediate, |
| 528 &chosen_work_queue)); | 523 &chosen_work_queue)); |
| 529 EXPECT_EQ(chosen_work_queue->task_queue(), task_queues_[0].get()); | 524 EXPECT_EQ(chosen_work_queue->task_queue(), task_queues_[0].get()); |
| 530 EXPECT_STREQ(chosen_work_queue->GetName(), | 525 EXPECT_STREQ(chosen_work_queue->GetName(), |
| 531 GetParam().expected_work_queue_name); | 526 GetParam().expected_work_queue_name); |
| 532 EXPECT_EQ(chose_delayed_over_immediate, | 527 EXPECT_EQ(chose_delayed_over_immediate, |
| 533 GetParam().expected_did_starve_immediate_queue); | 528 GetParam().expected_did_starve_immediate_queue); |
| 534 } | 529 } |
| 535 | 530 |
| 536 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, | 531 INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, |
| 537 ChooseOldestWithPriorityTest, | 532 ChooseOldestWithPriorityTest, |
| 538 testing::ValuesIn(kChooseOldestWithPriorityTestCases)); | 533 testing::ValuesIn(kChooseOldestWithPriorityTestCases)); |
| 539 | 534 |
| 540 } // namespace internal | 535 } // namespace internal |
| 541 } // namespace scheduler | 536 } // namespace scheduler |
| 542 } // namespace blink | 537 } // namespace blink |
| OLD | NEW |