summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.cc
blob: 5e24f1165366dfc04c04e62e35613923a7959c40 (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
// Copyright 2014 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/single_thread_idle_task_runner.h"

#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/blame_context.h"
#include "base/trace_event/trace_event.h"

namespace blink {
namespace scheduler {

SingleThreadIdleTaskRunner::SingleThreadIdleTaskRunner(
    scoped_refptr<base::SingleThreadTaskRunner> idle_priority_task_runner,
    Delegate* delegate)
    : idle_priority_task_runner_(idle_priority_task_runner),
      delegate_(delegate),
      blame_context_(nullptr) {
  weak_scheduler_ptr_ = weak_factory_.GetWeakPtr();
}

SingleThreadIdleTaskRunner::~SingleThreadIdleTaskRunner() = default;

SingleThreadIdleTaskRunner::Delegate::Delegate() = default;

SingleThreadIdleTaskRunner::Delegate::~Delegate() = default;

bool SingleThreadIdleTaskRunner::RunsTasksInCurrentSequence() const {
  return idle_priority_task_runner_->RunsTasksInCurrentSequence();
}

void SingleThreadIdleTaskRunner::PostIdleTask(const base::Location& from_here,
                                              IdleTask idle_task) {
  delegate_->OnIdleTaskPosted();
  idle_priority_task_runner_->PostTask(
      from_here, base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
                                weak_scheduler_ptr_, std::move(idle_task)));
}

void SingleThreadIdleTaskRunner::PostDelayedIdleTask(
    const base::Location& from_here,
    const base::TimeDelta delay,
    IdleTask idle_task) {
  base::TimeTicks first_run_time = delegate_->NowTicks() + delay;
  delayed_idle_tasks_.emplace(
      first_run_time,
      std::make_pair(
          from_here,
          base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
                         weak_scheduler_ptr_, std::move(idle_task))));
}

void SingleThreadIdleTaskRunner::PostNonNestableIdleTask(
    const base::Location& from_here,
    IdleTask idle_task) {
  delegate_->OnIdleTaskPosted();
  idle_priority_task_runner_->PostNonNestableTask(
      from_here, base::BindOnce(&SingleThreadIdleTaskRunner::RunTask,
                                weak_scheduler_ptr_, std::move(idle_task)));
}

void SingleThreadIdleTaskRunner::EnqueueReadyDelayedIdleTasks() {
  if (delayed_idle_tasks_.empty())
    return;

  base::TimeTicks now = delegate_->NowTicks();
  while (!delayed_idle_tasks_.empty() &&
         delayed_idle_tasks_.begin()->first <= now) {
    idle_priority_task_runner_->PostTask(
        delayed_idle_tasks_.begin()->second.first,
        std::move(delayed_idle_tasks_.begin()->second.second));
    delayed_idle_tasks_.erase(delayed_idle_tasks_.begin());
  }
}

void SingleThreadIdleTaskRunner::RunTask(IdleTask idle_task) {
  base::TimeTicks deadline = delegate_->WillProcessIdleTask();
  TRACE_EVENT1("renderer.scheduler", "SingleThreadIdleTaskRunner::RunTask",
               "allotted_time_ms",
               (deadline - base::TimeTicks::Now()).InMillisecondsF());
  if (blame_context_)
    blame_context_->Enter();
  std::move(idle_task).Run(deadline);
  if (blame_context_)
    blame_context_->Leave();
  delegate_->DidProcessIdleTask();
}

void SingleThreadIdleTaskRunner::SetBlameContext(
    base::trace_event::BlameContext* blame_context) {
  blame_context_ = blame_context;
}

}  // namespace scheduler
}  // namespace blink