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 <algorithm> | 7 #include <algorithm> |
8 #include <deque> | 8 #include <deque> |
9 #include <sstream> | |
10 #include <string> | |
9 | 11 |
10 #include "base/logging.h" | 12 #include "base/debug/trace_event.h" |
13 #include "base/debug/trace_event_argument.h" | |
14 #include "base/strings/string_number_conversions.h" | |
15 | |
16 #define TRACE_TASK(function, task) \ | |
17 TRACE_EVENT_INSTANT1( \ | |
18 "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", TaskAsValue(task)); | |
19 | |
20 #define TRACE_TASK_RUN(function, tag, task) | |
11 | 21 |
12 namespace { | 22 namespace { |
13 | 23 |
14 bool TestPendingTaskComparator(const base::TestPendingTask& lhs, | 24 bool TestPendingTaskComparator(const base::TestPendingTask& lhs, |
15 const base::TestPendingTask& rhs) { | 25 const base::TestPendingTask& rhs) { |
16 return lhs.ShouldRunBefore(rhs); | 26 return lhs.ShouldRunBefore(rhs); |
17 } | 27 } |
18 | 28 |
29 void TaskAsValueInto(const base::TestPendingTask& task, | |
30 base::debug::TracedValue* state) { | |
31 state->SetInteger("run_at", task.GetTimeToRun().ToInternalValue()); | |
32 state->SetString("function", task.location.ToString()); | |
19 } | 33 } |
20 | 34 |
35 scoped_refptr<base::debug::ConvertableToTraceFormat> TaskAsValue( | |
36 const base::TestPendingTask& task) { | |
37 scoped_refptr<base::debug::TracedValue> state = | |
38 new base::debug::TracedValue(); | |
39 TaskAsValueInto(task, state); | |
40 return state; | |
41 } | |
42 | |
43 } // namespace | |
44 | |
21 namespace cc { | 45 namespace cc { |
22 | 46 |
23 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner() {} | 47 scoped_refptr<base::debug::ConvertableToTraceFormat> |
48 OrderedSimpleTaskRunner::AsValue() const { | |
49 scoped_refptr<base::debug::TracedValue> state = | |
50 new base::debug::TracedValue(); | |
51 | |
52 for (std::deque<base::TestPendingTask>::const_iterator it = | |
53 pending_tasks_.begin(); | |
54 it != pending_tasks_.end(); | |
55 ++it) { | |
56 state->BeginDictionary( | |
57 base::SizeTToString(std::distance(pending_tasks_.begin(), it)).c_str()); | |
58 TaskAsValueInto(*it, state); | |
59 state->EndDictionary(); | |
60 } | |
61 return state; | |
62 } | |
63 | |
64 OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(bool advance_now) | |
65 : advance_now_(advance_now), now_(), inside_run_pending_tasks_(false) { | |
66 } | |
24 | 67 |
25 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} | 68 OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {} |
26 | 69 |
Sami
2014/08/19 18:45:04
// static
| |
70 void OrderedSimpleTaskRunner::SortTasks( | |
71 std::deque<base::TestPendingTask>* tasks) { | |
72 std::stable_sort(tasks->begin(), tasks->end(), TestPendingTaskComparator); | |
73 } | |
74 | |
75 bool OrderedSimpleTaskRunner::PostDelayedTask( | |
76 const tracked_objects::Location& from_here, | |
77 const base::Closure& task, | |
78 base::TimeDelta delay) { | |
79 DCHECK(thread_checker_.CalledOnValidThread()); | |
80 base::TestPendingTask pt( | |
81 from_here, task, Now(), delay, base::TestPendingTask::NESTABLE); | |
82 | |
83 TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt); | |
84 | |
85 pending_tasks_.push_back(pt); | |
86 SortTasks(&pending_tasks_); | |
87 return true; | |
88 } | |
89 | |
90 bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask( | |
91 const tracked_objects::Location& from_here, | |
92 const base::Closure& task, | |
93 base::TimeDelta delay) { | |
94 DCHECK(thread_checker_.CalledOnValidThread()); | |
95 base::TestPendingTask pt( | |
96 from_here, task, Now(), delay, base::TestPendingTask::NON_NESTABLE); | |
97 | |
98 TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt); | |
99 | |
100 pending_tasks_.push_back(pt); | |
101 SortTasks(&pending_tasks_); | |
102 return true; | |
103 } | |
104 | |
27 void OrderedSimpleTaskRunner::RunPendingTasks() { | 105 void OrderedSimpleTaskRunner::RunPendingTasks() { |
106 TRACE_EVENT2("cc", | |
107 "OrderedSimpleTaskRunner::RunPendingTasks", | |
108 "now", | |
109 Now(), | |
110 "tasks", | |
111 AsValue()); | |
28 DCHECK(thread_checker_.CalledOnValidThread()); | 112 DCHECK(thread_checker_.CalledOnValidThread()); |
113 | |
114 if (inside_run_pending_tasks_) | |
115 return; | |
116 inside_run_pending_tasks_ = true; | |
117 | |
29 // Swap with a local variable to avoid re-entrancy problems. | 118 // Swap with a local variable to avoid re-entrancy problems. |
30 std::deque<base::TestPendingTask> tasks_to_run; | 119 std::deque<base::TestPendingTask> tasks_to_run; |
31 tasks_to_run.swap(pending_tasks_); | 120 tasks_to_run.swap(pending_tasks_); |
32 std::stable_sort(tasks_to_run.begin(), | 121 |
33 tasks_to_run.end(), | 122 std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); |
34 TestPendingTaskComparator); | 123 for (; it != tasks_to_run.end(); ++it) { |
35 for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin(); | 124 base::TimeTicks task_time = it->GetTimeToRun(); |
36 it != tasks_to_run.end(); ++it) { | 125 |
37 it->task.Run(); | 126 // Have new items been added to pending_tasks which need to run before this |
127 // task? | |
128 if (pending_tasks_.size() > 0 && | |
129 task_time > pending_tasks_.begin()->GetTimeToRun()) { | |
130 break; | |
131 } | |
132 | |
133 // Is the task in the future? | |
134 if (task_time > Now()) { | |
135 if (!advance_now_) | |
136 break; | |
137 else | |
138 SetNow(task_time); | |
139 } | |
140 | |
141 { | |
142 TRACE_EVENT1("cc", | |
143 "OrderedSimpleTaskRunner::RunPendingTasks running", | |
144 "task", | |
145 TaskAsValue(*it)); | |
146 it->task.Run(); | |
147 } | |
38 } | 148 } |
149 | |
150 // Push any remaining tasks back into the pending queue | |
151 for (; it != tasks_to_run.end(); ++it) { | |
152 pending_tasks_.push_front(*it); | |
153 } | |
154 std::stable_sort( | |
Sami
2014/08/19 18:45:04
Can you call SortTasks here?
| |
155 pending_tasks_.begin(), pending_tasks_.end(), TestPendingTaskComparator); | |
156 | |
157 inside_run_pending_tasks_ = false; | |
158 } | |
159 | |
160 base::TimeTicks OrderedSimpleTaskRunner::Now() const { | |
161 return now_; | |
162 } | |
163 | |
164 base::TimeDelta OrderedSimpleTaskRunner::DelayToNextPendingTask() { | |
165 DCHECK(thread_checker_.CalledOnValidThread()); | |
166 | |
167 base::TimeDelta delay = pending_tasks_.front().GetTimeToRun() - Now(); | |
168 if (delay > base::TimeDelta()) | |
169 return delay; | |
170 return base::TimeDelta(); | |
171 } | |
172 | |
173 void OrderedSimpleTaskRunner::SetAutoAdvanceNowToPendingTasks( | |
174 bool advance_now) { | |
175 advance_now_ = advance_now; | |
176 } | |
177 | |
178 void OrderedSimpleTaskRunner::SetNow(base::TimeTicks time) { | |
179 TRACE_EVENT_INSTANT2("cc", | |
Sami
2014/08/19 18:45:04
Random question: can we get traces out of unit tes
| |
180 "OrderedSimpleTaskRunner::SetNow", | |
181 TRACE_EVENT_SCOPE_THREAD, | |
182 "current", | |
183 time, | |
184 "new", | |
185 time); | |
186 DCHECK(time >= now_); | |
187 now_ = time; | |
39 } | 188 } |
40 | 189 |
41 } // namespace cc | 190 } // namespace cc |
OLD | NEW |