OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/resources/worker_pool.h" | 5 #include "cc/resources/worker_pool.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "cc/base/completion_event.h" | 9 #include "cc/base/completion_event.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 dependent_count(dependent_count), | 53 dependent_count(dependent_count), |
54 priority(priority) { | 54 priority(priority) { |
55 } | 55 } |
56 | 56 |
57 base::Closure callback; | 57 base::Closure callback; |
58 base::Closure reply; | 58 base::Closure reply; |
59 base::Closure dependent; | 59 base::Closure dependent; |
60 unsigned dependent_count; | 60 unsigned dependent_count; |
61 unsigned priority; | 61 unsigned priority; |
62 }; | 62 }; |
63 FakeWorkerPool() : WorkerPool(1, "test") {} | 63 FakeWorkerPool() : WorkerPool() {} |
64 virtual ~FakeWorkerPool() {} | 64 virtual ~FakeWorkerPool() {} |
65 | 65 |
66 static scoped_ptr<FakeWorkerPool> Create() { | 66 static scoped_ptr<FakeWorkerPool> Create() { |
67 return make_scoped_ptr(new FakeWorkerPool); | 67 return make_scoped_ptr(new FakeWorkerPool); |
68 } | 68 } |
69 | 69 |
70 void ScheduleTasks(const std::vector<Task>& tasks) { | 70 void ScheduleTasks(const std::vector<Task>& tasks) { |
71 TaskVector new_tasks; | 71 TaskVector new_tasks; |
72 TaskVector new_dependents; | 72 TaskVector new_dependents; |
73 TaskGraph new_graph; | 73 TaskGraph new_graph; |
74 | 74 |
75 scoped_refptr<FakeWorkerPoolTaskImpl> new_completion_task( | 75 scoped_refptr<FakeWorkerPoolTaskImpl> new_completion_task( |
76 new FakeWorkerPoolTaskImpl( | 76 new FakeWorkerPoolTaskImpl( |
77 base::Bind(&FakeWorkerPool::OnTasksCompleted, | 77 base::Bind(&FakeWorkerPool::OnTasksCompleted, |
78 base::Unretained(this)), | 78 base::Unretained(this)), |
79 base::Closure())); | 79 base::Closure())); |
80 scoped_ptr<internal::GraphNode> completion_node( | 80 scoped_ptr<internal::GraphNode> completion_node( |
81 new internal::GraphNode(new_completion_task.get(), 0u)); | 81 new internal::GraphNode(new_completion_task.get(), 0u)); |
82 | 82 |
83 | |
84 | |
reveman
2014/01/09 16:04:26
no need to add these 2 blank lines
sohanjg
2014/01/10 15:12:31
Done.
| |
83 for (std::vector<Task>::const_iterator it = tasks.begin(); | 85 for (std::vector<Task>::const_iterator it = tasks.begin(); |
84 it != tasks.end(); ++it) { | 86 it != tasks.end(); ++it) { |
85 scoped_refptr<FakeWorkerPoolTaskImpl> new_task( | 87 scoped_refptr<FakeWorkerPoolTaskImpl> new_task( |
86 new FakeWorkerPoolTaskImpl(it->callback, it->reply)); | 88 new FakeWorkerPoolTaskImpl(it->callback, it->reply)); |
87 scoped_ptr<internal::GraphNode> node( | 89 scoped_ptr<internal::GraphNode> node( |
88 new internal::GraphNode(new_task.get(), it->priority)); | 90 new internal::GraphNode(new_task.get(), it->priority)); |
89 | 91 |
90 DCHECK(it->dependent_count); | 92 DCHECK(it->dependent_count); |
91 for (unsigned i = 0; i < it->dependent_count; ++i) { | 93 for (unsigned i = 0; i < it->dependent_count; ++i) { |
92 scoped_refptr<FakeWorkerPoolTaskImpl> new_dependent_task( | 94 scoped_refptr<FakeWorkerPoolTaskImpl> new_dependent_task( |
93 new FakeWorkerPoolTaskImpl(it->dependent, base::Closure())); | 95 new FakeWorkerPoolTaskImpl(it->dependent, base::Closure())); |
94 scoped_ptr<internal::GraphNode> dependent_node( | 96 scoped_ptr<internal::GraphNode> dependent_node( |
95 new internal::GraphNode(new_dependent_task.get(), it->priority)); | 97 new internal::GraphNode(new_dependent_task.get(), it->priority)); |
96 dependent_node->add_dependent(completion_node.get()); | 98 dependent_node->add_dependent(completion_node.get()); |
97 completion_node->add_dependency(); | 99 completion_node->add_dependency(); |
98 node->add_dependent(dependent_node.get()); | 100 node->add_dependent(dependent_node.get()); |
99 dependent_node->add_dependency(); | 101 dependent_node->add_dependency(); |
100 new_graph.set(new_dependent_task.get(), dependent_node.Pass()); | 102 new_graph.set(new_dependent_task.get(), dependent_node.Pass()); |
101 new_dependents.push_back(new_dependent_task.get()); | 103 new_dependents.push_back(new_dependent_task.get()); |
102 } | 104 } |
103 | 105 |
104 new_graph.set(new_task.get(), node.Pass()); | 106 new_graph.set(new_task.get(), node.Pass()); |
105 new_tasks.push_back(new_task.get()); | 107 new_tasks.push_back(new_task.get()); |
106 } | 108 } |
107 | 109 |
108 new_graph.set(new_completion_task.get(), completion_node.Pass()); | 110 new_graph.set(new_completion_task.get(), completion_node.Pass()); |
109 | 111 |
110 scheduled_tasks_completion_.reset(new CompletionEvent); | 112 scheduled_tasks_completion_.reset(new CompletionEvent); |
111 | |
reveman
2014/01/09 16:04:26
no need to remove this blank line
sohanjg
2014/01/10 15:12:31
Done.
| |
112 SetTaskGraph(&new_graph); | 113 SetTaskGraph(&new_graph); |
113 | |
reveman
2014/01/09 16:04:26
no need to remove this blank line
sohanjg
2014/01/10 15:12:31
Done.
| |
114 dependents_.swap(new_dependents); | 114 dependents_.swap(new_dependents); |
115 completion_task_.swap(new_completion_task); | 115 completion_task_.swap(new_completion_task); |
116 tasks_.swap(new_tasks); | 116 tasks_.swap(new_tasks); |
117 } | 117 } |
118 | 118 |
119 void WaitForTasksToComplete() { | 119 void WaitForTasksToComplete() { |
120 DCHECK(scheduled_tasks_completion_); | 120 DCHECK(scheduled_tasks_completion_); |
121 scheduled_tasks_completion_->Wait(); | 121 scheduled_tasks_completion_->Wait(); |
122 } | 122 } |
123 | 123 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 ASSERT_LE(3u, run_task_ids().size()); | 382 ASSERT_LE(3u, run_task_ids().size()); |
383 EXPECT_EQ(2u, run_task_ids()[0]); | 383 EXPECT_EQ(2u, run_task_ids()[0]); |
384 EXPECT_EQ(5u, run_task_ids()[1]); | 384 EXPECT_EQ(5u, run_task_ids()[1]); |
385 EXPECT_EQ(1u, run_task_ids()[2]); | 385 EXPECT_EQ(1u, run_task_ids()[2]); |
386 ASSERT_EQ(3u, on_task_completed_ids().size()); | 386 ASSERT_EQ(3u, on_task_completed_ids().size()); |
387 EXPECT_EQ(2u, on_task_completed_ids()[0]); | 387 EXPECT_EQ(2u, on_task_completed_ids()[0]); |
388 EXPECT_EQ(1u, on_task_completed_ids()[1]); | 388 EXPECT_EQ(1u, on_task_completed_ids()[1]); |
389 EXPECT_EQ(0u, on_task_completed_ids()[2]); | 389 EXPECT_EQ(0u, on_task_completed_ids()[2]); |
390 } | 390 } |
391 | 391 |
392 TEST_F(WorkerPoolTest, MultipleWorkerPoolBasic) { | |
393 ResetIds(); | |
394 | |
395 EXPECT_EQ(0u, run_task_ids().size()); | |
396 EXPECT_EQ(0u, on_task_completed_ids().size()); | |
397 | |
398 // Setup multiple workerpool. | |
399 scoped_ptr<FakeWorkerPool>worker_pool1 = FakeWorkerPool::Create(); | |
400 scoped_ptr<FakeWorkerPool>worker_pool2 = FakeWorkerPool::Create(); | |
401 scoped_ptr<FakeWorkerPool>worker_pool3 = FakeWorkerPool::Create(); | |
402 | |
403 worker_pool1->ScheduleTasks( | |
404 std::vector<FakeWorkerPool::Task>( | |
405 1, | |
406 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
407 base::Unretained(this), | |
408 0u), | |
409 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
410 base::Unretained(this), | |
411 0u), | |
412 base::Closure(), | |
413 1u, | |
414 0u))); | |
415 worker_pool1->WaitForTasksToComplete(); | |
416 worker_pool1->CheckForCompletedTasks(); | |
417 | |
418 EXPECT_EQ(1u, run_task_ids().size()); | |
419 EXPECT_EQ(1u, on_task_completed_ids().size()); | |
420 | |
421 worker_pool2->ScheduleTasks( | |
422 std::vector<FakeWorkerPool::Task>( | |
423 1, | |
424 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
425 base::Unretained(this), | |
426 0u), | |
427 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
428 base::Unretained(this), | |
429 0u), | |
430 base::Bind(&WorkerPoolTest::RunTask, | |
431 base::Unretained(this), | |
432 0u), | |
433 1u, | |
434 0u))); | |
435 | |
436 worker_pool2->WaitForTasksToComplete(); | |
437 worker_pool2->CheckForCompletedTasks(); | |
438 | |
439 EXPECT_EQ(3u, run_task_ids().size()); | |
440 EXPECT_EQ(2u, on_task_completed_ids().size()); | |
441 | |
442 worker_pool3->ScheduleTasks( | |
443 std::vector<FakeWorkerPool::Task>( | |
444 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
445 base::Unretained(this), | |
446 0u), | |
447 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
448 base::Unretained(this), | |
449 0u), | |
450 base::Bind(&WorkerPoolTest::RunTask, | |
451 base::Unretained(this), | |
452 0u), | |
453 2u, | |
454 0u))); | |
455 worker_pool3->WaitForTasksToComplete(); | |
456 worker_pool3->CheckForCompletedTasks(); | |
457 | |
458 EXPECT_EQ(6u, run_task_ids().size()); | |
459 EXPECT_EQ(3u, on_task_completed_ids().size()); | |
460 } | |
461 | |
462 TEST_F(WorkerPoolTest, MultipleWorkerPoolDependencies) { | |
463 // Setup multiple workerpool. | |
464 scoped_ptr<FakeWorkerPool>worker_pool1 = FakeWorkerPool::Create(); | |
465 scoped_ptr<FakeWorkerPool>worker_pool2 = FakeWorkerPool::Create(); | |
466 | |
467 worker_pool1->ScheduleTasks( | |
468 std::vector<FakeWorkerPool::Task>( | |
469 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
470 base::Unretained(this), | |
471 0u), | |
472 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
473 base::Unretained(this), | |
474 0u), | |
475 base::Bind(&WorkerPoolTest::RunTask, | |
476 base::Unretained(this), | |
477 1u), | |
478 1u, | |
479 0u))); | |
480 worker_pool1->WaitForTasksToComplete(); | |
481 worker_pool1->CheckForCompletedTasks(); | |
482 | |
483 // Check if task ran before dependent. | |
484 ASSERT_EQ(2u, run_task_ids().size()); | |
485 EXPECT_EQ(0u, run_task_ids()[0]); | |
486 EXPECT_EQ(1u, run_task_ids()[1]); | |
487 ASSERT_EQ(1u, on_task_completed_ids().size()); | |
488 EXPECT_EQ(0u, on_task_completed_ids()[0]); | |
489 | |
490 worker_pool2->ScheduleTasks( | |
491 std::vector<FakeWorkerPool::Task>( | |
492 1, FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
493 base::Unretained(this), | |
494 2u), | |
495 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
496 base::Unretained(this), | |
497 2u), | |
498 base::Bind(&WorkerPoolTest::RunTask, | |
499 base::Unretained(this), | |
500 3u), | |
501 2u, | |
502 0u))); | |
503 worker_pool2->WaitForTasksToComplete(); | |
504 worker_pool2->CheckForCompletedTasks(); | |
505 | |
506 // Task should only run once. | |
507 ASSERT_EQ(5u, run_task_ids().size()); | |
508 EXPECT_EQ(2u, run_task_ids()[2]); | |
509 EXPECT_EQ(3u, run_task_ids()[3]); | |
510 EXPECT_EQ(3u, run_task_ids()[4]); | |
511 ASSERT_EQ(2u, on_task_completed_ids().size()); | |
512 EXPECT_EQ(2u, on_task_completed_ids()[1]); | |
513 } | |
514 | |
515 TEST_F(WorkerPoolTest, MultipleWorkerPoolPriority) { | |
516 // Setup multiple workerpool. | |
517 scoped_ptr<FakeWorkerPool>worker_pool1 = FakeWorkerPool::Create(); | |
518 scoped_ptr<FakeWorkerPool>worker_pool2 = FakeWorkerPool::Create(); | |
519 { | |
520 FakeWorkerPool::Task tasks[] = { | |
521 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
522 base::Unretained(this), | |
523 0u), | |
524 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
525 base::Unretained(this), | |
526 0u), | |
527 base::Bind(&WorkerPoolTest::RunTask, | |
528 base::Unretained(this), | |
529 2u), | |
530 1u, | |
531 1u), // Priority 1 | |
532 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
533 base::Unretained(this), | |
534 1u), | |
535 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
536 base::Unretained(this), | |
537 1u), | |
538 base::Bind(&WorkerPoolTest::RunTask, | |
539 base::Unretained(this), | |
540 3u), | |
541 1u, | |
542 0u) // Priority 0 | |
543 }; | |
544 worker_pool1->ScheduleTasks( | |
545 std::vector<FakeWorkerPool::Task>(tasks, tasks + arraysize(tasks))); | |
546 } | |
547 worker_pool1->WaitForTasksToComplete(); | |
548 worker_pool1->CheckForCompletedTasks(); | |
549 | |
550 // Check if tasks ran in order of priority. | |
551 ASSERT_EQ(4u, run_task_ids().size()); | |
552 EXPECT_EQ(1u, run_task_ids()[0]); | |
553 EXPECT_EQ(3u, run_task_ids()[1]); | |
554 EXPECT_EQ(0u, run_task_ids()[2]); | |
555 EXPECT_EQ(2u, run_task_ids()[3]); | |
556 ASSERT_EQ(2u, on_task_completed_ids().size()); | |
557 EXPECT_EQ(1u, on_task_completed_ids()[0]); | |
558 EXPECT_EQ(0u, on_task_completed_ids()[1]); | |
559 | |
560 ResetIds(); | |
561 { | |
562 std::vector<FakeWorkerPool::Task> tasks; | |
563 tasks.push_back( | |
564 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
565 base::Unretained(this), | |
566 0u), | |
567 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
568 base::Unretained(this), | |
569 0u), | |
570 base::Bind(&WorkerPoolTest::RunTask, | |
571 base::Unretained(this), | |
572 3u), | |
573 1u, // 1 dependent | |
574 1u)); // Priority 1 | |
575 tasks.push_back( | |
576 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
577 base::Unretained(this), | |
578 1u), | |
579 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
580 base::Unretained(this), | |
581 1u), | |
582 base::Bind(&WorkerPoolTest::RunTask, | |
583 base::Unretained(this), | |
584 4u), | |
585 2u, // 2 dependents | |
586 1u)); // Priority 1 | |
587 tasks.push_back( | |
588 FakeWorkerPool::Task(base::Bind(&WorkerPoolTest::RunTask, | |
589 base::Unretained(this), | |
590 2u), | |
591 base::Bind(&WorkerPoolTest::OnTaskCompleted, | |
592 base::Unretained(this), | |
593 2u), | |
594 base::Bind(&WorkerPoolTest::RunTask, | |
595 base::Unretained(this), | |
596 5u), | |
597 1u, // 1 dependent | |
598 0u)); // Priority 0 | |
599 worker_pool2->ScheduleTasks(tasks); | |
600 } | |
601 worker_pool2->WaitForTasksToComplete(); | |
602 worker_pool2->CheckForCompletedTasks(); | |
603 | |
604 // Check if tasks ran in order of priority and that task with more | |
605 // dependents ran first when priority is the same. | |
606 ASSERT_LE(3u, run_task_ids().size()); | |
607 EXPECT_EQ(2u, run_task_ids()[0]); | |
608 EXPECT_EQ(5u, run_task_ids()[1]); | |
609 EXPECT_EQ(1u, run_task_ids()[2]); | |
610 ASSERT_EQ(3u, on_task_completed_ids().size()); | |
611 EXPECT_EQ(2u, on_task_completed_ids()[0]); | |
612 EXPECT_EQ(1u, on_task_completed_ids()[1]); | |
613 EXPECT_EQ(0u, on_task_completed_ids()[2]); | |
614 } | |
reveman
2014/01/09 16:04:26
I'd like to see the tests run tasks from multiple
| |
615 | |
392 } // namespace | 616 } // namespace |
393 | 617 |
394 } // namespace cc | 618 } // namespace cc |
OLD | NEW |