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/renderer/task_queue_throttler.h" | 5 #include "platform/scheduler/renderer/task_queue_throttler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... |
31 | 31 |
32 void SetUp() override { | 32 void SetUp() override { |
33 clock_.reset(new base::SimpleTestTickClock()); | 33 clock_.reset(new base::SimpleTestTickClock()); |
34 clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); | 34 clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); |
35 mock_task_runner_ = | 35 mock_task_runner_ = |
36 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(clock_.get(), true)); | 36 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(clock_.get(), true)); |
37 delegate_ = SchedulerTqmDelegateForTest::Create( | 37 delegate_ = SchedulerTqmDelegateForTest::Create( |
38 mock_task_runner_, base::MakeUnique<TestTimeSource>(clock_.get())); | 38 mock_task_runner_, base::MakeUnique<TestTimeSource>(clock_.get())); |
39 scheduler_.reset(new RendererSchedulerImpl(delegate_)); | 39 scheduler_.reset(new RendererSchedulerImpl(delegate_)); |
40 task_queue_throttler_ = scheduler_->task_queue_throttler(); | 40 task_queue_throttler_ = scheduler_->task_queue_throttler(); |
| 41 start_time_ = clock_->NowTicks(); |
41 } | 42 } |
42 | 43 |
43 void TearDown() override { | 44 void TearDown() override { |
44 scheduler_->Shutdown(); | 45 scheduler_->Shutdown(); |
45 scheduler_.reset(); | 46 scheduler_.reset(); |
46 } | 47 } |
47 | 48 |
| 49 base::TimeTicks MillisecondsAfterStart(int milliseconds) { |
| 50 return start_time_ + base::TimeDelta::FromMilliseconds(milliseconds); |
| 51 } |
| 52 |
| 53 base::TimeTicks SecondsAfterStart(int seconds) { |
| 54 return start_time_ + base::TimeDelta::FromSeconds(seconds); |
| 55 } |
| 56 |
48 protected: | 57 protected: |
49 std::unique_ptr<base::SimpleTestTickClock> clock_; | 58 std::unique_ptr<base::SimpleTestTickClock> clock_; |
50 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | 59 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; |
51 scoped_refptr<SchedulerTqmDelegate> delegate_; | 60 scoped_refptr<SchedulerTqmDelegate> delegate_; |
52 std::unique_ptr<RendererSchedulerImpl> scheduler_; | 61 std::unique_ptr<RendererSchedulerImpl> scheduler_; |
53 TaskQueueThrottler* task_queue_throttler_; // NOT OWNED | 62 TaskQueueThrottler* task_queue_throttler_; // NOT OWNED |
| 63 base::TimeTicks start_time_; |
54 | 64 |
55 DISALLOW_COPY_AND_ASSIGN(BudgetPoolTest); | 65 DISALLOW_COPY_AND_ASSIGN(BudgetPoolTest); |
56 }; | 66 }; |
57 | 67 |
58 TEST_F(BudgetPoolTest, CPUTimeBudgetPool) { | 68 TEST_F(BudgetPoolTest, CPUTimeBudgetPool) { |
59 CPUTimeBudgetPool* pool = | 69 CPUTimeBudgetPool* pool = |
60 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); | 70 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); |
61 | 71 |
62 base::TimeTicks time_zero = clock_->NowTicks(); | 72 pool->SetTimeBudgetRecoveryRate(SecondsAfterStart(0), 0.1); |
63 | 73 |
64 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); | 74 EXPECT_TRUE(pool->CanRunTasksAt(SecondsAfterStart(0), false)); |
65 | 75 EXPECT_EQ(SecondsAfterStart(0), |
66 EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero)); | 76 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
67 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime()); | |
68 | 77 |
69 // Run an expensive task and make sure that we're throttled. | 78 // Run an expensive task and make sure that we're throttled. |
70 pool->RecordTaskRunTime(time_zero, | 79 pool->RecordTaskRunTime(nullptr, SecondsAfterStart(0), |
71 time_zero + base::TimeDelta::FromMilliseconds(100)); | 80 MillisecondsAfterStart(100)); |
72 | 81 |
73 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 82 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(500), false)); |
74 time_zero + base::TimeDelta::FromMilliseconds(500))); | 83 EXPECT_EQ(MillisecondsAfterStart(1000), |
75 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(1000), | 84 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
76 pool->GetNextAllowedRunTime()); | 85 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(1000), false)); |
77 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | |
78 time_zero + base::TimeDelta::FromMilliseconds(1000))); | |
79 | 86 |
80 // Run a cheap task and make sure that it doesn't affect anything. | 87 // Run a cheap task and make sure that it doesn't affect anything. |
81 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | 88 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(2000), false)); |
82 time_zero + base::TimeDelta::FromMilliseconds(2000))); | 89 pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(2000), |
83 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(2000), | 90 MillisecondsAfterStart(2020)); |
84 time_zero + base::TimeDelta::FromMilliseconds(2020)); | 91 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(2020), false)); |
85 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | 92 EXPECT_EQ(MillisecondsAfterStart(2020), |
86 time_zero + base::TimeDelta::FromMilliseconds(2020))); | 93 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
87 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(2020), | |
88 pool->GetNextAllowedRunTime()); | |
89 | 94 |
90 pool->Close(); | 95 pool->Close(); |
91 } | 96 } |
92 | 97 |
93 TEST_F(BudgetPoolTest, CPUTimeBudgetPoolMinBudgetLevelToRun) { | 98 TEST_F(BudgetPoolTest, CPUTimeBudgetPoolMinBudgetLevelToRun) { |
94 CPUTimeBudgetPool* pool = | 99 CPUTimeBudgetPool* pool = |
95 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); | 100 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); |
96 | 101 |
97 base::TimeTicks time_zero = clock_->NowTicks(); | 102 pool->SetMinBudgetLevelToRun(SecondsAfterStart(0), |
| 103 base::TimeDelta::FromMilliseconds(10)); |
| 104 pool->SetTimeBudgetRecoveryRate(SecondsAfterStart(0), 0.1); |
98 | 105 |
99 pool->SetMinBudgetLevelToRun(time_zero, | 106 EXPECT_TRUE(pool->CanRunTasksAt(SecondsAfterStart(0), false)); |
100 base::TimeDelta::FromMilliseconds(10)); | 107 EXPECT_EQ(SecondsAfterStart(0), |
101 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); | 108 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
102 | 109 |
103 EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero)); | 110 pool->RecordTaskRunTime(nullptr, SecondsAfterStart(0), |
104 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime()); | 111 MillisecondsAfterStart(10)); |
| 112 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(15), false)); |
| 113 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(150), false)); |
| 114 // We need to wait extra 100ms to get budget of 10ms. |
| 115 EXPECT_EQ(MillisecondsAfterStart(200), |
| 116 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
105 | 117 |
106 pool->RecordTaskRunTime(time_zero, | 118 pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(200), |
107 time_zero + base::TimeDelta::FromMilliseconds(10)); | 119 MillisecondsAfterStart(205)); |
108 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 120 // We can run when budget is non-negative even when it less than 10ms. |
109 time_zero + base::TimeDelta::FromMilliseconds(15))); | 121 EXPECT_EQ(MillisecondsAfterStart(205), |
110 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 122 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
111 time_zero + base::TimeDelta::FromMilliseconds(150))); | |
112 // We need to wait extra 100ms to get budget of 10ms. | |
113 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(200), | |
114 pool->GetNextAllowedRunTime()); | |
115 | 123 |
116 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(200), | 124 pool->RecordTaskRunTime(nullptr, MillisecondsAfterStart(205), |
117 time_zero + base::TimeDelta::FromMilliseconds(205)); | 125 MillisecondsAfterStart(215)); |
118 // We can run when budget is non-negative even when it less than 10ms. | 126 EXPECT_EQ(MillisecondsAfterStart(350), |
119 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(205), | 127 pool->GetNextAllowedRunTime(SecondsAfterStart(0))); |
120 pool->GetNextAllowedRunTime()); | 128 } |
121 | 129 |
122 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(205), | 130 TEST_F(BudgetPoolTest, WakeUpBudgetPool) { |
123 time_zero + base::TimeDelta::FromMilliseconds(215)); | 131 WakeUpBudgetPool* pool = |
124 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(350), | 132 task_queue_throttler_->CreateWakeUpBudgetPool("test"); |
125 pool->GetNextAllowedRunTime()); | 133 |
| 134 scoped_refptr<TaskQueue> queue = |
| 135 scheduler_->NewTimerTaskQueue(TaskQueue::QueueType::TEST); |
| 136 |
| 137 pool->SetWakeUpRate(0.1); |
| 138 pool->SetWakeUpDuration(base::TimeDelta::FromMilliseconds(10)); |
| 139 |
| 140 // Can't run tasks until a wake-up. |
| 141 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false)); |
| 142 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false)); |
| 143 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false)); |
| 144 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false)); |
| 145 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false)); |
| 146 |
| 147 pool->OnWakeUp(MillisecondsAfterStart(0)); |
| 148 |
| 149 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false)); |
| 150 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false)); |
| 151 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false)); |
| 152 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false)); |
| 153 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false)); |
| 154 |
| 155 // GetNextAllowedRunTime should return the desired time when in the |
| 156 // wakeup window and return the next wakeup otherwise. |
| 157 EXPECT_EQ(start_time_, pool->GetNextAllowedRunTime(start_time_)); |
| 158 EXPECT_EQ(SecondsAfterStart(10) - base::TimeDelta::FromMicroseconds(1), |
| 159 pool->GetNextAllowedRunTime(MillisecondsAfterStart(15))); |
| 160 |
| 161 pool->RecordTaskRunTime(queue.get(), MillisecondsAfterStart(5), |
| 162 MillisecondsAfterStart(7)); |
| 163 |
| 164 // Make sure that nothing changes after a task inside wakeup window. |
| 165 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(0), false)); |
| 166 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(5), false)); |
| 167 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(9), false)); |
| 168 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(10), false)); |
| 169 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(11), false)); |
| 170 EXPECT_EQ(start_time_, pool->GetNextAllowedRunTime(start_time_)); |
| 171 EXPECT_EQ(SecondsAfterStart(10) - base::TimeDelta::FromMicroseconds(1), |
| 172 pool->GetNextAllowedRunTime(MillisecondsAfterStart(15))); |
| 173 |
| 174 pool->OnWakeUp(MillisecondsAfterStart(12005)); |
| 175 pool->RecordTaskRunTime(queue.get(), MillisecondsAfterStart(12005), |
| 176 MillisecondsAfterStart(12007)); |
| 177 |
| 178 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12005), false)); |
| 179 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12007), false)); |
| 180 EXPECT_TRUE(pool->CanRunTasksAt(MillisecondsAfterStart(12014), false)); |
| 181 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(12015), false)); |
| 182 EXPECT_FALSE(pool->CanRunTasksAt(MillisecondsAfterStart(12016), false)); |
| 183 EXPECT_EQ( |
| 184 MillisecondsAfterStart(22005) - base::TimeDelta::FromMicroseconds(1), |
| 185 pool->GetNextAllowedRunTime(SecondsAfterStart(13))); |
126 } | 186 } |
127 | 187 |
128 } // namespace scheduler | 188 } // namespace scheduler |
129 } // namespace blink | 189 } // namespace blink |
OLD | NEW |