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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/budget_pool_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698