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

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

Issue 2778743004: [scheduler] Refactor common code into BudgetPool. (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/budget_pool.h" 5 #include "platform/scheduler/renderer/budget_pool.h"
6 6
7 #include <cstdint> 7 #include <cstdint>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 14 matching lines...) Expand all
25 namespace { 25 namespace {
26 26
27 std::string PointerToId(void* pointer) { 27 std::string PointerToId(void* pointer) {
28 return base::StringPrintf( 28 return base::StringPrintf(
29 "0x%" PRIx64, 29 "0x%" PRIx64,
30 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); 30 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
31 } 31 }
32 32
33 } // namespace 33 } // namespace
34 34
35 BudgetPool::BudgetPool(const char* name,
36 BudgetPoolController* budget_pool_controller)
37 : name_(name),
38 budget_pool_controller_(budget_pool_controller),
39 is_enabled_(true) {}
40
35 BudgetPool::~BudgetPool() {} 41 BudgetPool::~BudgetPool() {}
36 42
37 CPUTimeBudgetPool::CPUTimeBudgetPool( 43 const char* BudgetPool::Name() const {
38 const char* name, 44 return name_;
39 BudgetPoolController* budget_pool_controller,
40 base::TimeTicks now)
41 : name_(name),
42 budget_pool_controller_(budget_pool_controller),
43 last_checkpoint_(now),
44 cpu_percentage_(1),
45 is_enabled_(true) {}
46
47 CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
48
49 void CPUTimeBudgetPool::SetMaxBudgetLevel(
50 base::TimeTicks now,
51 base::Optional<base::TimeDelta> max_budget_level) {
52 Advance(now);
53 max_budget_level_ = max_budget_level;
54 EnforceBudgetLevelRestrictions();
55 } 45 }
56 46
57 void CPUTimeBudgetPool::SetMaxThrottlingDelay( 47 void BudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) {
58 base::TimeTicks now,
59 base::Optional<base::TimeDelta> max_throttling_delay) {
60 Advance(now);
61 max_throttling_delay_ = max_throttling_delay;
62 EnforceBudgetLevelRestrictions();
63 }
64
65 void CPUTimeBudgetPool::SetMinBudgetLevelToRun(
66 base::TimeTicks now,
67 base::TimeDelta min_budget_level_to_run) {
68 Advance(now);
69 min_budget_level_to_run_ = min_budget_level_to_run;
70 }
71
72 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now,
73 double cpu_percentage) {
74 Advance(now);
75 cpu_percentage_ = cpu_percentage;
76 EnforceBudgetLevelRestrictions();
77 }
78
79 void CPUTimeBudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) {
80 budget_pool_controller_->AddQueueToBudgetPool(queue, this); 48 budget_pool_controller_->AddQueueToBudgetPool(queue, this);
81 associated_task_queues_.insert(queue); 49 associated_task_queues_.insert(queue);
82 50
83 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue)) 51 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
84 return; 52 return;
85 53
86 budget_pool_controller_->BlockQueue(now, queue); 54 budget_pool_controller_->BlockQueue(now, queue);
87 } 55 }
88 56
89 void CPUTimeBudgetPool::RemoveQueue(base::TimeTicks now, TaskQueue* queue) { 57 void BudgetPool::RemoveQueue(base::TimeTicks now, TaskQueue* queue) {
90 budget_pool_controller_->RemoveQueueFromBudgetPool(queue, this); 58 budget_pool_controller_->RemoveQueueFromBudgetPool(queue, this);
91 associated_task_queues_.erase(queue); 59 associated_task_queues_.erase(queue);
92 60
93 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue)) 61 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
94 return; 62 return;
95 63
96 budget_pool_controller_->UnblockQueue(now, queue); 64 budget_pool_controller_->UnblockQueue(now, queue);
97 } 65 }
98 66
99 void CPUTimeBudgetPool::EnableThrottling(LazyNow* lazy_now) { 67 void BudgetPool::EnableThrottling(LazyNow* lazy_now) {
100 if (is_enabled_) 68 if (is_enabled_)
101 return; 69 return;
102 is_enabled_ = true; 70 is_enabled_ = true;
103 71
104 TRACE_EVENT0("renderer.scheduler", "CPUTimeBudgetPool_EnableThrottling"); 72 TRACE_EVENT0("renderer.scheduler", "BudgetPool_EnableThrottling");
105 73
106 BlockThrottledQueues(lazy_now->Now()); 74 BlockThrottledQueues(lazy_now->Now());
107 } 75 }
108 76
109 void CPUTimeBudgetPool::DisableThrottling(LazyNow* lazy_now) { 77 void BudgetPool::DisableThrottling(LazyNow* lazy_now) {
110 if (!is_enabled_) 78 if (!is_enabled_)
111 return; 79 return;
112 is_enabled_ = false; 80 is_enabled_ = false;
113 81
114 TRACE_EVENT0("renderer.scheduler", "CPUTimeBudgetPool_DisableThrottling"); 82 TRACE_EVENT0("renderer.scheduler", "BudgetPool_DisableThrottling");
115 83
116 for (TaskQueue* queue : associated_task_queues_) { 84 for (TaskQueue* queue : associated_task_queues_) {
117 if (!budget_pool_controller_->IsThrottled(queue)) 85 if (!budget_pool_controller_->IsThrottled(queue))
118 continue; 86 continue;
119 87
120 budget_pool_controller_->UnblockQueue(lazy_now->Now(), queue); 88 budget_pool_controller_->UnblockQueue(lazy_now->Now(), queue);
121 } 89 }
122 90
123 // TODO(altimin): We need to disable TimeBudgetQueues here or they will 91 // TODO(altimin): We need to disable TimeBudgetQueues here or they will
124 // regenerate extra time budget when they are disabled. 92 // regenerate extra time budget when they are disabled.
125 } 93 }
126 94
127 bool CPUTimeBudgetPool::IsThrottlingEnabled() const { 95 bool BudgetPool::IsThrottlingEnabled() const {
128 return is_enabled_; 96 return is_enabled_;
129 } 97 }
130 98
99 void BudgetPool::Close() {
100 DCHECK_EQ(0u, associated_task_queues_.size());
101
102 budget_pool_controller_->UnregisterBudgetPool(this);
103 }
104
105 void BudgetPool::BlockThrottledQueues(base::TimeTicks now) {
106 for (TaskQueue* queue : associated_task_queues_)
107 budget_pool_controller_->BlockQueue(now, queue);
108 }
109
110 CPUTimeBudgetPool::CPUTimeBudgetPool(
111 const char* name,
112 BudgetPoolController* budget_pool_controller,
113 base::TimeTicks now)
114 : BudgetPool(name, budget_pool_controller),
115 last_checkpoint_(now),
116 cpu_percentage_(1) {}
117
118 CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
119
120 void CPUTimeBudgetPool::SetMaxBudgetLevel(
121 base::TimeTicks now,
122 base::Optional<base::TimeDelta> max_budget_level) {
123 Advance(now);
124 max_budget_level_ = max_budget_level;
125 EnforceBudgetLevelRestrictions();
126 }
127
128 void CPUTimeBudgetPool::SetMaxThrottlingDelay(
129 base::TimeTicks now,
130 base::Optional<base::TimeDelta> max_throttling_delay) {
131 Advance(now);
132 max_throttling_delay_ = max_throttling_delay;
133 EnforceBudgetLevelRestrictions();
134 }
135
136 void CPUTimeBudgetPool::SetMinBudgetLevelToRun(
137 base::TimeTicks now,
138 base::TimeDelta min_budget_level_to_run) {
139 Advance(now);
140 min_budget_level_to_run_ = min_budget_level_to_run;
141 }
142
143 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now,
144 double cpu_percentage) {
145 Advance(now);
146 cpu_percentage_ = cpu_percentage;
147 EnforceBudgetLevelRestrictions();
148 }
149
131 void CPUTimeBudgetPool::GrantAdditionalBudget(base::TimeTicks now, 150 void CPUTimeBudgetPool::GrantAdditionalBudget(base::TimeTicks now,
132 base::TimeDelta budget_level) { 151 base::TimeDelta budget_level) {
133 Advance(now); 152 Advance(now);
134 current_budget_level_ += budget_level; 153 current_budget_level_ += budget_level;
135 EnforceBudgetLevelRestrictions(); 154 EnforceBudgetLevelRestrictions();
136 } 155 }
137 156
138 void CPUTimeBudgetPool::SetReportingCallback( 157 void CPUTimeBudgetPool::SetReportingCallback(
139 base::Callback<void(base::TimeDelta)> reporting_callback) { 158 base::Callback<void(base::TimeDelta)> reporting_callback) {
140 reporting_callback_ = reporting_callback; 159 reporting_callback_ = reporting_callback;
141 } 160 }
142 161
143 void CPUTimeBudgetPool::Close() {
144 DCHECK_EQ(0u, associated_task_queues_.size());
145
146 budget_pool_controller_->UnregisterBudgetPool(this);
147 }
148
149 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) { 162 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) {
150 return now >= GetNextAllowedRunTime(); 163 return now >= GetNextAllowedRunTime();
151 } 164 }
152 165
153 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() { 166 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() {
154 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) { 167 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) {
155 return last_checkpoint_; 168 return last_checkpoint_;
156 } else { 169 } else {
157 // Subtract because current_budget is negative. 170 // Subtract because current_budget is negative.
158 return last_checkpoint_ + 171 return last_checkpoint_ +
(...skipping 11 matching lines...) Expand all
170 current_budget_level_ -= (end_time - start_time); 183 current_budget_level_ -= (end_time - start_time);
171 EnforceBudgetLevelRestrictions(); 184 EnforceBudgetLevelRestrictions();
172 185
173 if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 && 186 if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 &&
174 current_budget_level_.InSecondsF() < 0) { 187 current_budget_level_.InSecondsF() < 0) {
175 reporting_callback_.Run(-current_budget_level_ / cpu_percentage_); 188 reporting_callback_.Run(-current_budget_level_ / cpu_percentage_);
176 } 189 }
177 } 190 }
178 } 191 }
179 192
180 const char* CPUTimeBudgetPool::Name() const {
181 return name_;
182 }
183
184 void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state, 193 void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
185 base::TimeTicks now) const { 194 base::TimeTicks now) const {
186 state->BeginDictionary(name_); 195 state->BeginDictionary(name_);
187 196
188 state->SetString("name", name_); 197 state->SetString("name", name_);
189 state->SetDouble("time_budget", cpu_percentage_); 198 state->SetDouble("time_budget", cpu_percentage_);
190 state->SetDouble("time_budget_level_in_seconds", 199 state->SetDouble("time_budget_level_in_seconds",
191 current_budget_level_.InSecondsF()); 200 current_budget_level_.InSecondsF());
192 state->SetDouble("last_checkpoint_seconds_ago", 201 state->SetDouble("last_checkpoint_seconds_ago",
193 (now - last_checkpoint_).InSecondsF()); 202 (now - last_checkpoint_).InSecondsF());
(...skipping 22 matching lines...) Expand all
216 void CPUTimeBudgetPool::Advance(base::TimeTicks now) { 225 void CPUTimeBudgetPool::Advance(base::TimeTicks now) {
217 if (now > last_checkpoint_) { 226 if (now > last_checkpoint_) {
218 if (is_enabled_) { 227 if (is_enabled_) {
219 current_budget_level_ += cpu_percentage_ * (now - last_checkpoint_); 228 current_budget_level_ += cpu_percentage_ * (now - last_checkpoint_);
220 EnforceBudgetLevelRestrictions(); 229 EnforceBudgetLevelRestrictions();
221 } 230 }
222 last_checkpoint_ = now; 231 last_checkpoint_ = now;
223 } 232 }
224 } 233 }
225 234
226 void CPUTimeBudgetPool::BlockThrottledQueues(base::TimeTicks now) {
227 for (TaskQueue* queue : associated_task_queues_)
228 budget_pool_controller_->BlockQueue(now, queue);
229 }
230
231 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() { 235 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() {
232 if (max_budget_level_) { 236 if (max_budget_level_) {
233 current_budget_level_ = 237 current_budget_level_ =
234 std::min(current_budget_level_, max_budget_level_.value()); 238 std::min(current_budget_level_, max_budget_level_.value());
235 } 239 }
236 if (max_throttling_delay_) { 240 if (max_throttling_delay_) {
237 // Current budget level may be negative. 241 // Current budget level may be negative.
238 current_budget_level_ = 242 current_budget_level_ =
239 std::max(current_budget_level_, 243 std::max(current_budget_level_,
240 -max_throttling_delay_.value() * cpu_percentage_); 244 -max_throttling_delay_.value() * cpu_percentage_);
241 } 245 }
242 } 246 }
243 247
244 } // namespace scheduler 248 } // namespace scheduler
245 } // namespace blink 249 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/scheduler/renderer/budget_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698