Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/renderer/scheduler/task_queue_manager.h" | 5 #include "content/renderer/scheduler/task_queue_manager.h" |
| 6 | 6 |
| 7 #include "base/test/test_simple_task_runner.h" | 7 #include "base/test/test_simple_task_runner.h" |
| 8 #include "base/threading/thread.h" | 8 #include "base/threading/thread.h" |
| 9 #include "cc/test/test_now_source.h" | 9 #include "cc/test/test_now_source.h" |
| 10 #include "content/renderer/scheduler/task_queue_selector.h" | 10 #include "content/renderer/scheduler/task_queue_selector.h" |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 thread.Start(); | 450 thread.Start(); |
| 451 thread.message_loop()->PostTask( | 451 thread.message_loop()->PostTask( |
| 452 FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order)); | 452 FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order)); |
| 453 thread.Stop(); | 453 thread.Stop(); |
| 454 | 454 |
| 455 selector_->AppendQueueToService(0); | 455 selector_->AppendQueueToService(0); |
| 456 message_loop_->RunUntilIdle(); | 456 message_loop_->RunUntilIdle(); |
| 457 EXPECT_THAT(run_order, ElementsAre(1)); | 457 EXPECT_THAT(run_order, ElementsAre(1)); |
| 458 } | 458 } |
| 459 | 459 |
| 460 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner) { | 460 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, |
| 461 int* run_count) { | |
| 462 (*run_count)++; | |
| 461 runner->PostTask( | 463 runner->PostTask( |
| 462 FROM_HERE, Bind(&RePostingTestTask, base::Unretained(runner.get()))); | 464 FROM_HERE, |
| 465 Bind(&RePostingTestTask, base::Unretained(runner.get()), run_count)); | |
| 463 } | 466 } |
| 464 | 467 |
| 465 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { | 468 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { |
| 466 Initialize(1u); | 469 Initialize(1u); |
| 467 | |
| 468 scoped_refptr<base::SingleThreadTaskRunner> runner = | 470 scoped_refptr<base::SingleThreadTaskRunner> runner = |
| 469 manager_->TaskRunnerForQueue(0); | 471 manager_->TaskRunnerForQueue(0); |
| 470 | 472 |
| 471 runner->PostTask(FROM_HERE, base::Bind(&RePostingTestTask, runner)); | 473 int run_count = 0; |
| 474 runner->PostTask(FROM_HERE, | |
| 475 base::Bind(&RePostingTestTask, runner, &run_count)); | |
| 472 | 476 |
| 473 selector_->AppendQueueToService(0); | 477 selector_->AppendQueueToService(0); |
| 474 selector_->AppendQueueToService(0); | 478 selector_->AppendQueueToService(0); |
| 475 selector_->AppendQueueToService(0); | 479 selector_->AppendQueueToService(0); |
| 476 | 480 |
| 477 test_task_runner_->RunPendingTasks(); | 481 test_task_runner_->RunPendingTasks(); |
| 478 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there | 482 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there |
| 479 // will be two tasks here. | 483 // will be two tasks here. |
| 480 EXPECT_EQ(1u, test_task_runner_->GetPendingTasks().size()); | 484 EXPECT_EQ(1u, test_task_runner_->GetPendingTasks().size()); |
| 485 EXPECT_EQ(1, run_count); | |
|
Sami
2015/03/02 12:28:56
Not sure why you made this more strict? Seems like
rmcilroy
2015/03/02 15:34:51
I added the run_count arg to RePostingTestTask for
Sami
2015/03/02 15:55:58
Ah, makes sense, thanks.
rmcilroy
2015/03/02 16:47:52
Acknowledged.
| |
| 481 } | 486 } |
| 482 | 487 |
| 483 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { | 488 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { |
| 484 InitializeWithRealMessageLoop(1u); | 489 InitializeWithRealMessageLoop(1u); |
| 485 | 490 |
| 486 selector_->AppendQueueToService(0); | 491 selector_->AppendQueueToService(0); |
| 487 selector_->AppendQueueToService(0); | 492 selector_->AppendQueueToService(0); |
| 488 selector_->AppendQueueToService(0); | 493 selector_->AppendQueueToService(0); |
| 489 selector_->AppendQueueToService(0); | 494 selector_->AppendQueueToService(0); |
| 490 | 495 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 // the work batch is interrupted by the pending delayed task. | 581 // the work batch is interrupted by the pending delayed task. |
| 577 EXPECT_EQ(test_task_runner_->GetPendingTasks().size(), 2u); | 582 EXPECT_EQ(test_task_runner_->GetPendingTasks().size(), 2u); |
| 578 test_task_runner_->RunPendingTasks(); | 583 test_task_runner_->RunPendingTasks(); |
| 579 EXPECT_THAT(run_order, ElementsAre(2)); | 584 EXPECT_THAT(run_order, ElementsAre(2)); |
| 580 | 585 |
| 581 // Running all remaining tasks should execute both pending tasks. | 586 // Running all remaining tasks should execute both pending tasks. |
| 582 test_task_runner_->RunUntilIdle(); | 587 test_task_runner_->RunUntilIdle(); |
| 583 EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); | 588 EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); |
| 584 } | 589 } |
| 585 | 590 |
| 586 TEST_F(TaskQueueManagerTest, AutoPumpOnWakeup) { | 591 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) { |
| 587 Initialize(2u); | 592 Initialize(2u); |
| 588 EXPECT_EQ(2u, selector_->work_queues().size()); | 593 EXPECT_EQ(2u, selector_->work_queues().size()); |
| 589 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | 594 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); |
| 590 | 595 |
| 591 std::vector<int> run_order; | 596 std::vector<int> run_order; |
| 592 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | 597 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { |
| 593 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | 598 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; |
| 594 | 599 |
| 595 selector_->AppendQueueToService(1); | 600 selector_->AppendQueueToService(1); |
| 596 selector_->AppendQueueToService(0); | 601 selector_->AppendQueueToService(0); |
| 597 selector_->AppendQueueToService(0); | 602 selector_->AppendQueueToService(0); |
| 598 | 603 |
| 599 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | 604 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); |
| 600 test_task_runner_->RunUntilIdle(); | 605 test_task_runner_->RunUntilIdle(); |
| 601 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | 606 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. |
| 602 | 607 |
| 603 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | 608 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); |
| 604 test_task_runner_->RunUntilIdle(); | 609 test_task_runner_->RunUntilIdle(); |
| 605 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM. | 610 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM. |
| 606 | 611 |
| 607 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | 612 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); |
| 608 test_task_runner_->RunUntilIdle(); | 613 test_task_runner_->RunUntilIdle(); |
| 609 // Executing a task on an auto pumped queue should wake the TQM. | 614 // Executing a task on an auto pumped queue should wake the TQM. |
| 610 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | 615 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); |
| 611 } | 616 } |
| 612 | 617 |
| 613 TEST_F(TaskQueueManagerTest, AutoPumpOnWakeupWhenAlreadyAwake) { | 618 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) { |
| 614 Initialize(2u); | 619 Initialize(2u); |
| 615 EXPECT_EQ(2u, selector_->work_queues().size()); | 620 EXPECT_EQ(2u, selector_->work_queues().size()); |
| 616 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | 621 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); |
| 617 | 622 |
| 618 std::vector<int> run_order; | 623 std::vector<int> run_order; |
| 619 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | 624 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { |
| 620 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | 625 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; |
| 621 | 626 |
| 622 selector_->AppendQueueToService(1); | 627 selector_->AppendQueueToService(1); |
| 623 selector_->AppendQueueToService(0); | 628 selector_->AppendQueueToService(0); |
| 624 | 629 |
| 625 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | 630 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); |
| 626 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | 631 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); |
| 627 test_task_runner_->RunUntilIdle(); | 632 test_task_runner_->RunUntilIdle(); |
| 628 EXPECT_THAT(run_order, ElementsAre(1, 2)); // TQM was already awake. | 633 EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake. |
| 629 } | 634 } |
| 630 | 635 |
| 631 TEST_F(TaskQueueManagerTest, AutoPumpOnWakeupTriggeredByManuallyPumpedQueue) { | 636 TEST_F(TaskQueueManagerTest, |
| 637 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) { | |
| 632 Initialize(2u); | 638 Initialize(2u); |
| 633 EXPECT_EQ(2u, selector_->work_queues().size()); | 639 EXPECT_EQ(2u, selector_->work_queues().size()); |
| 634 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | 640 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); |
| 635 manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL); | 641 manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL); |
| 636 | 642 |
| 637 std::vector<int> run_order; | 643 std::vector<int> run_order; |
| 638 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | 644 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { |
| 639 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | 645 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; |
| 640 | 646 |
| 641 selector_->AppendQueueToService(1); | 647 selector_->AppendQueueToService(1); |
| 642 selector_->AppendQueueToService(0); | 648 selector_->AppendQueueToService(0); |
| 643 | 649 |
| 644 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | 650 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); |
| 645 test_task_runner_->RunUntilIdle(); | 651 test_task_runner_->RunUntilIdle(); |
| 646 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | 652 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. |
| 647 | 653 |
| 648 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | 654 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); |
| 649 test_task_runner_->RunUntilIdle(); | 655 test_task_runner_->RunUntilIdle(); |
| 650 // This still shouldn't wake TQM as manual queue was not pumped. | 656 // This still shouldn't wake TQM as manual queue was not pumped. |
| 651 EXPECT_TRUE(run_order.empty()); | 657 EXPECT_TRUE(run_order.empty()); |
| 652 | 658 |
| 653 manager_->PumpQueue(1); | 659 manager_->PumpQueue(1); |
| 654 test_task_runner_->RunUntilIdle(); | 660 test_task_runner_->RunUntilIdle(); |
| 655 // Executing a task on an auto pumped queue should wake the TQM. | 661 // Executing a task on an auto pumped queue should wake the TQM. |
| 656 EXPECT_THAT(run_order, ElementsAre(2, 1)); | 662 EXPECT_THAT(run_order, ElementsAre(2, 1)); |
| 657 } | 663 } |
| 658 | 664 |
| 665 void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
| 666 base::Closure task) { | |
| 667 task_runner->PostTask(FROM_HERE, task); | |
| 668 } | |
| 669 | |
| 670 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) { | |
| 671 Initialize(2u); | |
| 672 EXPECT_EQ(2u, selector_->work_queues().size()); | |
|
Sami
2015/03/02 12:28:56
nit: These EXPECT_EQs here are a bit redundant. We
rmcilroy
2015/03/02 15:34:51
Done.
| |
| 673 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 674 | |
| 675 std::vector<int> run_order; | |
| 676 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 677 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 678 | |
| 679 selector_->AppendQueueToService(1); | |
| 680 selector_->AppendQueueToService(1); | |
| 681 selector_->AppendQueueToService(0); | |
| 682 | |
| 683 // Check that a task which posts a task to an auto pump after wakeup queue | |
| 684 // doesn't cause the queue to wake up. | |
| 685 base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order); | |
| 686 runners[1]->PostTask( | |
| 687 FROM_HERE, | |
| 688 base::Bind(&TestPostingTask, runners[0], after_wakeup_task)); | |
| 689 test_task_runner_->RunUntilIdle(); | |
| 690 EXPECT_TRUE(run_order.empty()); | |
| 691 | |
| 692 // Wake up the queue. | |
| 693 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
| 694 test_task_runner_->RunUntilIdle(); | |
| 695 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
| 696 } | |
| 697 | |
| 698 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) { | |
| 699 Initialize(2u); | |
| 700 EXPECT_EQ(2u, selector_->work_queues().size()); | |
| 701 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 702 | |
| 703 std::vector<int> run_order; | |
| 704 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 705 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 706 | |
| 707 selector_->AppendQueueToService(1); | |
| 708 selector_->AppendQueueToService(1); | |
| 709 selector_->AppendQueueToService(1); | |
| 710 selector_->AppendQueueToService(0); | |
| 711 selector_->AppendQueueToService(0); | |
| 712 | |
| 713 // Check that a task which posts a task to an auto pump after wakeup queue | |
| 714 // doesn't cause the queue to wake up. | |
| 715 base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order); | |
| 716 base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order); | |
| 717 runners[1]->PostTask( | |
| 718 FROM_HERE, | |
| 719 base::Bind(&TestPostingTask, runners[0], after_wakeup_task_1)); | |
| 720 runners[1]->PostTask( | |
| 721 FROM_HERE, | |
| 722 base::Bind(&TestPostingTask, runners[0], after_wakeup_task_2)); | |
| 723 test_task_runner_->RunUntilIdle(); | |
| 724 EXPECT_TRUE(run_order.empty()); | |
| 725 | |
| 726 // Wake up the queue. | |
| 727 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
| 728 test_task_runner_->RunUntilIdle(); | |
| 729 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
| 730 } | |
| 731 | |
| 732 void NullTestTask() { | |
| 733 } | |
| 734 | |
| 735 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) { | |
| 736 Initialize(2u); | |
| 737 EXPECT_EQ(2u, selector_->work_queues().size()); | |
| 738 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
| 739 | |
| 740 int run_count = 0; | |
| 741 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
| 742 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
| 743 | |
| 744 selector_->AppendQueueToService(1); | |
| 745 selector_->AppendQueueToService(0); | |
| 746 selector_->AppendQueueToService(0); | |
| 747 // Append extra service queue '0' entries to the selector otherwise test will | |
| 748 // finish even if the RePostingTestTask woke each other up. | |
| 749 selector_->AppendQueueToService(0); | |
| 750 selector_->AppendQueueToService(0); | |
| 751 | |
| 752 // Check that if multiple task reposts themselves onto a auto pump after | |
|
Sami
2015/03/02 12:28:56
s/a/an/
rmcilroy
2015/03/02 15:34:51
Done.
| |
| 753 // wakeup queue they don't wake each other and eventually stops running when | |
| 754 // no other tasks execute | |
| 755 runners[0]->PostTask(FROM_HERE, | |
| 756 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
| 757 runners[0]->PostTask(FROM_HERE, | |
| 758 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
| 759 runners[1]->PostTask(FROM_HERE, base::Bind(&NullTestTask)); | |
| 760 test_task_runner_->RunUntilIdle(); | |
| 761 // The reposting tasks posted to the after wakeup queue shouldn't have woken | |
| 762 // each other up. | |
| 763 EXPECT_EQ(2, run_count); | |
| 764 } | |
| 765 | |
| 659 class MockTaskObserver : public base::MessageLoop::TaskObserver { | 766 class MockTaskObserver : public base::MessageLoop::TaskObserver { |
| 660 public: | 767 public: |
| 661 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); | 768 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); |
| 662 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); | 769 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); |
| 663 }; | 770 }; |
| 664 | 771 |
| 665 TEST_F(TaskQueueManagerTest, TaskObserverAdding) { | 772 TEST_F(TaskQueueManagerTest, TaskObserverAdding) { |
| 666 InitializeWithRealMessageLoop(1u); | 773 InitializeWithRealMessageLoop(1u); |
| 667 MockTaskObserver observer; | 774 MockTaskObserver observer; |
| 668 | 775 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 725 selector_->AppendQueueToService(0); | 832 selector_->AppendQueueToService(0); |
| 726 | 833 |
| 727 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | 834 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); |
| 728 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | 835 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); |
| 729 message_loop_->RunUntilIdle(); | 836 message_loop_->RunUntilIdle(); |
| 730 } | 837 } |
| 731 | 838 |
| 732 } // namespace | 839 } // namespace |
| 733 } // namespace content | 840 } // namespace content |
| 734 | 841 |
| OLD | NEW |