1 // Copyright 2018 The Chromium Authors
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 "base/task/sequence_manager/sequence_manager.h"
6
7 #include <utility>
8
9 namespace base {
10 namespace sequence_manager {
11
12 namespace {
13
14 #if BUILDFLAG(ENABLE_BASE_TRACING)
15 perfetto::protos::pbzero::SequenceManagerTask::Priority
DefaultTaskPriorityToProto(TaskQueue::QueuePriority priority)16 DefaultTaskPriorityToProto(TaskQueue::QueuePriority priority) {
17 DCHECK_EQ(priority, static_cast<TaskQueue::QueuePriority>(
18 TaskQueue::DefaultQueuePriority::kNormalPriority));
19 return perfetto::protos::pbzero::SequenceManagerTask::Priority::
20 NORMAL_PRIORITY;
21 }
22 #endif
23
CheckPriorities(TaskQueue::QueuePriority priority_count,TaskQueue::QueuePriority default_priority)24 void CheckPriorities(TaskQueue::QueuePriority priority_count,
25 TaskQueue::QueuePriority default_priority) {
26 CHECK_LE(static_cast<size_t>(priority_count),
27 SequenceManager::PrioritySettings::kMaxPriorities)
28 << "The number of priorities cannot exceed kMaxPriorities.";
29 CHECK_LT(static_cast<size_t>(default_priority), priority_count)
30 << "The default priority must be within the priority range.";
31 }
32
33 } // namespace
34
MetricRecordingSettings(double task_thread_time_sampling_rate)35 SequenceManager::MetricRecordingSettings::MetricRecordingSettings(
36 double task_thread_time_sampling_rate)
37 : task_sampling_rate_for_recording_cpu_time(
38 base::ThreadTicks::IsSupported() ? task_thread_time_sampling_rate
39 : 0) {}
40
41 // static
42 SequenceManager::PrioritySettings
CreateDefault()43 SequenceManager::PrioritySettings::CreateDefault() {
44 PrioritySettings settings(
45 TaskQueue::DefaultQueuePriority::kQueuePriorityCount,
46 TaskQueue::DefaultQueuePriority::kNormalPriority);
47 #if BUILDFLAG(ENABLE_BASE_TRACING)
48 settings.SetProtoPriorityConverter(&DefaultTaskPriorityToProto);
49 #endif
50 return settings;
51 }
52
PrioritySettings(TaskQueue::QueuePriority priority_count,TaskQueue::QueuePriority default_priority)53 SequenceManager::PrioritySettings::PrioritySettings(
54 TaskQueue::QueuePriority priority_count,
55 TaskQueue::QueuePriority default_priority)
56 #if DCHECK_IS_ON()
57 : PrioritySettings(priority_count,
58 default_priority,
59 std::vector<TimeDelta>(priority_count),
60 std::vector<TimeDelta>(priority_count)){}
61 #else
62 : priority_count_(priority_count), default_priority_(default_priority) {
63 CheckPriorities(priority_count, default_priority);
64 }
65 #endif
66
67 #if DCHECK_IS_ON()
PrioritySettings(TaskQueue::QueuePriority priority_count,TaskQueue::QueuePriority default_priority,std::vector<TimeDelta> per_priority_cross_thread_task_delay,std::vector<TimeDelta> per_priority_same_thread_task_delay)68 SequenceManager::PrioritySettings::PrioritySettings(
69 TaskQueue::QueuePriority priority_count,
70 TaskQueue::QueuePriority default_priority,
71 std::vector<TimeDelta> per_priority_cross_thread_task_delay,
72 std::vector<TimeDelta> per_priority_same_thread_task_delay)
73 : priority_count_(priority_count),
74 default_priority_(default_priority),
75 per_priority_cross_thread_task_delay_(
76 std::move(per_priority_cross_thread_task_delay)),
77 per_priority_same_thread_task_delay_(
78 std::move(per_priority_same_thread_task_delay)) {
79 CheckPriorities(priority_count, default_priority);
80 DCHECK_EQ(priority_count, per_priority_cross_thread_task_delay_.size());
81 DCHECK_EQ(priority_count, per_priority_same_thread_task_delay_.size());
82 }
83 #endif
84
85 #if BUILDFLAG(ENABLE_BASE_TRACING)
86 perfetto::protos::pbzero::SequenceManagerTask::Priority
TaskPriorityToProto(TaskQueue::QueuePriority priority) const87 SequenceManager::PrioritySettings::TaskPriorityToProto(
88 TaskQueue::QueuePriority priority) const {
89 // `proto_priority_converter_` will be null in some unit tests, but those
90 // tests should not be tracing.
91 DCHECK(proto_priority_converter_)
92 << "A tracing priority-to-proto-priority function was not provided";
93 return proto_priority_converter_(priority);
94 }
95 #endif
96
97 SequenceManager::PrioritySettings::~PrioritySettings() = default;
98
99 SequenceManager::PrioritySettings::PrioritySettings(
100 PrioritySettings&&) noexcept = default;
101
102 SequenceManager::PrioritySettings& SequenceManager::PrioritySettings::operator=(
103 PrioritySettings&&) = default;
104
105 SequenceManager::Settings::Settings() = default;
106
107 SequenceManager::Settings::Settings(Settings&& move_from) noexcept = default;
108
109 SequenceManager::Settings::~Settings() = default;
110
111 SequenceManager::Settings::Builder::Builder() = default;
112
113 SequenceManager::Settings::Builder::~Builder() = default;
114
115 SequenceManager::Settings::Builder&
SetMessagePumpType(MessagePumpType message_loop_type_val)116 SequenceManager::Settings::Builder::SetMessagePumpType(
117 MessagePumpType message_loop_type_val) {
118 settings_.message_loop_type = message_loop_type_val;
119 return *this;
120 }
121
122 SequenceManager::Settings::Builder&
SetRandomisedSamplingEnabled(bool randomised_sampling_enabled_val)123 SequenceManager::Settings::Builder::SetRandomisedSamplingEnabled(
124 bool randomised_sampling_enabled_val) {
125 settings_.randomised_sampling_enabled = randomised_sampling_enabled_val;
126 return *this;
127 }
128
129 SequenceManager::Settings::Builder&
SetTickClock(const TickClock * clock_val)130 SequenceManager::Settings::Builder::SetTickClock(const TickClock* clock_val) {
131 settings_.clock = clock_val;
132 return *this;
133 }
134
135 SequenceManager::Settings::Builder&
SetAddQueueTimeToTasks(bool add_queue_time_to_tasks_val)136 SequenceManager::Settings::Builder::SetAddQueueTimeToTasks(
137 bool add_queue_time_to_tasks_val) {
138 settings_.add_queue_time_to_tasks = add_queue_time_to_tasks_val;
139 return *this;
140 }
141
142 SequenceManager::Settings::Builder&
SetCanRunTasksByBatches(bool can_run_tasks_by_batches_val)143 SequenceManager::Settings::Builder::SetCanRunTasksByBatches(
144 bool can_run_tasks_by_batches_val) {
145 settings_.can_run_tasks_by_batches = can_run_tasks_by_batches_val;
146 return *this;
147 }
148
149 SequenceManager::Settings::Builder&
SetPrioritySettings(SequenceManager::PrioritySettings settings)150 SequenceManager::Settings::Builder::SetPrioritySettings(
151 SequenceManager::PrioritySettings settings) {
152 settings_.priority_settings = std::move(settings);
153 return *this;
154 }
155
156 #if DCHECK_IS_ON()
157
158 SequenceManager::Settings::Builder&
SetRandomTaskSelectionSeed(uint64_t random_task_selection_seed_val)159 SequenceManager::Settings::Builder::SetRandomTaskSelectionSeed(
160 uint64_t random_task_selection_seed_val) {
161 settings_.random_task_selection_seed = random_task_selection_seed_val;
162 return *this;
163 }
164
165 SequenceManager::Settings::Builder&
SetTaskLogging(TaskLogging task_execution_logging_val)166 SequenceManager::Settings::Builder::SetTaskLogging(
167 TaskLogging task_execution_logging_val) {
168 settings_.task_execution_logging = task_execution_logging_val;
169 return *this;
170 }
171
172 SequenceManager::Settings::Builder&
SetLogPostTask(bool log_post_task_val)173 SequenceManager::Settings::Builder::SetLogPostTask(bool log_post_task_val) {
174 settings_.log_post_task = log_post_task_val;
175 return *this;
176 }
177
178 SequenceManager::Settings::Builder&
SetLogTaskDelayExpiry(bool log_task_delay_expiry_val)179 SequenceManager::Settings::Builder::SetLogTaskDelayExpiry(
180 bool log_task_delay_expiry_val) {
181 settings_.log_task_delay_expiry = log_task_delay_expiry_val;
182 return *this;
183 }
184
185 #endif // DCHECK_IS_ON()
186
Build()187 SequenceManager::Settings SequenceManager::Settings::Builder::Build() {
188 return std::move(settings_);
189 }
190
191 } // namespace sequence_manager
192 } // namespace base
193