Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: cc/test/ordered_simple_task_runner.cc

Issue 387493002: Fixing and enhancing OrderedSimpleTaskRunner to allow 100% deterministic tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Using SizeTToString rather then c++11 to_string. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698