1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/scheduling_metrics/thread_metrics.h"
6
7 namespace scheduling_metrics {
8
9 namespace {
10
11 // Threshold for discarding ultra-long tasks. It is assumed that ultra-long
12 // tasks are reporting glitches (e.g. system falling asleep on the middle of the
13 // task).
14 constexpr base::TimeDelta kLongTaskDiscardingThreshold =
15 base::TimeDelta::FromSeconds(30);
16
17 } // namespace
18
ThreadMetrics(ThreadType thread_type,bool has_cpu_timing_for_each_task)19 ThreadMetrics::ThreadMetrics(ThreadType thread_type,
20 bool has_cpu_timing_for_each_task)
21 : thread_type_(thread_type),
22 has_cpu_timing_for_each_task_(has_cpu_timing_for_each_task),
23 last_known_time_(has_cpu_timing_for_each_task_ ? base::ThreadTicks::Now()
24 : base::ThreadTicks()),
25 thread_task_duration_reporter_(
26 "Scheduler.Experimental.WallTimePerThread"),
27 thread_task_cpu_duration_reporter_(
28 "Scheduler.Experimental.CPUTimePerThread"),
29 tracked_cpu_duration_reporter_(
30 "Scheduler.Experimental.CPUTimePerThread.Tracked"),
31 non_tracked_cpu_duration_reporter_(
32 "Scheduler.Experimental.CPUTimePerThread.Untracked") {}
33
~ThreadMetrics()34 ThreadMetrics::~ThreadMetrics() {}
35
ShouldDiscardTask(base::sequence_manager::TaskQueue * queue,const base::sequence_manager::Task & task,const base::sequence_manager::TaskQueue::TaskTiming & task_timing)36 bool ThreadMetrics::ShouldDiscardTask(
37 base::sequence_manager::TaskQueue* queue,
38 const base::sequence_manager::Task& task,
39 const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
40 // TODO(altimin): Investigate the relationship between thread time and
41 // wall time for discarded tasks.
42 return task_timing.wall_duration() > kLongTaskDiscardingThreshold;
43 }
44
RecordTaskMetrics(base::sequence_manager::TaskQueue * queue,const base::sequence_manager::Task & task,const base::sequence_manager::TaskQueue::TaskTiming & task_timing)45 void ThreadMetrics::RecordTaskMetrics(
46 base::sequence_manager::TaskQueue* queue,
47 const base::sequence_manager::Task& task,
48 const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
49 DCHECK(!has_cpu_timing_for_each_task_ || task_timing.has_thread_time());
50 thread_task_duration_reporter_.RecordTask(thread_type_,
51 task_timing.wall_duration());
52
53 if (!task_timing.has_thread_time())
54 return;
55 thread_task_cpu_duration_reporter_.RecordTask(thread_type_,
56 task_timing.thread_duration());
57 if (has_cpu_timing_for_each_task_) {
58 non_tracked_cpu_duration_reporter_.RecordTask(
59 thread_type_, task_timing.start_thread_time() - last_known_time_);
60 tracked_cpu_duration_reporter_.RecordTask(thread_type_,
61 task_timing.thread_duration());
62
63 last_known_time_ = task_timing.end_thread_time();
64 }
65 }
66
67 } // namespace scheduling_metrics
68