Chromium Code Reviews| 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 time_zero_ = clock_->NowTicks(); | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
I think start_time_ would be a better name.
altimin
2017/04/25 13:22:35
Done.
| |
| 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 Milliseconds(int milliseconds) { | |
|
alex clarke (OOO till 29th)
2017/04/21 09:14:19
I'd prefer if this and the function below had an
altimin
2017/04/25 13:22:35
Done.
| |
| 50 return time_zero_ + base::TimeDelta::FromMilliseconds(milliseconds); | |
| 51 } | |
| 52 | |
| 53 base::TimeTicks Seconds(int seconds) { | |
| 54 return time_zero_ + 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 time_zero_; | |
| 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 base::TimeTicks time_zero = clock_->NowTicks(); |
| 63 | 73 |
| 64 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); | 74 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); |
| 65 | 75 |
| 66 EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero)); | 76 EXPECT_TRUE(pool->CanRunTasksAt(time_zero)); |
| 67 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime()); | 77 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime(time_zero)); |
| 68 | 78 |
| 69 // Run an expensive task and make sure that we're throttled. | 79 // Run an expensive task and make sure that we're throttled. |
| 70 pool->RecordTaskRunTime(time_zero, | 80 pool->RecordTaskRunTime(nullptr, time_zero, |
| 71 time_zero + base::TimeDelta::FromMilliseconds(100)); | 81 time_zero + base::TimeDelta::FromMilliseconds(100)); |
| 72 | 82 |
| 73 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 83 EXPECT_FALSE( |
| 74 time_zero + base::TimeDelta::FromMilliseconds(500))); | 84 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(500))); |
| 75 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(1000), | 85 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(1000), |
| 76 pool->GetNextAllowedRunTime()); | 86 pool->GetNextAllowedRunTime(time_zero)); |
| 77 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | 87 EXPECT_TRUE( |
| 78 time_zero + base::TimeDelta::FromMilliseconds(1000))); | 88 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(1000))); |
| 79 | 89 |
| 80 // Run a cheap task and make sure that it doesn't affect anything. | 90 // Run a cheap task and make sure that it doesn't affect anything. |
| 81 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | 91 EXPECT_TRUE( |
| 82 time_zero + base::TimeDelta::FromMilliseconds(2000))); | 92 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(2000))); |
| 83 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(2000), | 93 pool->RecordTaskRunTime(nullptr, |
| 94 time_zero + base::TimeDelta::FromMilliseconds(2000), | |
| 84 time_zero + base::TimeDelta::FromMilliseconds(2020)); | 95 time_zero + base::TimeDelta::FromMilliseconds(2020)); |
| 85 EXPECT_TRUE(pool->HasEnoughBudgetToRun( | 96 EXPECT_TRUE( |
| 86 time_zero + base::TimeDelta::FromMilliseconds(2020))); | 97 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(2020))); |
| 87 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(2020), | 98 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(2020), |
| 88 pool->GetNextAllowedRunTime()); | 99 pool->GetNextAllowedRunTime(time_zero)); |
| 89 | 100 |
| 90 pool->Close(); | 101 pool->Close(); |
| 91 } | 102 } |
| 92 | 103 |
| 93 TEST_F(BudgetPoolTest, CPUTimeBudgetPoolMinBudgetLevelToRun) { | 104 TEST_F(BudgetPoolTest, CPUTimeBudgetPoolMinBudgetLevelToRun) { |
| 94 CPUTimeBudgetPool* pool = | 105 CPUTimeBudgetPool* pool = |
| 95 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); | 106 task_queue_throttler_->CreateCPUTimeBudgetPool("test"); |
| 96 | 107 |
| 97 base::TimeTicks time_zero = clock_->NowTicks(); | 108 base::TimeTicks time_zero = clock_->NowTicks(); |
| 98 | 109 |
| 99 pool->SetMinBudgetLevelToRun(time_zero, | 110 pool->SetMinBudgetLevelToRun(time_zero, |
| 100 base::TimeDelta::FromMilliseconds(10)); | 111 base::TimeDelta::FromMilliseconds(10)); |
| 101 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); | 112 pool->SetTimeBudgetRecoveryRate(time_zero, 0.1); |
| 102 | 113 |
| 103 EXPECT_TRUE(pool->HasEnoughBudgetToRun(time_zero)); | 114 EXPECT_TRUE(pool->CanRunTasksAt(time_zero)); |
| 104 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime()); | 115 EXPECT_EQ(time_zero, pool->GetNextAllowedRunTime(time_zero)); |
| 105 | 116 |
| 106 pool->RecordTaskRunTime(time_zero, | 117 pool->RecordTaskRunTime(nullptr, time_zero, |
| 107 time_zero + base::TimeDelta::FromMilliseconds(10)); | 118 time_zero + base::TimeDelta::FromMilliseconds(10)); |
| 108 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 119 EXPECT_FALSE( |
| 109 time_zero + base::TimeDelta::FromMilliseconds(15))); | 120 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(15))); |
| 110 EXPECT_FALSE(pool->HasEnoughBudgetToRun( | 121 EXPECT_FALSE( |
| 111 time_zero + base::TimeDelta::FromMilliseconds(150))); | 122 pool->CanRunTasksAt(time_zero + base::TimeDelta::FromMilliseconds(150))); |
| 112 // We need to wait extra 100ms to get budget of 10ms. | 123 // We need to wait extra 100ms to get budget of 10ms. |
| 113 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(200), | 124 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(200), |
| 114 pool->GetNextAllowedRunTime()); | 125 pool->GetNextAllowedRunTime(time_zero)); |
| 115 | 126 |
| 116 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(200), | 127 pool->RecordTaskRunTime(nullptr, |
| 128 time_zero + base::TimeDelta::FromMilliseconds(200), | |
| 117 time_zero + base::TimeDelta::FromMilliseconds(205)); | 129 time_zero + base::TimeDelta::FromMilliseconds(205)); |
| 118 // We can run when budget is non-negative even when it less than 10ms. | 130 // We can run when budget is non-negative even when it less than 10ms. |
| 119 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(205), | 131 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(205), |
| 120 pool->GetNextAllowedRunTime()); | 132 pool->GetNextAllowedRunTime(time_zero)); |
| 121 | 133 |
| 122 pool->RecordTaskRunTime(time_zero + base::TimeDelta::FromMilliseconds(205), | 134 pool->RecordTaskRunTime(nullptr, |
| 135 time_zero + base::TimeDelta::FromMilliseconds(205), | |
| 123 time_zero + base::TimeDelta::FromMilliseconds(215)); | 136 time_zero + base::TimeDelta::FromMilliseconds(215)); |
| 124 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(350), | 137 EXPECT_EQ(time_zero + base::TimeDelta::FromMilliseconds(350), |
| 125 pool->GetNextAllowedRunTime()); | 138 pool->GetNextAllowedRunTime(time_zero)); |
| 139 } | |
| 140 | |
| 141 TEST_F(BudgetPoolTest, WakeupBudgetPool) { | |
| 142 WakeupBudgetPool* pool = | |
| 143 task_queue_throttler_->CreateWakeupBudgetPool("test"); | |
| 144 | |
| 145 scoped_refptr<TaskQueue> queue = | |
| 146 scheduler_->NewTimerTaskRunner(TaskQueue::QueueType::TEST); | |
| 147 | |
| 148 pool->SetWakeupRate(time_zero_, 0.1); | |
| 149 pool->SetWakeupDuration(time_zero_, base::TimeDelta::FromMilliseconds(10)); | |
| 150 | |
| 151 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(0))); | |
| 152 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(5))); | |
| 153 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(9))); | |
| 154 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(10))); | |
| 155 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(11))); | |
| 156 | |
| 157 // GetNextAllowedRunTime should return the desired time when in the | |
| 158 // wakeup window and return the next wakeup otherwise. | |
| 159 EXPECT_EQ(time_zero_, pool->GetNextAllowedRunTime(time_zero_)); | |
| 160 EXPECT_EQ(Seconds(10) - base::TimeDelta::FromMicroseconds(1), | |
| 161 pool->GetNextAllowedRunTime(Milliseconds(15))); | |
| 162 | |
| 163 pool->RecordTaskRunTime(queue.get(), Milliseconds(5), Milliseconds(7)); | |
| 164 | |
| 165 // Make sure that nothing changes after a task inside wakeup window. | |
| 166 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(0))); | |
| 167 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(5))); | |
| 168 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(9))); | |
| 169 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(10))); | |
| 170 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(11))); | |
| 171 EXPECT_EQ(time_zero_, pool->GetNextAllowedRunTime(time_zero_)); | |
| 172 EXPECT_EQ(Seconds(10) - base::TimeDelta::FromMicroseconds(1), | |
| 173 pool->GetNextAllowedRunTime(Milliseconds(15))); | |
| 174 | |
| 175 pool->OnWakeup(Milliseconds(12005)); | |
| 176 pool->RecordTaskRunTime(queue.get(), Milliseconds(12005), | |
| 177 Milliseconds(12007)); | |
| 178 | |
| 179 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(12005))); | |
| 180 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(12007))); | |
| 181 EXPECT_TRUE(pool->CanRunTasksAt(Milliseconds(12014))); | |
| 182 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(12015))); | |
| 183 EXPECT_FALSE(pool->CanRunTasksAt(Milliseconds(12016))); | |
| 184 EXPECT_EQ(Milliseconds(22005) - base::TimeDelta::FromMicroseconds(1), | |
| 185 pool->GetNextAllowedRunTime(Seconds(13))); | |
| 126 } | 186 } |
| 127 | 187 |
| 128 } // namespace scheduler | 188 } // namespace scheduler |
| 129 } // namespace blink | 189 } // namespace blink |
| OLD | NEW |