OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/test/ordered_simple_task_runner.h" | 5 #include "cc/test/ordered_simple_task_runner.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <limits> | 10 #include <limits> |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 #define TRACE_TASK(function, task) \ | 22 #define TRACE_TASK(function, task) \ |
23 TRACE_EVENT_INSTANT1( \ | 23 TRACE_EVENT_INSTANT1( \ |
24 "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", task.AsValue()); | 24 "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", task.AsValue()); |
25 | 25 |
26 #define TRACE_TASK_RUN(function, tag, task) | 26 #define TRACE_TASK_RUN(function, tag, task) |
27 | 27 |
28 namespace cc { | 28 namespace cc { |
29 | 29 |
30 // TestOrderablePendingTask implementation | 30 // TestOrderablePendingTask implementation |
31 TestOrderablePendingTask::TestOrderablePendingTask() | 31 TestOrderablePendingTaskInfo::TestOrderablePendingTaskInfo() |
32 : base::TestPendingTask(), | 32 : task_id_(TestOrderablePendingTaskInfo::task_id_counter++) {} |
33 task_id_(TestOrderablePendingTask::task_id_counter++) { | |
34 } | |
35 | 33 |
36 TestOrderablePendingTask::TestOrderablePendingTask( | 34 TestOrderablePendingTaskInfo::TestOrderablePendingTaskInfo( |
37 const tracked_objects::Location& location, | 35 const tracked_objects::Location& location, |
38 const base::Closure& task, | |
39 base::TimeTicks post_time, | 36 base::TimeTicks post_time, |
40 base::TimeDelta delay, | 37 base::TimeDelta delay, |
41 TestNestability nestability) | 38 TestNestability nestability) |
42 : base::TestPendingTask(location, task, post_time, delay, nestability), | 39 : base::TestPendingTaskInfo(location, post_time, delay, nestability), |
43 task_id_(TestOrderablePendingTask::task_id_counter++) { | 40 task_id_(TestOrderablePendingTaskInfo::task_id_counter++) {} |
44 } | |
45 | 41 |
46 size_t TestOrderablePendingTask::task_id_counter = 0; | 42 size_t TestOrderablePendingTaskInfo::task_id_counter = 0; |
47 | 43 |
48 TestOrderablePendingTask::~TestOrderablePendingTask() { | 44 TestOrderablePendingTaskInfo::~TestOrderablePendingTaskInfo() {} |
49 } | |
50 | 45 |
51 bool TestOrderablePendingTask::operator==( | 46 bool TestOrderablePendingTaskInfo::operator==( |
52 const TestOrderablePendingTask& other) const { | 47 const TestOrderablePendingTaskInfo& other) const { |
53 return task_id_ == other.task_id_; | 48 return task_id_ == other.task_id_; |
54 } | 49 } |
55 | 50 |
56 bool TestOrderablePendingTask::operator<( | 51 bool TestOrderablePendingTaskInfo::operator<( |
57 const TestOrderablePendingTask& other) const { | 52 const TestOrderablePendingTaskInfo& other) const { |
58 if (*this == other) | 53 if (*this == other) |
59 return false; | 54 return false; |
60 | 55 |
61 if (GetTimeToRun() == other.GetTimeToRun()) { | 56 if (GetTimeToRun() == other.GetTimeToRun()) { |
62 return task_id_ < other.task_id_; | 57 return task_id_ < other.task_id_; |
63 } | 58 } |
64 return ShouldRunBefore(other); | 59 return ShouldRunBefore(other); |
65 } | 60 } |
66 | 61 |
67 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 62 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
68 TestOrderablePendingTask::AsValue() const { | 63 TestOrderablePendingTaskInfo::AsValue() const { |
69 std::unique_ptr<base::trace_event::TracedValue> state( | 64 std::unique_ptr<base::trace_event::TracedValue> state( |
70 new base::trace_event::TracedValue()); | 65 new base::trace_event::TracedValue()); |
71 AsValueInto(state.get()); | 66 AsValueInto(state.get()); |
72 return std::move(state); | 67 return std::move(state); |
73 } | 68 } |
74 | 69 |
75 void TestOrderablePendingTask::AsValueInto( | 70 void TestOrderablePendingTaskInfo::AsValueInto( |
76 base::trace_event::TracedValue* state) const { | 71 base::trace_event::TracedValue* state) const { |
77 state->SetInteger("id", base::saturated_cast<int>(task_id_)); | 72 state->SetInteger("id", base::saturated_cast<int>(task_id_)); |
78 state->SetInteger("run_at", GetTimeToRun().ToInternalValue()); | 73 state->SetInteger("run_at", GetTimeToRun().ToInternalValue()); |
79 state->SetString("posted_from", location.ToString()); | 74 state->SetString("posted_from", location.ToString()); |
80 } | 75 } |
81 | 76 |
82 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner( | 77 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner( |
83 base::SimpleTestTickClock* now_src, | 78 base::SimpleTestTickClock* now_src, |
84 bool advance_now) | 79 bool advance_now) |
85 : advance_now_(advance_now), | 80 : advance_now_(advance_now), |
86 now_src_(now_src), | 81 now_src_(now_src), |
87 max_tasks_(kAbsoluteMaxTasks), | 82 max_tasks_(kAbsoluteMaxTasks), |
88 inside_run_tasks_until_(false) { | 83 inside_run_tasks_until_(false) { |
89 } | 84 } |
90 | 85 |
91 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} | 86 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} |
92 | 87 |
93 // static | 88 // static |
94 base::TimeTicks OrderedSimpleTaskRunner::AbsoluteMaxNow() { | 89 base::TimeTicks OrderedSimpleTaskRunner::AbsoluteMaxNow() { |
95 return base::TimeTicks::FromInternalValue( | 90 return base::TimeTicks::FromInternalValue( |
96 std::numeric_limits<int64_t>::max()); | 91 std::numeric_limits<int64_t>::max()); |
97 } | 92 } |
98 | 93 |
99 // base::TestSimpleTaskRunner implementation | 94 // base::TestSimpleTaskRunner implementation |
100 bool OrderedSimpleTaskRunner::PostDelayedTask( | 95 bool OrderedSimpleTaskRunner::PostDelayedTask( |
101 const tracked_objects::Location& from_here, | 96 const tracked_objects::Location& from_here, |
102 const base::Closure& task, | 97 const base::Closure& task, |
103 base::TimeDelta delay) { | 98 base::TimeDelta delay) { |
104 DCHECK(thread_checker_.CalledOnValidThread()); | 99 DCHECK(thread_checker_.CalledOnValidThread()); |
105 TestOrderablePendingTask pt(from_here, task, now_src_->NowTicks(), delay, | 100 TestOrderablePendingTaskInfo pt(from_here, now_src_->NowTicks(), delay, |
106 base::TestPendingTask::NESTABLE); | 101 base::TestPendingTaskInfo::NESTABLE); |
107 | 102 |
108 TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt); | 103 TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt); |
109 pending_tasks_.insert(pt); | 104 pending_tasks_.insert(std::make_pair(pt, task)); |
110 return true; | 105 return true; |
111 } | 106 } |
112 | 107 |
113 bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask( | 108 bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask( |
114 const tracked_objects::Location& from_here, | 109 const tracked_objects::Location& from_here, |
115 const base::Closure& task, | 110 const base::Closure& task, |
116 base::TimeDelta delay) { | 111 base::TimeDelta delay) { |
117 DCHECK(thread_checker_.CalledOnValidThread()); | 112 DCHECK(thread_checker_.CalledOnValidThread()); |
118 TestOrderablePendingTask pt(from_here, task, now_src_->NowTicks(), delay, | 113 TestOrderablePendingTaskInfo pt(from_here, now_src_->NowTicks(), delay, |
119 base::TestPendingTask::NON_NESTABLE); | 114 base::TestPendingTaskInfo::NON_NESTABLE); |
120 | 115 |
121 TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt); | 116 TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt); |
122 pending_tasks_.insert(pt); | 117 pending_tasks_.insert(std::make_pair(pt, task)); |
123 return true; | 118 return true; |
124 } | 119 } |
125 | 120 |
126 bool OrderedSimpleTaskRunner::RunsTasksOnCurrentThread() const { | 121 bool OrderedSimpleTaskRunner::RunsTasksOnCurrentThread() const { |
127 DCHECK(thread_checker_.CalledOnValidThread()); | 122 DCHECK(thread_checker_.CalledOnValidThread()); |
128 return true; | 123 return true; |
129 } | 124 } |
130 | 125 |
131 size_t OrderedSimpleTaskRunner::NumPendingTasks() const { | 126 size_t OrderedSimpleTaskRunner::NumPendingTasks() const { |
132 return pending_tasks_.size(); | 127 return pending_tasks_.size(); |
133 } | 128 } |
134 | 129 |
135 bool OrderedSimpleTaskRunner::HasPendingTasks() const { | 130 bool OrderedSimpleTaskRunner::HasPendingTasks() const { |
136 return pending_tasks_.size() > 0; | 131 return pending_tasks_.size() > 0; |
137 } | 132 } |
138 | 133 |
139 base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() { | 134 base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() { |
140 if (pending_tasks_.size() <= 0) { | 135 if (pending_tasks_.size() <= 0) { |
141 return AbsoluteMaxNow(); | 136 return AbsoluteMaxNow(); |
142 } | 137 } |
143 | 138 |
144 return pending_tasks_.begin()->GetTimeToRun(); | 139 const base::TestPendingTaskInfo& task_info = pending_tasks_.begin()->first; |
| 140 return task_info.GetTimeToRun(); |
145 } | 141 } |
146 | 142 |
147 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() { | 143 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() { |
148 DCHECK(thread_checker_.CalledOnValidThread()); | 144 DCHECK(thread_checker_.CalledOnValidThread()); |
149 | 145 |
150 if (pending_tasks_.size() <= 0) { | 146 if (pending_tasks_.size() <= 0) { |
151 return AbsoluteMaxNow() - base::TimeTicks(); | 147 return AbsoluteMaxNow() - base::TimeTicks(); |
152 } | 148 } |
153 | 149 |
154 base::TimeDelta delay = NextTaskTime() - now_src_->NowTicks(); | 150 base::TimeDelta delay = NextTaskTime() - now_src_->NowTicks(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 if (!condition_success) | 204 if (!condition_success) |
209 break; | 205 break; |
210 } | 206 } |
211 | 207 |
212 // Conditions could modify the pending task length, so we need to recheck | 208 // Conditions could modify the pending task length, so we need to recheck |
213 // that there are tasks to run. | 209 // that there are tasks to run. |
214 if (!condition_success || !HasPendingTasks()) { | 210 if (!condition_success || !HasPendingTasks()) { |
215 break; | 211 break; |
216 } | 212 } |
217 | 213 |
218 std::set<TestOrderablePendingTask>::iterator task_to_run = | 214 TestOrderablePendingTaskQueue::iterator task_to_run = |
219 pending_tasks_.begin(); | 215 pending_tasks_.begin(); |
220 { | 216 { |
221 TRACE_EVENT1("cc", | 217 const base::TestPendingTaskInfo& task_info = task_to_run->first; |
222 "OrderedSimpleTaskRunner::RunPendingTasks running", | 218 base::OnceClosure task = std::move(task_to_run->second); |
223 "task", | 219 |
224 task_to_run->AsValue()); | 220 TRACE_EVENT1("cc", "OrderedSimpleTaskRunner::RunPendingTasks running", |
225 task_to_run->task.Run(); | 221 "task", task_info.AsValue()); |
| 222 std::move(task).Run(); |
226 } | 223 } |
227 | 224 |
228 pending_tasks_.erase(task_to_run); | 225 pending_tasks_.erase(task_to_run); |
229 } | 226 } |
230 | 227 |
231 return HasPendingTasks(); | 228 return HasPendingTasks(); |
232 } | 229 } |
233 | 230 |
234 bool OrderedSimpleTaskRunner::RunPendingTasks() { | 231 bool OrderedSimpleTaskRunner::RunPendingTasks() { |
235 return RunTasksWhile(TaskExistedInitially()); | 232 return RunTasksWhile(TaskExistedInitially()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 AsValueInto(state.get()); | 267 AsValueInto(state.get()); |
271 return std::move(state); | 268 return std::move(state); |
272 } | 269 } |
273 | 270 |
274 void OrderedSimpleTaskRunner::AsValueInto( | 271 void OrderedSimpleTaskRunner::AsValueInto( |
275 base::trace_event::TracedValue* state) const { | 272 base::trace_event::TracedValue* state) const { |
276 state->SetInteger("pending_tasks", | 273 state->SetInteger("pending_tasks", |
277 base::saturated_cast<int>(pending_tasks_.size())); | 274 base::saturated_cast<int>(pending_tasks_.size())); |
278 | 275 |
279 state->BeginArray("tasks"); | 276 state->BeginArray("tasks"); |
280 for (std::set<TestOrderablePendingTask>::const_iterator it = | 277 for (const auto& pending_task : pending_tasks_) { |
281 pending_tasks_.begin(); | |
282 it != pending_tasks_.end(); | |
283 ++it) { | |
284 state->BeginDictionary(); | 278 state->BeginDictionary(); |
285 it->AsValueInto(state); | 279 pending_task.first.AsValueInto(state); |
286 state->EndDictionary(); | 280 state->EndDictionary(); |
287 } | 281 } |
288 state->EndArray(); | 282 state->EndArray(); |
289 | 283 |
290 state->BeginDictionary("now_src"); | 284 state->BeginDictionary("now_src"); |
291 state->SetDouble("now_in_ms", (now_src_->NowTicks() - base::TimeTicks()) | 285 state->SetDouble("now_in_ms", (now_src_->NowTicks() - base::TimeTicks()) |
292 .InMillisecondsF()); | 286 .InMillisecondsF()); |
293 state->EndDictionary(); | 287 state->EndDictionary(); |
294 | 288 |
295 state->SetBoolean("advance_now", advance_now_); | 289 state->SetBoolean("advance_now", advance_now_); |
296 state->SetBoolean("inside_run_tasks_until", inside_run_tasks_until_); | 290 state->SetBoolean("inside_run_tasks_until", inside_run_tasks_until_); |
297 state->SetString("max_tasks", base::SizeTToString(max_tasks_)); | 291 state->SetString("max_tasks", base::SizeTToString(max_tasks_)); |
298 } | 292 } |
299 | 293 |
300 base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskRunCountBelow( | 294 base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskRunCountBelow( |
301 size_t max_tasks) { | 295 size_t max_tasks) { |
302 return base::Bind(&OrderedSimpleTaskRunner::TaskRunCountBelowCallback, | 296 return base::Bind(&OrderedSimpleTaskRunner::TaskRunCountBelowCallback, |
303 max_tasks, | 297 max_tasks, |
304 base::Owned(new size_t(0))); | 298 base::Owned(new size_t(0))); |
305 } | 299 } |
306 | 300 |
307 bool OrderedSimpleTaskRunner::TaskRunCountBelowCallback(size_t max_tasks, | 301 bool OrderedSimpleTaskRunner::TaskRunCountBelowCallback(size_t max_tasks, |
308 size_t* tasks_run) { | 302 size_t* tasks_run) { |
309 return (*tasks_run)++ < max_tasks; | 303 return (*tasks_run)++ < max_tasks; |
310 } | 304 } |
311 | 305 |
312 base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskExistedInitially() { | 306 base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskExistedInitially() { |
313 // base::Bind takes a copy of pending_tasks_ | 307 std::set<size_t> existing_task_ids; |
| 308 for (const auto& task : pending_tasks_) |
| 309 existing_task_ids.insert(task.first.task_id()); |
314 return base::Bind(&OrderedSimpleTaskRunner::TaskExistedInitiallyCallback, | 310 return base::Bind(&OrderedSimpleTaskRunner::TaskExistedInitiallyCallback, |
315 base::Unretained(this), | 311 base::Unretained(this), std::move(existing_task_ids)); |
316 pending_tasks_); | |
317 } | 312 } |
318 | 313 |
319 bool OrderedSimpleTaskRunner::TaskExistedInitiallyCallback( | 314 bool OrderedSimpleTaskRunner::TaskExistedInitiallyCallback( |
320 const std::set<TestOrderablePendingTask>& existing_tasks) { | 315 const std::set<size_t>& existing_task_ids) { |
321 return existing_tasks.find(*pending_tasks_.begin()) != existing_tasks.end(); | 316 const TestOrderablePendingTaskInfo& task_info = pending_tasks_.begin()->first; |
| 317 return existing_task_ids.find(task_info.task_id()) != existing_task_ids.end(); |
322 } | 318 } |
323 | 319 |
324 base::Callback<bool(void)> OrderedSimpleTaskRunner::NowBefore( | 320 base::Callback<bool(void)> OrderedSimpleTaskRunner::NowBefore( |
325 base::TimeTicks stop_at) { | 321 base::TimeTicks stop_at) { |
326 return base::Bind(&OrderedSimpleTaskRunner::NowBeforeCallback, | 322 return base::Bind(&OrderedSimpleTaskRunner::NowBeforeCallback, |
327 base::Unretained(this), | 323 base::Unretained(this), |
328 stop_at); | 324 stop_at); |
329 } | 325 } |
330 bool OrderedSimpleTaskRunner::NowBeforeCallback(base::TimeTicks stop_at) { | 326 bool OrderedSimpleTaskRunner::NowBeforeCallback(base::TimeTicks stop_at) { |
331 return NextTaskTime() <= stop_at; | 327 return NextTaskTime() <= stop_at; |
332 } | 328 } |
333 | 329 |
334 base::Callback<bool(void)> OrderedSimpleTaskRunner::AdvanceNow() { | 330 base::Callback<bool(void)> OrderedSimpleTaskRunner::AdvanceNow() { |
335 return base::Bind(&OrderedSimpleTaskRunner::AdvanceNowCallback, | 331 return base::Bind(&OrderedSimpleTaskRunner::AdvanceNowCallback, |
336 base::Unretained(this)); | 332 base::Unretained(this)); |
337 } | 333 } |
338 | 334 |
339 bool OrderedSimpleTaskRunner::AdvanceNowCallback() { | 335 bool OrderedSimpleTaskRunner::AdvanceNowCallback() { |
340 base::TimeTicks next_task_time = NextTaskTime(); | 336 base::TimeTicks next_task_time = NextTaskTime(); |
341 if (now_src_->NowTicks() < next_task_time) { | 337 if (now_src_->NowTicks() < next_task_time) { |
342 now_src_->Advance(next_task_time - now_src_->NowTicks()); | 338 now_src_->Advance(next_task_time - now_src_->NowTicks()); |
343 } | 339 } |
344 return true; | 340 return true; |
345 } | 341 } |
346 | 342 |
347 } // namespace cc | 343 } // namespace cc |
OLD | NEW |