| 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 |