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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.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 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/cpu_time_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"
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/optional.h" 12 #include "base/optional.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "platform/WebFrameScheduler.h"
15 #include "platform/scheduler/base/real_time_domain.h"
16 #include "platform/scheduler/child/scheduler_tqm_delegate.h"
17 #include "platform/scheduler/renderer/renderer_scheduler_impl.h"
18 #include "platform/scheduler/renderer/task_queue_throttler.h" 14 #include "platform/scheduler/renderer/task_queue_throttler.h"
19 #include "platform/scheduler/renderer/throttled_time_domain.h"
20 #include "platform/scheduler/renderer/web_frame_scheduler_impl.h"
21 15
22 namespace blink { 16 namespace blink {
23 namespace scheduler { 17 namespace scheduler {
24 18
25 namespace { 19 namespace {
26 20
27 std::string PointerToId(void* pointer) { 21 std::string PointerToId(void* pointer) {
28 return base::StringPrintf( 22 return base::StringPrintf(
29 "0x%" PRIx64, 23 "0x%" PRIx64,
30 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer))); 24 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pointer)));
31 } 25 }
32 26
33 } // namespace 27 } // namespace
34 28
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
41 BudgetPool::~BudgetPool() {}
42
43 const char* BudgetPool::Name() const {
44 return name_;
45 }
46
47 void BudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) {
48 budget_pool_controller_->AddQueueToBudgetPool(queue, this);
49 associated_task_queues_.insert(queue);
50
51 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
52 return;
53
54 budget_pool_controller_->BlockQueue(now, queue);
55 }
56
57 void BudgetPool::RemoveQueue(base::TimeTicks now, TaskQueue* queue) {
58 budget_pool_controller_->RemoveQueueFromBudgetPool(queue, this);
59 associated_task_queues_.erase(queue);
60
61 if (!is_enabled_ || !budget_pool_controller_->IsThrottled(queue))
62 return;
63
64 budget_pool_controller_->UnblockQueue(now, queue);
65 }
66
67 void BudgetPool::EnableThrottling(LazyNow* lazy_now) {
68 if (is_enabled_)
69 return;
70 is_enabled_ = true;
71
72 TRACE_EVENT0("renderer.scheduler", "BudgetPool_EnableThrottling");
73
74 BlockThrottledQueues(lazy_now->Now());
75 }
76
77 void BudgetPool::DisableThrottling(LazyNow* lazy_now) {
78 if (!is_enabled_)
79 return;
80 is_enabled_ = false;
81
82 TRACE_EVENT0("renderer.scheduler", "BudgetPool_DisableThrottling");
83
84 for (TaskQueue* queue : associated_task_queues_) {
85 if (!budget_pool_controller_->IsThrottled(queue))
86 continue;
87
88 budget_pool_controller_->UnblockQueue(lazy_now->Now(), queue);
89 }
90
91 // TODO(altimin): We need to disable TimeBudgetQueues here or they will
92 // regenerate extra time budget when they are disabled.
93 }
94
95 bool BudgetPool::IsThrottlingEnabled() const {
96 return is_enabled_;
97 }
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( 29 CPUTimeBudgetPool::CPUTimeBudgetPool(
111 const char* name, 30 const char* name,
112 BudgetPoolController* budget_pool_controller, 31 BudgetPoolController* budget_pool_controller,
113 base::TimeTicks now) 32 base::TimeTicks now)
114 : BudgetPool(name, budget_pool_controller), 33 : BudgetPool(name, budget_pool_controller),
115 last_checkpoint_(now), 34 last_checkpoint_(now),
116 cpu_percentage_(1) {} 35 cpu_percentage_(1) {}
117 36
118 CPUTimeBudgetPool::~CPUTimeBudgetPool() {} 37 CPUTimeBudgetPool::~CPUTimeBudgetPool() {}
119 38
39 QueueBlockType CPUTimeBudgetPool::GetBlockType() const {
40 return QueueBlockType::kAllTasks;
41 }
42
120 void CPUTimeBudgetPool::SetMaxBudgetLevel( 43 void CPUTimeBudgetPool::SetMaxBudgetLevel(
121 base::TimeTicks now, 44 base::TimeTicks now,
122 base::Optional<base::TimeDelta> max_budget_level) { 45 base::Optional<base::TimeDelta> max_budget_level) {
123 Advance(now); 46 Advance(now);
124 max_budget_level_ = max_budget_level; 47 max_budget_level_ = max_budget_level;
125 EnforceBudgetLevelRestrictions(); 48 EnforceBudgetLevelRestrictions();
126 } 49 }
127 50
128 void CPUTimeBudgetPool::SetMaxThrottlingDelay( 51 void CPUTimeBudgetPool::SetMaxThrottlingDelay(
129 base::TimeTicks now, 52 base::TimeTicks now,
(...skipping 22 matching lines...) Expand all
152 Advance(now); 75 Advance(now);
153 current_budget_level_ += budget_level; 76 current_budget_level_ += budget_level;
154 EnforceBudgetLevelRestrictions(); 77 EnforceBudgetLevelRestrictions();
155 } 78 }
156 79
157 void CPUTimeBudgetPool::SetReportingCallback( 80 void CPUTimeBudgetPool::SetReportingCallback(
158 base::Callback<void(base::TimeDelta)> reporting_callback) { 81 base::Callback<void(base::TimeDelta)> reporting_callback) {
159 reporting_callback_ = reporting_callback; 82 reporting_callback_ = reporting_callback;
160 } 83 }
161 84
162 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) { 85 bool CPUTimeBudgetPool::CanRunTasksAt(base::TimeTicks now,
163 return now >= GetNextAllowedRunTime(); 86 bool is_wake_up) const {
87 return now >= GetNextAllowedRunTime(now);
164 } 88 }
165 89
166 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() { 90 bool CPUTimeBudgetPool::CanRunTasksUntil(base::TimeTicks now,
91 base::TimeTicks moment) const {
92 return CanRunTasksAt(now, false);
Sami 2017/04/29 17:43:02 I think this is slightly misleading: I would expec
altimin 2017/05/02 18:16:58 Scrapped CanRunTasksUntil completely.
93 }
94
95 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime(
96 base::TimeTicks desired_run_time) const {
167 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) { 97 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) {
168 return last_checkpoint_; 98 return last_checkpoint_;
169 } else { 99 } else {
170 // Subtract because current_budget is negative. 100 // Subtract because current_budget is negative.
171 return last_checkpoint_ + 101 return last_checkpoint_ +
172 (-current_budget_level_ + min_budget_level_to_run_) / 102 (-current_budget_level_ + min_budget_level_to_run_) /
173 cpu_percentage_; 103 cpu_percentage_;
174 } 104 }
175 } 105 }
176 106
177 void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time, 107 void CPUTimeBudgetPool::RecordTaskRunTime(TaskQueue* queue,
108 base::TimeTicks start_time,
178 base::TimeTicks end_time) { 109 base::TimeTicks end_time) {
179 DCHECK_LE(start_time, end_time); 110 DCHECK_LE(start_time, end_time);
180 Advance(end_time); 111 Advance(end_time);
181 if (is_enabled_) { 112 if (is_enabled_) {
182 base::TimeDelta old_budget_level = current_budget_level_; 113 base::TimeDelta old_budget_level = current_budget_level_;
183 current_budget_level_ -= (end_time - start_time); 114 current_budget_level_ -= (end_time - start_time);
184 EnforceBudgetLevelRestrictions(); 115 EnforceBudgetLevelRestrictions();
185 116
186 if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 && 117 if (!reporting_callback_.is_null() && old_budget_level.InSecondsF() > 0 &&
187 current_budget_level_.InSecondsF() < 0) { 118 current_budget_level_.InSecondsF() < 0) {
188 reporting_callback_.Run(-current_budget_level_ / cpu_percentage_); 119 reporting_callback_.Run(-current_budget_level_ / cpu_percentage_);
189 } 120 }
190 } 121 }
122
123 if (current_budget_level_.InSecondsF() < 0)
124 BlockThrottledQueues(end_time);
191 } 125 }
192 126
127 void CPUTimeBudgetPool::OnQueueNextWakeUpChanged(
128 TaskQueue* queue,
129 base::TimeTicks now,
130 base::TimeTicks desired_run_time) {
131 budget_pool_controller_->UpdateQueueThrottlingState(now, queue);
132 }
133
134 void CPUTimeBudgetPool::OnWakeUp(base::TimeTicks now) {}
135
193 void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state, 136 void CPUTimeBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
194 base::TimeTicks now) const { 137 base::TimeTicks now) const {
195 state->BeginDictionary(name_); 138 state->BeginDictionary(name_);
196 139
197 state->SetString("name", name_); 140 state->SetString("name", name_);
198 state->SetDouble("time_budget", cpu_percentage_); 141 state->SetDouble("time_budget", cpu_percentage_);
199 state->SetDouble("time_budget_level_in_seconds", 142 state->SetDouble("time_budget_level_in_seconds",
200 current_budget_level_.InSecondsF()); 143 current_budget_level_.InSecondsF());
201 state->SetDouble("last_checkpoint_seconds_ago", 144 state->SetDouble("last_checkpoint_seconds_ago",
202 (now - last_checkpoint_).InSecondsF()); 145 (now - last_checkpoint_).InSecondsF());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 if (max_throttling_delay_) { 183 if (max_throttling_delay_) {
241 // Current budget level may be negative. 184 // Current budget level may be negative.
242 current_budget_level_ = 185 current_budget_level_ =
243 std::max(current_budget_level_, 186 std::max(current_budget_level_,
244 -max_throttling_delay_.value() * cpu_percentage_); 187 -max_throttling_delay_.value() * cpu_percentage_);
245 } 188 }
246 } 189 }
247 190
248 } // namespace scheduler 191 } // namespace scheduler
249 } // namespace blink 192 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698