Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(898)

Side by Side Diff: components/scheduler/base/task_queue_manager_unittest.cc

Issue 1507093004: Adopt a less severe anti-starvation policy for immediate tasks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix test flakes Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | components/scheduler/base/task_queue_selector.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "components/scheduler/base/task_queue_manager.h" 5 #include "components/scheduler/base/task_queue_manager.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/run_loop.h" 8 #include "base/run_loop.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/test/simple_test_tick_clock.h" 10 #include "base/test/simple_test_tick_clock.h"
11 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
12 #include "cc/test/ordered_simple_task_runner.h" 12 #include "cc/test/ordered_simple_task_runner.h"
13 #include "components/scheduler/base/real_time_domain.h" 13 #include "components/scheduler/base/real_time_domain.h"
14 #include "components/scheduler/base/task_queue_impl.h" 14 #include "components/scheduler/base/task_queue_impl.h"
15 #include "components/scheduler/base/task_queue_manager_delegate_for_test.h" 15 #include "components/scheduler/base/task_queue_manager_delegate_for_test.h"
16 #include "components/scheduler/base/task_queue_selector.h" 16 #include "components/scheduler/base/task_queue_selector.h"
17 #include "components/scheduler/base/test_always_fail_time_source.h" 17 #include "components/scheduler/base/test_always_fail_time_source.h"
18 #include "components/scheduler/base/test_time_source.h" 18 #include "components/scheduler/base/test_time_source.h"
19 #include "components/scheduler/base/virtual_time_domain.h" 19 #include "components/scheduler/base/virtual_time_domain.h"
20 #include "components/scheduler/base/work_queue.h" 20 #include "components/scheduler/base/work_queue.h"
21 #include "components/scheduler/base/work_queue_sets.h" 21 #include "components/scheduler/base/work_queue_sets.h"
22 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gmock/include/gmock/gmock.h"
23 23
24 using testing::ElementsAre; 24 using testing::ElementsAre;
25 using testing::ElementsAreArray;
25 using testing::_; 26 using testing::_;
26 27
27 namespace scheduler { 28 namespace scheduler {
28 29
29 class MessageLoopTaskRunner : public TaskQueueManagerDelegateForTest { 30 class MessageLoopTaskRunner : public TaskQueueManagerDelegateForTest {
30 public: 31 public:
31 static scoped_refptr<MessageLoopTaskRunner> Create( 32 static scoped_refptr<MessageLoopTaskRunner> Create(
32 scoped_ptr<base::TickClock> tick_clock) { 33 scoped_ptr<base::TickClock> tick_clock) {
33 return make_scoped_refptr(new MessageLoopTaskRunner(tick_clock.Pass())); 34 return make_scoped_refptr(new MessageLoopTaskRunner(tick_clock.Pass()));
34 } 35 }
(...skipping 1045 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 EXPECT_FALSE(queue1->NeedsPumping()); 1081 EXPECT_FALSE(queue1->NeedsPumping());
1081 } 1082 }
1082 1083
1083 void ExpensiveTestTask(int value, 1084 void ExpensiveTestTask(int value,
1084 base::SimpleTestTickClock* clock, 1085 base::SimpleTestTickClock* clock,
1085 std::vector<int>* out_result) { 1086 std::vector<int>* out_result) {
1086 out_result->push_back(value); 1087 out_result->push_back(value);
1087 clock->Advance(base::TimeDelta::FromMilliseconds(1)); 1088 clock->Advance(base::TimeDelta::FromMilliseconds(1));
1088 } 1089 }
1089 1090
1090 TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskRoundRobbin) { 1091 TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskInterleaving) {
1091 Initialize(1u); 1092 Initialize(1u);
1092 1093
1093 std::vector<int> run_order; 1094 std::vector<int> run_order;
1094 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); 1095 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
1095 runners_[0]->PostDelayedTask( 1096 for (int i = 10; i < 19; i++) {
1096 FROM_HERE, base::Bind(&ExpensiveTestTask, 10, now_src_.get(), &run_order), 1097 runners_[0]->PostDelayedTask(
1097 delay); 1098 FROM_HERE,
1098 runners_[0]->PostDelayedTask( 1099 base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order),
1099 FROM_HERE, base::Bind(&ExpensiveTestTask, 11, now_src_.get(), &run_order), 1100 delay);
1100 delay); 1101 }
1101 runners_[0]->PostDelayedTask(
1102 FROM_HERE, base::Bind(&ExpensiveTestTask, 12, now_src_.get(), &run_order),
1103 delay);
1104 runners_[0]->PostDelayedTask(
1105 FROM_HERE, base::Bind(&ExpensiveTestTask, 13, now_src_.get(), &run_order),
1106 delay);
1107 1102
1108 test_task_runner_->RunForPeriod(delay); 1103 test_task_runner_->RunForPeriod(delay);
1109 1104
1110 runners_[0]->PostTask( 1105 for (int i = 0; i < 9; i++) {
1111 FROM_HERE, base::Bind(&ExpensiveTestTask, 0, now_src_.get(), &run_order)); 1106 runners_[0]->PostTask(
1112 runners_[0]->PostTask( 1107 FROM_HERE,
1113 FROM_HERE, base::Bind(&ExpensiveTestTask, 1, now_src_.get(), &run_order)); 1108 base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order));
1114 runners_[0]->PostTask( 1109 }
1115 FROM_HERE, base::Bind(&ExpensiveTestTask, 2, now_src_.get(), &run_order));
1116 runners_[0]->PostTask(
1117 FROM_HERE, base::Bind(&ExpensiveTestTask, 3, now_src_.get(), &run_order));
1118 1110
1119 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); 1111 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1120 test_task_runner_->RunUntilIdle(); 1112 test_task_runner_->RunUntilIdle();
1121 1113
1122 EXPECT_THAT(run_order, ElementsAre(10, 0, 11, 1, 12, 2, 13, 3)); 1114 // Delayed tasks are not allowed to starve out immediate work which is why
1115 // some of the immediate tasks run out of order.
1116 int expected_run_order[] = {
1117 10, 11, 12, 13, 0, 14, 15, 16, 1, 17, 18, 2, 3, 4, 5, 6, 7, 8
1118 };
1119 EXPECT_THAT(run_order, ElementsAreArray(expected_run_order));
1123 } 1120 }
1124 1121
1125 TEST_F(TaskQueueManagerTest, 1122 TEST_F(TaskQueueManagerTest,
1126 DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) { 1123 DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) {
1127 Initialize(1u); 1124 Initialize(1u);
1128 1125
1129 std::vector<int> run_order; 1126 std::vector<int> run_order;
1130 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); 1127 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
1131 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); 1128 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1132 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); 1129 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 base::Callback<bool()> should_exit_; 1583 base::Callback<bool()> should_exit_;
1587 base::SimpleTestTickClock* now_src_; 1584 base::SimpleTestTickClock* now_src_;
1588 }; 1585 };
1589 1586
1590 bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) { 1587 bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) {
1591 return quadratic_task->count() == 1000 || linear_task->count() == 1000; 1588 return quadratic_task->count() == 1000 || linear_task->count() == 1000;
1592 } 1589 }
1593 1590
1594 } // namespace 1591 } // namespace
1595 1592
1596 TEST_F(TaskQueueManagerTest, DelayedTasksDontStarveNonDelayedWork_SameQueue) { 1593 TEST_F(TaskQueueManagerTest,
1594 DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) {
1597 Initialize(1u); 1595 Initialize(1u);
1598 1596
1599 QuadraticTask quadratic_delayed_task( 1597 QuadraticTask quadratic_delayed_task(
1600 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); 1598 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1601 LinearTask linear_immediate_task(runners_[0], base::TimeDelta(), 1599 LinearTask linear_immediate_task(runners_[0], base::TimeDelta(),
1602 now_src_.get()); 1600 now_src_.get());
1603 base::Callback<bool()> should_exit = 1601 base::Callback<bool()> should_exit =
1604 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task); 1602 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
1605 quadratic_delayed_task.SetShouldExit(should_exit); 1603 quadratic_delayed_task.SetShouldExit(should_exit);
1606 linear_immediate_task.SetShouldExit(should_exit); 1604 linear_immediate_task.SetShouldExit(should_exit);
1607 1605
1608 quadratic_delayed_task.Run(); 1606 quadratic_delayed_task.Run();
1609 linear_immediate_task.Run(); 1607 linear_immediate_task.Run();
1610 1608
1611 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); 1609 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1612 test_task_runner_->RunUntilIdle(); 1610 test_task_runner_->RunUntilIdle();
1613 1611
1614 double ratio = static_cast<double>(linear_immediate_task.count()) / 1612 double ratio = static_cast<double>(linear_immediate_task.count()) /
1615 static_cast<double>(quadratic_delayed_task.count()); 1613 static_cast<double>(quadratic_delayed_task.count());
1616 1614
1617 EXPECT_GT(ratio, 0.9); 1615 EXPECT_GT(ratio, 0.333);
1618 EXPECT_LT(ratio, 1.1); 1616 EXPECT_LT(ratio, 1.1);
1619 } 1617 }
1620 1618
1621 TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) { 1619 TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
1622 Initialize(1u); 1620 Initialize(1u);
1623 1621
1624 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), 1622 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
1625 now_src_.get()); 1623 now_src_.get());
1626 LinearTask linear_delayed_task( 1624 LinearTask linear_delayed_task(
1627 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); 1625 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
(...skipping 12 matching lines...) Expand all
1640 double ratio = static_cast<double>(linear_delayed_task.count()) / 1638 double ratio = static_cast<double>(linear_delayed_task.count()) /
1641 static_cast<double>(quadratic_immediate_task.count()); 1639 static_cast<double>(quadratic_immediate_task.count());
1642 1640
1643 // This is by design, we want to enforce a strict ordering in task execution 1641 // This is by design, we want to enforce a strict ordering in task execution
1644 // where by delayed tasks can not skip ahead of non-delayed work. 1642 // where by delayed tasks can not skip ahead of non-delayed work.
1645 EXPECT_GT(ratio, 0.0); 1643 EXPECT_GT(ratio, 0.0);
1646 EXPECT_LT(ratio, 0.1); 1644 EXPECT_LT(ratio, 0.1);
1647 } 1645 }
1648 1646
1649 TEST_F(TaskQueueManagerTest, 1647 TEST_F(TaskQueueManagerTest,
1650 DelayedTasksDontStarveNonDelayedWork_DifferentQueue) { 1648 DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) {
1651 Initialize(2u); 1649 Initialize(2u);
1652 1650
1653 QuadraticTask quadratic_delayed_task( 1651 QuadraticTask quadratic_delayed_task(
1654 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get()); 1652 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1655 LinearTask linear_immediate_task(runners_[1], base::TimeDelta(), 1653 LinearTask linear_immediate_task(runners_[1], base::TimeDelta(),
1656 now_src_.get()); 1654 now_src_.get());
1657 base::Callback<bool()> should_exit = 1655 base::Callback<bool()> should_exit =
1658 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task); 1656 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
1659 quadratic_delayed_task.SetShouldExit(should_exit); 1657 quadratic_delayed_task.SetShouldExit(should_exit);
1660 linear_immediate_task.SetShouldExit(should_exit); 1658 linear_immediate_task.SetShouldExit(should_exit);
1661 1659
1662 quadratic_delayed_task.Run(); 1660 quadratic_delayed_task.Run();
1663 linear_immediate_task.Run(); 1661 linear_immediate_task.Run();
1664 1662
1665 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); 1663 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1666 test_task_runner_->RunUntilIdle(); 1664 test_task_runner_->RunUntilIdle();
1667 1665
1668 double ratio = static_cast<double>(linear_immediate_task.count()) / 1666 double ratio = static_cast<double>(linear_immediate_task.count()) /
1669 static_cast<double>(quadratic_delayed_task.count()); 1667 static_cast<double>(quadratic_delayed_task.count());
1670 1668
1671 EXPECT_GT(ratio, 0.9); 1669 EXPECT_GT(ratio, 0.333);
1672 EXPECT_LT(ratio, 1.1); 1670 EXPECT_LT(ratio, 1.1);
1673 } 1671 }
1674 1672
1675 TEST_F(TaskQueueManagerTest, 1673 TEST_F(TaskQueueManagerTest,
1676 ImmediateWorkCanStarveDelayedTasks_DifferentQueue) { 1674 ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
1677 Initialize(2u); 1675 Initialize(2u);
1678 1676
1679 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), 1677 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
1680 now_src_.get()); 1678 now_src_.get());
1681 LinearTask linear_delayed_task( 1679 LinearTask linear_delayed_task(
(...skipping 13 matching lines...) Expand all
1695 double ratio = static_cast<double>(linear_delayed_task.count()) / 1693 double ratio = static_cast<double>(linear_delayed_task.count()) /
1696 static_cast<double>(quadratic_immediate_task.count()); 1694 static_cast<double>(quadratic_immediate_task.count());
1697 1695
1698 // This is by design, we want to enforce a strict ordering in task execution 1696 // This is by design, we want to enforce a strict ordering in task execution
1699 // where by delayed tasks can not skip ahead of non-delayed work. 1697 // where by delayed tasks can not skip ahead of non-delayed work.
1700 EXPECT_GT(ratio, 0.0); 1698 EXPECT_GT(ratio, 0.0);
1701 EXPECT_LT(ratio, 0.1); 1699 EXPECT_LT(ratio, 0.1);
1702 } 1700 }
1703 1701
1704 } // namespace scheduler 1702 } // namespace scheduler
OLDNEW
« no previous file with comments | « no previous file | components/scheduler/base/task_queue_selector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698