| OLD | NEW |
| 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 19 matching lines...) Expand all Loading... |
| 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() {} | 35 BudgetPool::~BudgetPool() {} |
| 36 | 36 |
| 37 CPUTimeBudgetPool::CPUTimeBudgetPool( | 37 CPUTimeBudgetPool::CPUTimeBudgetPool( |
| 38 const char* name, | 38 const char* name, |
| 39 BudgetPoolController* budget_pool_controller, | 39 BudgetPoolController* budget_pool_controller, |
| 40 base::TimeTicks now, | 40 base::TimeTicks now) |
| 41 base::Optional<base::TimeDelta> max_budget_level, | |
| 42 base::Optional<base::TimeDelta> max_throttling_duration) | |
| 43 : name_(name), | 41 : name_(name), |
| 44 budget_pool_controller_(budget_pool_controller), | 42 budget_pool_controller_(budget_pool_controller), |
| 45 max_budget_level_(max_budget_level), | |
| 46 max_throttling_duration_(max_throttling_duration), | |
| 47 last_checkpoint_(now), | 43 last_checkpoint_(now), |
| 48 cpu_percentage_(1), | 44 cpu_percentage_(1), |
| 49 is_enabled_(true) {} | 45 is_enabled_(true) {} |
| 50 | 46 |
| 51 CPUTimeBudgetPool::~CPUTimeBudgetPool() {} | 47 CPUTimeBudgetPool::~CPUTimeBudgetPool() {} |
| 52 | 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 } |
| 56 |
| 57 void CPUTimeBudgetPool::SetMaxThrottlingDelay( |
| 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 |
| 53 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now, | 72 void CPUTimeBudgetPool::SetTimeBudgetRecoveryRate(base::TimeTicks now, |
| 54 double cpu_percentage) { | 73 double cpu_percentage) { |
| 55 Advance(now); | 74 Advance(now); |
| 56 cpu_percentage_ = cpu_percentage; | 75 cpu_percentage_ = cpu_percentage; |
| 57 EnforceBudgetLevelRestrictions(); | 76 EnforceBudgetLevelRestrictions(); |
| 58 } | 77 } |
| 59 | 78 |
| 60 void CPUTimeBudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) { | 79 void CPUTimeBudgetPool::AddQueue(base::TimeTicks now, TaskQueue* queue) { |
| 61 budget_pool_controller_->AddQueueToBudgetPool(queue, this); | 80 budget_pool_controller_->AddQueueToBudgetPool(queue, this); |
| 62 associated_task_queues_.insert(queue); | 81 associated_task_queues_.insert(queue); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 reporting_callback_ = reporting_callback; | 140 reporting_callback_ = reporting_callback; |
| 122 } | 141 } |
| 123 | 142 |
| 124 void CPUTimeBudgetPool::Close() { | 143 void CPUTimeBudgetPool::Close() { |
| 125 DCHECK_EQ(0u, associated_task_queues_.size()); | 144 DCHECK_EQ(0u, associated_task_queues_.size()); |
| 126 | 145 |
| 127 budget_pool_controller_->UnregisterBudgetPool(this); | 146 budget_pool_controller_->UnregisterBudgetPool(this); |
| 128 } | 147 } |
| 129 | 148 |
| 130 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) { | 149 bool CPUTimeBudgetPool::HasEnoughBudgetToRun(base::TimeTicks now) { |
| 131 Advance(now); | 150 return now >= GetNextAllowedRunTime(); |
| 132 return !is_enabled_ || current_budget_level_.InMicroseconds() >= 0; | |
| 133 } | 151 } |
| 134 | 152 |
| 135 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() { | 153 base::TimeTicks CPUTimeBudgetPool::GetNextAllowedRunTime() { |
| 136 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) { | 154 if (!is_enabled_ || current_budget_level_.InMicroseconds() >= 0) { |
| 137 return last_checkpoint_; | 155 return last_checkpoint_; |
| 138 } else { | 156 } else { |
| 139 // Subtract because current_budget is negative. | 157 // Subtract because current_budget is negative. |
| 140 return last_checkpoint_ - current_budget_level_ / cpu_percentage_; | 158 return last_checkpoint_ + |
| 159 (-current_budget_level_ + min_budget_level_to_run_) / |
| 160 cpu_percentage_; |
| 141 } | 161 } |
| 142 } | 162 } |
| 143 | 163 |
| 144 void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time, | 164 void CPUTimeBudgetPool::RecordTaskRunTime(base::TimeTicks start_time, |
| 145 base::TimeTicks end_time) { | 165 base::TimeTicks end_time) { |
| 146 DCHECK_LE(start_time, end_time); | 166 DCHECK_LE(start_time, end_time); |
| 147 Advance(end_time); | 167 Advance(end_time); |
| 148 if (is_enabled_) { | 168 if (is_enabled_) { |
| 149 base::TimeDelta old_budget_level = current_budget_level_; | 169 base::TimeDelta old_budget_level = current_budget_level_; |
| 150 current_budget_level_ -= (end_time - start_time); | 170 current_budget_level_ -= (end_time - start_time); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 165 base::TimeTicks now) const { | 185 base::TimeTicks now) const { |
| 166 state->BeginDictionary(name_); | 186 state->BeginDictionary(name_); |
| 167 | 187 |
| 168 state->SetString("name", name_); | 188 state->SetString("name", name_); |
| 169 state->SetDouble("time_budget", cpu_percentage_); | 189 state->SetDouble("time_budget", cpu_percentage_); |
| 170 state->SetDouble("time_budget_level_in_seconds", | 190 state->SetDouble("time_budget_level_in_seconds", |
| 171 current_budget_level_.InSecondsF()); | 191 current_budget_level_.InSecondsF()); |
| 172 state->SetDouble("last_checkpoint_seconds_ago", | 192 state->SetDouble("last_checkpoint_seconds_ago", |
| 173 (now - last_checkpoint_).InSecondsF()); | 193 (now - last_checkpoint_).InSecondsF()); |
| 174 state->SetBoolean("is_enabled", is_enabled_); | 194 state->SetBoolean("is_enabled", is_enabled_); |
| 195 state->SetDouble("min_budget_level_to_run_in_seconds", |
| 196 min_budget_level_to_run_.InSecondsF()); |
| 197 |
| 198 if (max_throttling_delay_) { |
| 199 state->SetDouble("max_throttling_delay_in_seconds", |
| 200 max_throttling_delay_.value().InSecondsF()); |
| 201 } |
| 202 if (max_budget_level_) { |
| 203 state->SetDouble("max_budget_level_in_seconds", |
| 204 max_budget_level_.value().InSecondsF()); |
| 205 } |
| 175 | 206 |
| 176 state->BeginArray("task_queues"); | 207 state->BeginArray("task_queues"); |
| 177 for (TaskQueue* queue : associated_task_queues_) { | 208 for (TaskQueue* queue : associated_task_queues_) { |
| 178 state->AppendString(PointerToId(queue)); | 209 state->AppendString(PointerToId(queue)); |
| 179 } | 210 } |
| 180 state->EndArray(); | 211 state->EndArray(); |
| 181 | 212 |
| 182 state->EndDictionary(); | 213 state->EndDictionary(); |
| 183 } | 214 } |
| 184 | 215 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 195 void CPUTimeBudgetPool::BlockThrottledQueues(base::TimeTicks now) { | 226 void CPUTimeBudgetPool::BlockThrottledQueues(base::TimeTicks now) { |
| 196 for (TaskQueue* queue : associated_task_queues_) | 227 for (TaskQueue* queue : associated_task_queues_) |
| 197 budget_pool_controller_->BlockQueue(now, queue); | 228 budget_pool_controller_->BlockQueue(now, queue); |
| 198 } | 229 } |
| 199 | 230 |
| 200 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() { | 231 void CPUTimeBudgetPool::EnforceBudgetLevelRestrictions() { |
| 201 if (max_budget_level_) { | 232 if (max_budget_level_) { |
| 202 current_budget_level_ = | 233 current_budget_level_ = |
| 203 std::min(current_budget_level_, max_budget_level_.value()); | 234 std::min(current_budget_level_, max_budget_level_.value()); |
| 204 } | 235 } |
| 205 if (max_throttling_duration_) { | 236 if (max_throttling_delay_) { |
| 206 // Current budget level may be negative. | 237 // Current budget level may be negative. |
| 207 current_budget_level_ = | 238 current_budget_level_ = |
| 208 std::max(current_budget_level_, | 239 std::max(current_budget_level_, |
| 209 -max_throttling_duration_.value() * cpu_percentage_); | 240 -max_throttling_delay_.value() * cpu_percentage_); |
| 210 } | 241 } |
| 211 } | 242 } |
| 212 | 243 |
| 213 } // namespace scheduler | 244 } // namespace scheduler |
| 214 } // namespace blink | 245 } // namespace blink |
| OLD | NEW |