1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h"
#include <cstdint>
#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
#include "third_party/blink/renderer/platform/scheduler/common/tracing_helper.h"
namespace blink {
namespace scheduler {
using base::sequence_manager::TaskQueue;
WakeUpBudgetPool::WakeUpBudgetPool(const char* name,
BudgetPoolController* budget_pool_controller,
base::TimeTicks now)
: BudgetPool(name, budget_pool_controller),
wake_up_interval_(base::TimeDelta::FromSecondsD(1.0)) {}
WakeUpBudgetPool::~WakeUpBudgetPool() = default;
QueueBlockType WakeUpBudgetPool::GetBlockType() const {
return QueueBlockType::kNewTasksOnly;
}
void WakeUpBudgetPool::SetWakeUpRate(double wake_ups_per_second) {
wake_up_interval_ = base::TimeDelta::FromSecondsD(1 / wake_ups_per_second);
}
void WakeUpBudgetPool::SetWakeUpDuration(base::TimeDelta duration) {
wake_up_duration_ = duration;
}
void WakeUpBudgetPool::RecordTaskRunTime(TaskQueue* queue,
base::TimeTicks start_time,
base::TimeTicks end_time) {
budget_pool_controller_->UpdateQueueSchedulingLifecycleState(end_time, queue);
}
bool WakeUpBudgetPool::CanRunTasksAt(base::TimeTicks moment,
bool is_wake_up) const {
if (!is_enabled_)
return true;
if (!last_wake_up_)
return false;
// |is_wake_up| flag means that we're in the beginning of the wake-up and
// |OnWakeUp| has just been called. This is needed to support backwards
// compability with old throttling mechanism (when |wake_up_duration| is zero)
// and allow only one task to run.
if (last_wake_up_ == moment && is_wake_up)
return true;
return moment < last_wake_up_.value() + wake_up_duration_;
}
base::TimeTicks WakeUpBudgetPool::GetTimeTasksCanRunUntil(
base::TimeTicks now,
bool is_wake_up) const {
if (!is_enabled_)
return base::TimeTicks::Max();
if (!last_wake_up_)
return base::TimeTicks();
if (!CanRunTasksAt(now, is_wake_up))
return base::TimeTicks();
return last_wake_up_.value() + wake_up_duration_;
}
base::TimeTicks WakeUpBudgetPool::GetNextAllowedRunTime(
base::TimeTicks desired_run_time) const {
if (!is_enabled_)
return desired_run_time;
if (!last_wake_up_) {
return desired_run_time.SnappedToNextTick(base::TimeTicks(),
wake_up_interval_);
}
if (desired_run_time < last_wake_up_.value() + wake_up_duration_)
return desired_run_time;
DCHECK_GE(desired_run_time, last_wake_up_.value());
return desired_run_time.SnappedToNextTick(base::TimeTicks(),
wake_up_interval_);
}
void WakeUpBudgetPool::OnQueueNextWakeUpChanged(
TaskQueue* queue,
base::TimeTicks now,
base::TimeTicks desired_run_time) {
budget_pool_controller_->UpdateQueueSchedulingLifecycleState(now, queue);
}
void WakeUpBudgetPool::OnWakeUp(base::TimeTicks now) {
last_wake_up_ = now;
}
void WakeUpBudgetPool::AsValueInto(base::trace_event::TracedValue* state,
base::TimeTicks now) const {
state->BeginDictionary(name_);
state->SetString("name", name_);
state->SetDouble("wake_up_interval_in_seconds",
wake_up_interval_.InSecondsF());
state->SetDouble("wake_up_duration_in_seconds",
wake_up_duration_.InSecondsF());
if (last_wake_up_) {
state->SetDouble("last_wake_up_seconds_ago",
(now - last_wake_up_.value()).InSecondsF());
}
state->SetBoolean("is_enabled", is_enabled_);
state->BeginArray("task_queues");
for (TaskQueue* queue : associated_task_queues_) {
state->AppendString(PointerToString(queue));
}
state->EndArray();
state->EndDictionary();
}
} // namespace scheduler
} // namespace blink
|