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

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

Issue 2761503002: [scheduler] CPUTimeBudgetPool: Require a minimal level of budget to run (Closed)
Patch Set: Created 3 years, 9 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 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 <fstream> // FIXME
10 #include <iostream> // FIXME
11
9 #include "base/format_macros.h" 12 #include "base/format_macros.h"
10 #include "base/logging.h" 13 #include "base/logging.h"
11 #include "base/memory/ptr_util.h" 14 #include "base/memory/ptr_util.h"
12 #include "base/optional.h" 15 #include "base/optional.h"
13 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
14 #include "platform/WebFrameScheduler.h" 17 #include "platform/WebFrameScheduler.h"
15 #include "platform/scheduler/base/real_time_domain.h" 18 #include "platform/scheduler/base/real_time_domain.h"
16 #include "platform/scheduler/child/scheduler_tqm_delegate.h" 19 #include "platform/scheduler/child/scheduler_tqm_delegate.h"
17 #include "platform/scheduler/renderer/renderer_scheduler_impl.h" 20 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
18 #include "platform/scheduler/renderer/task_queue_throttler.h" 21 #include "platform/scheduler/renderer/task_queue_throttler.h"
(...skipping 11 matching lines...) Expand all
30 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); 33 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
31 } 34 }
32 35
33 } // namespace 36 } // namespace
34 37
35 BudgetPool::~BudgetPool() {} 38 BudgetPool::~BudgetPool() {}
36 39
37 CPUTimeBudgetPool::CPUTimeBudgetPool( 40 CPUTimeBudgetPool::CPUTimeBudgetPool(
38 const char* name, 41 const char* name,
39 BudgetPoolController* budget_pool_controller, 42 BudgetPoolController* budget_pool_controller,
40 base::TimeTicks now, 43 base::TimeTicks now)
41 base::Optional<base::TimeDelta> max_budget_level,
42 base::Optional<base::TimeDelta> max_throttling_duration)
43 : name_(name), 44 : name_(name),
44 budget_pool_controller_(budget_pool_controller), 45 budget_pool_controller_(budget_pool_controller),
45 max_budget_level_(max_budget_level),
46 max_throttling_duration_(max_throttling_duration),
47 last_checkpoint_(now), 46 last_checkpoint_(now),
48 cpu_percentage_(1), 47 cpu_percentage_(1),
49 is_enabled_(true) {} 48 is_enabled_(true) {}
50 49
51 CPUTimeBudgetPool::~CPUTimeBudgetPool() {} 50 CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
52 51
52 void CPUTimeBudgetPool::SetMaxBudgetLevel(
53 base::TimeTicks now,
54 base::Optional<base::TimeDelta> max_budget_level) {
55 Advance(now);
56 max_budget_level_ = max_budget_level;
57 EnforceBudgetLevelRestrictions();
58 }
59
60 void CPUTimeBudgetPool::SetMaxThrottlingDelay(
61 base::TimeTicks now,
62 base::Optional<base::TimeDelta> max_throttling_delay) {
63 Advance(now);
64 max_throttling_delay_ = max_throttling_delay;
65 EnforceBudgetLevelRestrictions();
66 }
67
68 void CPUTimeBudgetPool::SetMinBudgetLevelToRun(
69 base::TimeTicks now,
70 base::TimeDelta min_budget_level_to_run) {
71 Advance(now);
72 min_budget_level_to_run_ = min_budget_level_to_run;
alex clarke (OOO till 29th) 2017/03/20 09:03:03 Do we expect this to get called more than once dur
altimin 2017/03/20 15:21:08 Added a comment if the header file.
73 }
74
53 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now, 75 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now,
54 double cpu_percentage) { 76 double cpu_percentage) {
55 Advance(now); 77 Advance(now);
56 cpu_percentage_ = cpu_percentage; 78 cpu_percentage_ = cpu_percentage;
57 EnforceBudgetLevelRestrictions(); 79 EnforceBudgetLevelRestrictions();
58 } 80 }
59 81
60 void CPUTimeBudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) { 82 void CPUTimeBudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) {
61 budget_pool_controller_->AddQueueToBudgetPool(queue, this); 83 budget_pool_controller_->AddQueueToBudgetPool(queue, this);
62 associated_task_queues_.insert(queue); 84 associated_task_queues_.insert(queue);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 reporting_callback_ = reporting_callback; 143 reporting_callback_ = reporting_callback;
122 } 144 }
123 145
124 void CPUTimeBudgetPool::Close() { 146 void CPUTimeBudgetPool::Close() {
125 DCHECK_EQ(0u, associated_task_queues_.size()); 147 DCHECK_EQ(0u, associated_task_queues_.size());
126 148
127 budget_pool_controller_->UnregisterBudgetPool(this); 149 budget_pool_controller_->UnregisterBudgetPool(this);
128 } 150 }
129 151
130 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) { 152 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) {
131 Advance(now); 153 return now >= GetNextAllowedRunTime();
132 return !is_enabled_ || current_budget_level_.InMicroseconds() >= 0;
133 } 154 }
134 155
135 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() { 156 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() {
136 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) { 157 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) {
137 return last_checkpoint_; 158 return last_checkpoint_;
138 } else { 159 } else {
139 // Subtract because current_budget is negative. 160 // Subtract because current_budget is negative.
140 return last_checkpoint_ - current_budget_level_ / cpu_percentage_; 161 return last_checkpoint_ +
162 (-current_budget_level_ + min_budget_level_to_run_) /
163 cpu_percentage_;
141 } 164 }
142 } 165 }
143 166
144 void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time, 167 void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time,
145 base::TimeTicks end_time) { 168 base::TimeTicks end_time) {
146 DCHECK_LE(start_time, end_time); 169 DCHECK_LE(start_time, end_time);
147 Advance(end_time); 170 Advance(end_time);
148 if (is_enabled_) { 171 if (is_enabled_) {
149 base::TimeDelta old_budget_level = current_budget_level_; 172 base::TimeDelta old_budget_level = current_budget_level_;
150 current_budget_level_ -= (end_time - start_time); 173 current_budget_level_ -= (end_time - start_time);
(...skipping 14 matching lines...) Expand all
165 base::TimeTicks now) const { 188 base::TimeTicks now) const {
166 state->BeginDictionary(name_); 189 state->BeginDictionary(name_);
167 190
168 state->SetString("name", name_); 191 state->SetString("name", name_);
169 state->SetDouble("time_budget", cpu_percentage_); 192 state->SetDouble("time_budget", cpu_percentage_);
170 state->SetDouble("time_budget_level_in_seconds", 193 state->SetDouble("time_budget_level_in_seconds",
171 current_budget_level_.InSecondsF()); 194 current_budget_level_.InSecondsF());
172 state->SetDouble("last_checkpoint_seconds_ago", 195 state->SetDouble("last_checkpoint_seconds_ago",
173 (now - last_checkpoint_).InSecondsF()); 196 (now - last_checkpoint_).InSecondsF());
174 state->SetBoolean("is_enabled", is_enabled_); 197 state->SetBoolean("is_enabled", is_enabled_);
198 state->SetDouble("min_budget_level_to_run_in_seconds",
199 min_budget_level_to_run_.InSecondsF());
200
201 if (max_throttling_delay_) {
202 state->SetDouble("max_throttling_delay_in_seconds",
203 max_throttling_delay_.value().InSecondsF());
204 }
205 if (max_budget_level_) {
206 state->SetDouble("max_budget_level_in_seconds",
207 max_budget_level_.value().InSecondsF());
208 }
175 209
176 state->BeginArray("task_queues"); 210 state->BeginArray("task_queues");
177 for (TaskQueue* queue : associated_task_queues_) { 211 for (TaskQueue* queue : associated_task_queues_) {
178 state->AppendString(PointerToId(queue)); 212 state->AppendString(PointerToId(queue));
179 } 213 }
180 state->EndArray(); 214 state->EndArray();
181 215
182 state->EndDictionary(); 216 state->EndDictionary();
183 } 217 }
184 218
(...skipping 10 matching lines...) Expand all
195 void CPUTimeBudgetPool::BlockThrottledQueues(base::TimeTicks now) { 229 void CPUTimeBudgetPool::BlockThrottledQueues(base::TimeTicks now) {
196 for (TaskQueue* queue : associated_task_queues_) 230 for (TaskQueue* queue : associated_task_queues_)
197 budget_pool_controller_->BlockQueue(now, queue); 231 budget_pool_controller_->BlockQueue(now, queue);
198 } 232 }
199 233
200 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() { 234 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() {
201 if (max_budget_level_) { 235 if (max_budget_level_) {
202 current_budget_level_ = 236 current_budget_level_ =
203 std::min(current_budget_level_, max_budget_level_.value()); 237 std::min(current_budget_level_, max_budget_level_.value());
204 } 238 }
205 if (max_throttling_duration_) { 239 if (max_throttling_delay_) {
206 // Current budget level may be negative. 240 // Current budget level may be negative.
207 current_budget_level_ = 241 current_budget_level_ =
208 std::max(current_budget_level_, 242 std::max(current_budget_level_,
209 -max_throttling_duration_.value() * cpu_percentage_); 243 -max_throttling_delay_.value() * cpu_percentage_);
210 } 244 }
211 } 245 }
212 246
213 } // namespace scheduler 247 } // namespace scheduler
214 } // namespace blink 248 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698