summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc
blob: 5505763b03c1dd06eb1506c4ed41a039a2d8a7c6 (plain)
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