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

Side by Side Diff: cc/resources/worker_pool_unittest.cc

Issue 141163019: Re-land: cc: Remove WorkerPool class and instead use TaskGraphRunner directly. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix mode of task_graph_runner.h Created 6 years, 11 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
« no previous file with comments | « cc/resources/worker_pool_perftest.cc ('k') | cc/test/fake_tile_manager.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
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 "cc/resources/worker_pool.h"
6
7 #include <vector>
8
9 #include "cc/base/completion_event.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace cc {
13
14 namespace {
15
16 const int kWorkerPoolCount = 3;
17
18 class FakeWorkerPoolTaskImpl : public internal::WorkerPoolTask {
19 public:
20 FakeWorkerPoolTaskImpl(const base::Closure& callback,
21 const base::Closure& reply)
22 : callback_(callback),
23 reply_(reply) {
24 }
25
26 // Overridden from internal::WorkerPoolTask:
27 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
28 if (!callback_.is_null())
29 callback_.Run();
30 }
31 virtual void CompleteOnOriginThread() OVERRIDE {
32 if (!reply_.is_null())
33 reply_.Run();
34 }
35
36 private:
37 virtual ~FakeWorkerPoolTaskImpl() {}
38
39 const base::Closure callback_;
40 const base::Closure reply_;
41
42 DISALLOW_COPY_AND_ASSIGN(FakeWorkerPoolTaskImpl);
43 };
44
45 class FakeWorkerPool : public WorkerPool {
46 public:
47 struct Task {
48 Task(const base::Closure& callback,
49 const base::Closure& reply,
50 const base::Closure& dependent,
51 unsigned dependent_count,
52 unsigned priority) : callback(callback),
53 reply(reply),
54 dependent(dependent),
55 dependent_count(dependent_count),
56 priority(priority) {
57 }
58
59 base::Closure callback;
60 base::Closure reply;
61 base::Closure dependent;
62 unsigned dependent_count;
63 unsigned priority;
64 };
65 FakeWorkerPool() : WorkerPool() {}
66 virtual ~FakeWorkerPool() {}
67
68 static scoped_ptr<FakeWorkerPool> Create() {
69 return make_scoped_ptr(new FakeWorkerPool);
70 }
71
72 void ScheduleTasks(const std::vector<Task>& tasks) {
73 TaskVector new_tasks;
74 TaskVector new_dependents;
75 TaskGraph new_graph;
76
77 scoped_refptr<FakeWorkerPoolTaskImpl> new_completion_task(
78 new FakeWorkerPoolTaskImpl(
79 base::Bind(&FakeWorkerPool::OnTasksCompleted,
80 base::Unretained(this)),
81 base::Closure()));
82 scoped_ptr<internal::GraphNode> completion_node(
83 new internal::GraphNode(new_completion_task.get(), 0u));
84
85 for (std::vector<Task>::const_iterator it = tasks.begin();
86 it != tasks.end(); ++it) {
87 scoped_refptr<FakeWorkerPoolTaskImpl> new_task(
88 new FakeWorkerPoolTaskImpl(it->callback, it->reply));
89 scoped_ptr<internal::GraphNode> node(
90 new internal::GraphNode(new_task.get(), it->priority));
91
92 DCHECK(it->dependent_count);
93 for (unsigned i = 0; i < it->dependent_count; ++i) {
94 scoped_refptr<FakeWorkerPoolTaskImpl> new_dependent_task(
95 new FakeWorkerPoolTaskImpl(it->dependent, base::Closure()));
96 scoped_ptr<internal::GraphNode> dependent_node(
97 new internal::GraphNode(new_dependent_task.get(), it->priority));
98 dependent_node->add_dependent(completion_node.get());
99 completion_node->add_dependency();
100 node->add_dependent(dependent_node.get());
101 dependent_node->add_dependency();
102 new_graph.set(new_dependent_task.get(), dependent_node.Pass());
103 new_dependents.push_back(new_dependent_task.get());
104 }
105
106 new_graph.set(new_task.get(), node.Pass());
107 new_tasks.push_back(new_task.get());
108 }
109
110 new_graph.set(new_completion_task.get(), completion_node.Pass());
111
112 scheduled_tasks_completion_.reset(new CompletionEvent);
113
114 SetTaskGraph(&new_graph);
115
116 dependents_.swap(new_dependents);
117 completion_task_.swap(new_completion_task);
118 tasks_.swap(new_tasks);
119 }
120
121 void CheckForCompletedTasks() {
122 CheckForCompletedWorkerTasks();
123 }
124
125 void WaitForTasksToComplete() {
126 DCHECK(scheduled_tasks_completion_);
127 scheduled_tasks_completion_->Wait();
128 }
129
130 private:
131 typedef std::vector<scoped_refptr<internal::WorkerPoolTask> > TaskVector;
132
133 void OnTasksCompleted() {
134 DCHECK(scheduled_tasks_completion_);
135 scheduled_tasks_completion_->Signal();
136 }
137
138 TaskVector tasks_;
139 TaskVector dependents_;
140 scoped_refptr<FakeWorkerPoolTaskImpl> completion_task_;
141 scoped_ptr<CompletionEvent> scheduled_tasks_completion_;
142
143 DISALLOW_COPY_AND_ASSIGN(FakeWorkerPool);
144 };
145
146 class WorkerPoolTest : public testing::Test {
147 public:
148 WorkerPoolTest() {}
149 virtual ~WorkerPoolTest() {}
150
151 // Overridden from testing::Test:
152 virtual void SetUp() OVERRIDE {
153 for (int i = 0; i < kWorkerPoolCount; ++i)
154 worker_pools_[i] = FakeWorkerPool::Create();
155 }
156 virtual void TearDown() OVERRIDE {
157 for (int i = 0; i < kWorkerPoolCount; ++i) {
158 worker_pools_[i]->Shutdown();
159 worker_pools_[i]->CheckForCompletedTasks();
160 }
161 }
162
163 void ResetAllIdsforWorkerPool(int worker_pool_index) {
164 run_task_ids_[worker_pool_index].clear();
165 on_task_completed_ids_[worker_pool_index].clear();
166 }
167
168 void RunAllTasksforWorkerPool(int worker_pool_index) {
169 worker_pools_[worker_pool_index]->WaitForTasksToComplete();
170 worker_pools_[worker_pool_index]->CheckForCompletedTasks();
171 }
172
173 FakeWorkerPool* worker_pool(int worker_pool_index) {
174 return worker_pools_[worker_pool_index].get();
175 }
176
177 void RunTask(int worker_pool_index, unsigned id) {
178 run_task_ids_[worker_pool_index].push_back(id);
179 }
180
181 void OnTaskCompleted(int worker_pool_index, unsigned id) {
182 on_task_completed_ids_[worker_pool_index].push_back(id);
183 }
184
185 const std::vector<unsigned>& run_task_ids(int worker_pool_index) {
186 return run_task_ids_[worker_pool_index];
187 }
188
189 const std::vector<unsigned>& on_task_completed_ids(int worker_pool_index) {
190 return on_task_completed_ids_[worker_pool_index];
191 }
192
193 private:
194 scoped_ptr<FakeWorkerPool> worker_pools_[kWorkerPoolCount];
195 std::vector<unsigned> run_task_ids_[kWorkerPoolCount];
196 std::vector<unsigned> on_task_completed_ids_[kWorkerPoolCount];
197 };
198
199 TEST_F(WorkerPoolTest, Basic) {
200 for (int i = 0; i < kWorkerPoolCount; ++i) {
201 EXPECT_EQ(0u, run_task_ids(i).size());
202 EXPECT_EQ(0u, on_task_completed_ids(i).size());
203
204 worker_pool(i)->ScheduleTasks(
205 std::vector<FakeWorkerPool::Task>(
206 1,
207 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
208 base::Unretained(this),
209 i,
210 0u),
211 base::Bind(&WorkerPoolTest::OnTaskCompleted,
212 base::Unretained(this),
213 i,
214 0u),
215 base::Closure(),
216 1u,
217 0u)));
218 }
219
220 for (int i = 0; i < kWorkerPoolCount; ++i) {
221 RunAllTasksforWorkerPool(i);
222
223 EXPECT_EQ(1u, run_task_ids(i).size());
224 EXPECT_EQ(1u, on_task_completed_ids(i).size());
225 }
226
227 for (int i = 0; i < kWorkerPoolCount; ++i) {
228 worker_pool(i)->ScheduleTasks(
229 std::vector<FakeWorkerPool::Task>(
230 1,
231 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
232 base::Unretained(this),
233 i,
234 0u),
235 base::Bind(&WorkerPoolTest::OnTaskCompleted,
236 base::Unretained(this),
237 i,
238 0u),
239 base::Bind(&WorkerPoolTest::RunTask,
240 base::Unretained(this),
241 i,
242 0u),
243 1u,
244 0u)));
245 }
246
247 for (int i = 0; i < kWorkerPoolCount; ++i) {
248 RunAllTasksforWorkerPool(i);
249
250 EXPECT_EQ(3u, run_task_ids(i).size());
251 EXPECT_EQ(2u, on_task_completed_ids(i).size());
252 }
253
254 for (int i = 0; i < kWorkerPoolCount; ++i) {
255 worker_pool(i)->ScheduleTasks(
256 std::vector<FakeWorkerPool::Task>(
257 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
258 base::Unretained(this),
259 i,
260 0u),
261 base::Bind(&WorkerPoolTest::OnTaskCompleted,
262 base::Unretained(this),
263 i,
264 0u),
265 base::Bind(&WorkerPoolTest::RunTask,
266 base::Unretained(this),
267 i,
268 0u),
269 2u,
270 0u)));
271 }
272
273 for (int i = 0; i < kWorkerPoolCount; ++i) {
274 RunAllTasksforWorkerPool(i);
275
276 EXPECT_EQ(6u, run_task_ids(i).size());
277 EXPECT_EQ(3u, on_task_completed_ids(i).size());
278 }
279 }
280
281 TEST_F(WorkerPoolTest, Dependencies) {
282 for (int i = 0; i < kWorkerPoolCount; ++i) {
283 worker_pool(i)->ScheduleTasks(
284 std::vector<FakeWorkerPool::Task>(
285 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
286 base::Unretained(this),
287 i,
288 0u),
289 base::Bind(&WorkerPoolTest::OnTaskCompleted,
290 base::Unretained(this),
291 i,
292 0u),
293 base::Bind(&WorkerPoolTest::RunTask,
294 base::Unretained(this),
295 i,
296 1u),
297 1u,
298 0u)));
299 }
300
301 for (int i = 0; i < kWorkerPoolCount; ++i) {
302 RunAllTasksforWorkerPool(i);
303
304 // Check if task ran before dependent.
305 ASSERT_EQ(2u, run_task_ids(i).size());
306 EXPECT_EQ(0u, run_task_ids(i)[0]);
307 EXPECT_EQ(1u, run_task_ids(i)[1]);
308 ASSERT_EQ(1u, on_task_completed_ids(i).size());
309 EXPECT_EQ(0u, on_task_completed_ids(i)[0]);
310 }
311
312 for (int i = 0; i < kWorkerPoolCount; ++i) {
313 worker_pool(i)->ScheduleTasks(
314 std::vector<FakeWorkerPool::Task>(
315 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
316 base::Unretained(this),
317 i,
318 2u),
319 base::Bind(&WorkerPoolTest::OnTaskCompleted,
320 base::Unretained(this),
321 i,
322 2u),
323 base::Bind(&WorkerPoolTest::RunTask,
324 base::Unretained(this),
325 i,
326 3u),
327 2u,
328 0u)));
329 }
330
331 for (int i = 0; i < kWorkerPoolCount; ++i) {
332 RunAllTasksforWorkerPool(i);
333
334 // Task should only run once.
335 ASSERT_EQ(5u, run_task_ids(i).size());
336 EXPECT_EQ(2u, run_task_ids(i)[2]);
337 EXPECT_EQ(3u, run_task_ids(i)[3]);
338 EXPECT_EQ(3u, run_task_ids(i)[4]);
339 ASSERT_EQ(2u, on_task_completed_ids(i).size());
340 EXPECT_EQ(2u, on_task_completed_ids(i)[1]);
341 }
342 }
343
344 TEST_F(WorkerPoolTest, Priority) {
345 for (int i = 0; i < kWorkerPoolCount; ++i) {
346 FakeWorkerPool::Task tasks[] = {
347 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
348 base::Unretained(this),
349 i,
350 0u),
351 base::Bind(&WorkerPoolTest::OnTaskCompleted,
352 base::Unretained(this),
353 i,
354 0u),
355 base::Bind(&WorkerPoolTest::RunTask,
356 base::Unretained(this),
357 i,
358 2u),
359 1u,
360 1u), // Priority 1
361 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
362 base::Unretained(this),
363 i,
364 1u),
365 base::Bind(&WorkerPoolTest::OnTaskCompleted,
366 base::Unretained(this),
367 i,
368 1u),
369 base::Bind(&WorkerPoolTest::RunTask,
370 base::Unretained(this),
371 i,
372 3u),
373 1u,
374 0u) // Priority 0
375 };
376 worker_pool(i)->ScheduleTasks(
377 std::vector<FakeWorkerPool::Task>(tasks, tasks + arraysize(tasks)));
378 }
379
380 for (int i = 0; i < kWorkerPoolCount; ++i) {
381 RunAllTasksforWorkerPool(i);
382
383 // Check if tasks ran in order of priority.
384 ASSERT_EQ(4u, run_task_ids(i).size());
385 EXPECT_EQ(1u, run_task_ids(i)[0]);
386 EXPECT_EQ(3u, run_task_ids(i)[1]);
387 EXPECT_EQ(0u, run_task_ids(i)[2]);
388 EXPECT_EQ(2u, run_task_ids(i)[3]);
389 ASSERT_EQ(2u, on_task_completed_ids(i).size());
390 EXPECT_EQ(1u, on_task_completed_ids(i)[0]);
391 EXPECT_EQ(0u, on_task_completed_ids(i)[1]);
392 }
393
394 for (int i = 0; i < kWorkerPoolCount; ++i)
395 ResetAllIdsforWorkerPool(i);
396
397 for (int i = 0; i < kWorkerPoolCount; ++i) {
398 std::vector<FakeWorkerPool::Task> tasks;
399 tasks.push_back(
400 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
401 base::Unretained(this),
402 i,
403 0u),
404 base::Bind(&WorkerPoolTest::OnTaskCompleted,
405 base::Unretained(this),
406 i,
407 0u),
408 base::Bind(&WorkerPoolTest::RunTask,
409 base::Unretained(this),
410 i,
411 3u),
412 1u, // 1 dependent
413 1u)); // Priority 1
414 tasks.push_back(
415 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
416 base::Unretained(this),
417 i,
418 1u),
419 base::Bind(&WorkerPoolTest::OnTaskCompleted,
420 base::Unretained(this),
421 i,
422 1u),
423 base::Bind(&WorkerPoolTest::RunTask,
424 base::Unretained(this),
425 i,
426 4u),
427 2u, // 2 dependents
428 1u)); // Priority 1
429 tasks.push_back(
430 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask,
431 base::Unretained(this),
432 i,
433 2u),
434 base::Bind(&WorkerPoolTest::OnTaskCompleted,
435 base::Unretained(this),
436 i,
437 2u),
438 base::Bind(&WorkerPoolTest::RunTask,
439 base::Unretained(this),
440 i,
441 5u),
442 1u, // 1 dependent
443 0u)); // Priority 0
444 worker_pool(i)->ScheduleTasks(tasks);
445 }
446
447 for (int i = 0; i < kWorkerPoolCount; ++i) {
448 RunAllTasksforWorkerPool(i);
449
450 // Check if tasks ran in order of priority and that task with more
451 // dependents ran first when priority is the same.
452 ASSERT_LE(3u, run_task_ids(i).size());
453 EXPECT_EQ(2u, run_task_ids(i)[0]);
454 EXPECT_EQ(5u, run_task_ids(i)[1]);
455 EXPECT_EQ(1u, run_task_ids(i)[2]);
456 ASSERT_EQ(3u, on_task_completed_ids(i).size());
457 EXPECT_EQ(2u, on_task_completed_ids(i)[0]);
458 EXPECT_EQ(1u, on_task_completed_ids(i)[1]);
459 EXPECT_EQ(0u, on_task_completed_ids(i)[2]);
460 }
461 }
462
463 } // namespace
464
465 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/worker_pool_perftest.cc ('k') | cc/test/fake_tile_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698