OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/task_scheduler/scheduler_worker_pool_impl.h" | 5 #include "base/task_scheduler/scheduler_worker_pool_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <unordered_set> | 10 #include <unordered_set> |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 117 |
118 DelayedTaskManager delayed_task_manager_; | 118 DelayedTaskManager delayed_task_manager_; |
119 | 119 |
120 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplTest); | 120 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplTest); |
121 }; | 121 }; |
122 | 122 |
123 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode( | 123 scoped_refptr<TaskRunner> CreateTaskRunnerWithExecutionMode( |
124 SchedulerWorkerPoolImpl* worker_pool, | 124 SchedulerWorkerPoolImpl* worker_pool, |
125 test::ExecutionMode execution_mode) { | 125 test::ExecutionMode execution_mode) { |
126 // Allow tasks posted to the returned TaskRunner to wait on a WaitableEvent. | 126 // Allow tasks posted to the returned TaskRunner to wait on a WaitableEvent. |
127 const TaskTraits traits = TaskTraits().WithBaseSyncPrimitives(); | 127 const TaskTraits traits = test::CreateTaskTraits().WithBaseSyncPrimitives(); |
128 switch (execution_mode) { | 128 switch (execution_mode) { |
129 case test::ExecutionMode::PARALLEL: | 129 case test::ExecutionMode::PARALLEL: |
130 return worker_pool->CreateTaskRunnerWithTraits(traits); | 130 return worker_pool->CreateTaskRunnerWithTraits(traits); |
131 case test::ExecutionMode::SEQUENCED: | 131 case test::ExecutionMode::SEQUENCED: |
132 return worker_pool->CreateSequencedTaskRunnerWithTraits(traits); | 132 return worker_pool->CreateSequencedTaskRunnerWithTraits(traits); |
133 default: | 133 default: |
134 // Fall through. | 134 // Fall through. |
135 break; | 135 break; |
136 } | 136 } |
137 ADD_FAILURE() << "Unexpected ExecutionMode"; | 137 ADD_FAILURE() << "Unexpected ExecutionMode"; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 355 |
356 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner | 356 // Verify that the RunsTasksOnCurrentThread() method of a SEQUENCED TaskRunner |
357 // returns false when called from a task that isn't part of the sequence. Note: | 357 // returns false when called from a task that isn't part of the sequence. Note: |
358 // Tests that use TestTaskFactory already verify that RunsTasksOnCurrentThread() | 358 // Tests that use TestTaskFactory already verify that RunsTasksOnCurrentThread() |
359 // returns true when appropriate so this method complements it to get full | 359 // returns true when appropriate so this method complements it to get full |
360 // coverage of that method. | 360 // coverage of that method. |
361 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) { | 361 TEST_P(TaskSchedulerWorkerPoolImplTest, SequencedRunsTasksOnCurrentThread) { |
362 auto task_runner = | 362 auto task_runner = |
363 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()); | 363 CreateTaskRunnerWithExecutionMode(worker_pool_.get(), GetParam()); |
364 auto sequenced_task_runner = | 364 auto sequenced_task_runner = |
365 worker_pool_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); | 365 worker_pool_->CreateSequencedTaskRunnerWithTraits( |
| 366 test::CreateTaskTraits()); |
366 | 367 |
367 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 368 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
368 WaitableEvent::InitialState::NOT_SIGNALED); | 369 WaitableEvent::InitialState::NOT_SIGNALED); |
369 task_runner->PostTask( | 370 task_runner->PostTask( |
370 FROM_HERE, | 371 FROM_HERE, |
371 BindOnce( | 372 BindOnce( |
372 [](scoped_refptr<TaskRunner> sequenced_task_runner, | 373 [](scoped_refptr<TaskRunner> sequenced_task_runner, |
373 WaitableEvent* task_ran) { | 374 WaitableEvent* task_ran) { |
374 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); | 375 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); |
375 task_ran->Signal(); | 376 task_ran->Signal(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 WaitableEvent task_2_scheduled(WaitableEvent::ResetPolicy::MANUAL, | 419 WaitableEvent task_2_scheduled(WaitableEvent::ResetPolicy::MANUAL, |
419 WaitableEvent::InitialState::NOT_SIGNALED); | 420 WaitableEvent::InitialState::NOT_SIGNALED); |
420 | 421 |
421 // This event is used to prevent a task from completing before the other task | 422 // This event is used to prevent a task from completing before the other task |
422 // is scheduled. If that happened, both tasks could run on the same worker and | 423 // is scheduled. If that happened, both tasks could run on the same worker and |
423 // this test couldn't verify that the correct number of workers were woken up. | 424 // this test couldn't verify that the correct number of workers were woken up. |
424 WaitableEvent barrier(WaitableEvent::ResetPolicy::MANUAL, | 425 WaitableEvent barrier(WaitableEvent::ResetPolicy::MANUAL, |
425 WaitableEvent::InitialState::NOT_SIGNALED); | 426 WaitableEvent::InitialState::NOT_SIGNALED); |
426 | 427 |
427 worker_pool_ | 428 worker_pool_ |
428 ->CreateTaskRunnerWithTraits(TaskTraits().WithBaseSyncPrimitives()) | 429 ->CreateTaskRunnerWithTraits( |
| 430 test::CreateTaskTraits().WithBaseSyncPrimitives()) |
429 ->PostTask(FROM_HERE, | 431 ->PostTask(FROM_HERE, |
430 Bind(&TaskPostedBeforeStart, Unretained(&task_1_thread_ref), | 432 Bind(&TaskPostedBeforeStart, Unretained(&task_1_thread_ref), |
431 Unretained(&task_1_scheduled), Unretained(&barrier))); | 433 Unretained(&task_1_scheduled), Unretained(&barrier))); |
432 worker_pool_ | 434 worker_pool_ |
433 ->CreateTaskRunnerWithTraits(TaskTraits().WithBaseSyncPrimitives()) | 435 ->CreateTaskRunnerWithTraits( |
| 436 test::CreateTaskTraits().WithBaseSyncPrimitives()) |
434 ->PostTask(FROM_HERE, | 437 ->PostTask(FROM_HERE, |
435 Bind(&TaskPostedBeforeStart, Unretained(&task_2_thread_ref), | 438 Bind(&TaskPostedBeforeStart, Unretained(&task_2_thread_ref), |
436 Unretained(&task_2_scheduled), Unretained(&barrier))); | 439 Unretained(&task_2_scheduled), Unretained(&barrier))); |
437 | 440 |
438 // Workers should not be created and tasks should not run before the pool is | 441 // Workers should not be created and tasks should not run before the pool is |
439 // started. | 442 // started. |
440 EXPECT_EQ(0U, worker_pool_->NumberOfAliveWorkersForTesting()); | 443 EXPECT_EQ(0U, worker_pool_->NumberOfAliveWorkersForTesting()); |
441 EXPECT_FALSE(task_1_scheduled.IsSignaled()); | 444 EXPECT_FALSE(task_1_scheduled.IsSignaled()); |
442 EXPECT_FALSE(task_2_scheduled.IsSignaled()); | 445 EXPECT_FALSE(task_2_scheduled.IsSignaled()); |
443 | 446 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 | 499 |
497 } // namespace | 500 } // namespace |
498 | 501 |
499 // Checks that at least one thread has detached by checking the TLS. | 502 // Checks that at least one thread has detached by checking the TLS. |
500 TEST_F(TaskSchedulerWorkerPoolCheckTlsReuse, CheckDetachedThreads) { | 503 TEST_F(TaskSchedulerWorkerPoolCheckTlsReuse, CheckDetachedThreads) { |
501 // Saturate the threads and mark each thread with a magic TLS value. | 504 // Saturate the threads and mark each thread with a magic TLS value. |
502 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; | 505 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; |
503 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 506 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
504 factories.push_back(MakeUnique<test::TestTaskFactory>( | 507 factories.push_back(MakeUnique<test::TestTaskFactory>( |
505 worker_pool_->CreateTaskRunnerWithTraits( | 508 worker_pool_->CreateTaskRunnerWithTraits( |
506 TaskTraits().WithBaseSyncPrimitives()), | 509 test::CreateTaskTraits().WithBaseSyncPrimitives()), |
507 test::ExecutionMode::PARALLEL)); | 510 test::ExecutionMode::PARALLEL)); |
508 ASSERT_TRUE(factories.back()->PostTask( | 511 ASSERT_TRUE(factories.back()->PostTask( |
509 PostNestedTask::NO, | 512 PostNestedTask::NO, |
510 Bind(&TaskSchedulerWorkerPoolCheckTlsReuse::SetTlsValueAndWait, | 513 Bind(&TaskSchedulerWorkerPoolCheckTlsReuse::SetTlsValueAndWait, |
511 Unretained(this)))); | 514 Unretained(this)))); |
512 factories.back()->WaitForAllTasksToRun(); | 515 factories.back()->WaitForAllTasksToRun(); |
513 } | 516 } |
514 | 517 |
515 // Release tasks waiting on |waiter_|. | 518 // Release tasks waiting on |waiter_|. |
516 waiter_.Signal(); | 519 waiter_.Signal(); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
568 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolHistogramTest); | 571 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolHistogramTest); |
569 }; | 572 }; |
570 | 573 |
571 } // namespace | 574 } // namespace |
572 | 575 |
573 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaits) { | 576 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaits) { |
574 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 577 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
575 WaitableEvent::InitialState::NOT_SIGNALED); | 578 WaitableEvent::InitialState::NOT_SIGNALED); |
576 CreateAndStartWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); | 579 CreateAndStartWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); |
577 auto task_runner = worker_pool_->CreateSequencedTaskRunnerWithTraits( | 580 auto task_runner = worker_pool_->CreateSequencedTaskRunnerWithTraits( |
578 TaskTraits().WithBaseSyncPrimitives()); | 581 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
579 | 582 |
580 // Post a task. | 583 // Post a task. |
581 task_runner->PostTask(FROM_HERE, | 584 task_runner->PostTask(FROM_HERE, |
582 BindOnce(&WaitableEvent::Wait, Unretained(&event))); | 585 BindOnce(&WaitableEvent::Wait, Unretained(&event))); |
583 | 586 |
584 // Post 2 more tasks while the first task hasn't completed its execution. It | 587 // Post 2 more tasks while the first task hasn't completed its execution. It |
585 // is guaranteed that these tasks will run immediately after the first task, | 588 // is guaranteed that these tasks will run immediately after the first task, |
586 // without allowing the worker to sleep. | 589 // without allowing the worker to sleep. |
587 task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)); | 590 task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)); |
588 task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)); | 591 task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing)); |
(...skipping 23 matching lines...) Expand all Loading... |
612 wait_event->Wait(); | 615 wait_event->Wait(); |
613 } | 616 } |
614 | 617 |
615 } // namespace | 618 } // namespace |
616 | 619 |
617 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaitsWithDetach) { | 620 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBetweenWaitsWithDetach) { |
618 WaitableEvent tasks_can_exit_event(WaitableEvent::ResetPolicy::MANUAL, | 621 WaitableEvent tasks_can_exit_event(WaitableEvent::ResetPolicy::MANUAL, |
619 WaitableEvent::InitialState::NOT_SIGNALED); | 622 WaitableEvent::InitialState::NOT_SIGNALED); |
620 CreateAndStartWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | 623 CreateAndStartWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); |
621 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits( | 624 auto task_runner = worker_pool_->CreateTaskRunnerWithTraits( |
622 TaskTraits().WithBaseSyncPrimitives()); | 625 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
623 | 626 |
624 // Post tasks to saturate the pool. | 627 // Post tasks to saturate the pool. |
625 std::vector<std::unique_ptr<WaitableEvent>> task_started_events; | 628 std::vector<std::unique_ptr<WaitableEvent>> task_started_events; |
626 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { | 629 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
627 task_started_events.push_back( | 630 task_started_events.push_back( |
628 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::MANUAL, | 631 MakeUnique<WaitableEvent>(WaitableEvent::ResetPolicy::MANUAL, |
629 WaitableEvent::InitialState::NOT_SIGNALED)); | 632 WaitableEvent::InitialState::NOT_SIGNALED)); |
630 task_runner->PostTask(FROM_HERE, | 633 task_runner->PostTask(FROM_HERE, |
631 BindOnce(&SignalAndWaitEvent, | 634 BindOnce(&SignalAndWaitEvent, |
632 Unretained(task_started_events.back().get()), | 635 Unretained(task_started_events.back().get()), |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 tasks_can_exit_event.Signal(); | 679 tasks_can_exit_event.Signal(); |
677 worker_pool_->WaitForAllWorkersIdleForTesting(); | 680 worker_pool_->WaitForAllWorkersIdleForTesting(); |
678 worker_pool_->DisallowWorkerDetachmentForTesting(); | 681 worker_pool_->DisallowWorkerDetachmentForTesting(); |
679 } | 682 } |
680 | 683 |
681 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { | 684 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { |
682 CreateAndStartWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | 685 CreateAndStartWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); |
683 | 686 |
684 auto histogrammed_thread_task_runner = | 687 auto histogrammed_thread_task_runner = |
685 worker_pool_->CreateSequencedTaskRunnerWithTraits( | 688 worker_pool_->CreateSequencedTaskRunnerWithTraits( |
686 TaskTraits().WithBaseSyncPrimitives()); | 689 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
687 | 690 |
688 // Post 3 tasks and hold the thread for idle thread stack ordering. | 691 // Post 3 tasks and hold the thread for idle thread stack ordering. |
689 // This test assumes |histogrammed_thread_task_runner| gets assigned the same | 692 // This test assumes |histogrammed_thread_task_runner| gets assigned the same |
690 // thread for each of its tasks. | 693 // thread for each of its tasks. |
691 PlatformThreadRef thread_ref; | 694 PlatformThreadRef thread_ref; |
692 histogrammed_thread_task_runner->PostTask( | 695 histogrammed_thread_task_runner->PostTask( |
693 FROM_HERE, BindOnce( | 696 FROM_HERE, BindOnce( |
694 [](PlatformThreadRef* thread_ref) { | 697 [](PlatformThreadRef* thread_ref) { |
695 ASSERT_TRUE(thread_ref); | 698 ASSERT_TRUE(thread_ref); |
696 *thread_ref = PlatformThread::CurrentRef(); | 699 *thread_ref = PlatformThread::CurrentRef(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 // release and go idle. This allows the SchedulerWorker associated with | 737 // release and go idle. This allows the SchedulerWorker associated with |
735 // |histogrammed_thread_task_runner| to detach. | 738 // |histogrammed_thread_task_runner| to detach. |
736 WaitableEvent top_idle_thread_running( | 739 WaitableEvent top_idle_thread_running( |
737 WaitableEvent::ResetPolicy::MANUAL, | 740 WaitableEvent::ResetPolicy::MANUAL, |
738 WaitableEvent::InitialState::NOT_SIGNALED); | 741 WaitableEvent::InitialState::NOT_SIGNALED); |
739 WaitableEvent top_idle_thread_continue( | 742 WaitableEvent top_idle_thread_continue( |
740 WaitableEvent::ResetPolicy::MANUAL, | 743 WaitableEvent::ResetPolicy::MANUAL, |
741 WaitableEvent::InitialState::NOT_SIGNALED); | 744 WaitableEvent::InitialState::NOT_SIGNALED); |
742 auto task_runner_for_top_idle = | 745 auto task_runner_for_top_idle = |
743 worker_pool_->CreateSequencedTaskRunnerWithTraits( | 746 worker_pool_->CreateSequencedTaskRunnerWithTraits( |
744 TaskTraits().WithBaseSyncPrimitives()); | 747 test::CreateTaskTraits().WithBaseSyncPrimitives()); |
745 task_runner_for_top_idle->PostTask( | 748 task_runner_for_top_idle->PostTask( |
746 FROM_HERE, BindOnce( | 749 FROM_HERE, BindOnce( |
747 [](PlatformThreadRef thread_ref, | 750 [](PlatformThreadRef thread_ref, |
748 WaitableEvent* top_idle_thread_running, | 751 WaitableEvent* top_idle_thread_running, |
749 WaitableEvent* top_idle_thread_continue) { | 752 WaitableEvent* top_idle_thread_continue) { |
750 ASSERT_FALSE(thread_ref.is_null()); | 753 ASSERT_FALSE(thread_ref.is_null()); |
751 EXPECT_NE(thread_ref, PlatformThread::CurrentRef()) | 754 EXPECT_NE(thread_ref, PlatformThread::CurrentRef()) |
752 << "Worker reused. Thread will not detach and the " | 755 << "Worker reused. Thread will not detach and the " |
753 "histogram value will be wrong."; | 756 "histogram value will be wrong."; |
754 top_idle_thread_running->Signal(); | 757 top_idle_thread_running->Signal(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 &delayed_task_manager); | 818 &delayed_task_manager); |
816 worker_pool->Start(SchedulerWorkerPoolParams(StandbyThreadPolicy::ONE, 8U, | 819 worker_pool->Start(SchedulerWorkerPoolParams(StandbyThreadPolicy::ONE, 8U, |
817 TimeDelta::Max())); | 820 TimeDelta::Max())); |
818 ASSERT_TRUE(worker_pool); | 821 ASSERT_TRUE(worker_pool); |
819 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); | 822 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); |
820 worker_pool->JoinForTesting(); | 823 worker_pool->JoinForTesting(); |
821 } | 824 } |
822 | 825 |
823 } // namespace internal | 826 } // namespace internal |
824 } // namespace base | 827 } // namespace base |
OLD | NEW |