Chromium Code Reviews| 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 |