| 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 |