Chromium Code Reviews| 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 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 712 // beginning of the test. | 712 // beginning of the test. |
| 713 EXPECT_EQ(static_cast<int>(kNumWorkersInWorkerPool), | 713 EXPECT_EQ(static_cast<int>(kNumWorkersInWorkerPool), |
| 714 histogram->SnapshotSamples()->GetCount(1)); | 714 histogram->SnapshotSamples()->GetCount(1)); |
| 715 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 715 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
| 716 | 716 |
| 717 tasks_can_exit_event.Signal(); | 717 tasks_can_exit_event.Signal(); |
| 718 worker_pool_->WaitForAllWorkersIdleForTesting(); | 718 worker_pool_->WaitForAllWorkersIdleForTesting(); |
| 719 worker_pool_->DisallowWorkerDetachmentForTesting(); | 719 worker_pool_->DisallowWorkerDetachmentForTesting(); |
| 720 } | 720 } |
| 721 | 721 |
| 722 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { | |
| 723 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | |
| 724 | |
| 725 auto histogrammed_thread_task_runner = | |
| 726 worker_pool_->CreateSequencedTaskRunnerWithTraits( | |
| 727 TaskTraits().WithBaseSyncPrimitives()); | |
| 728 | |
| 729 // Post 3 tasks and hold the thread for idle thread stack ordering. | |
| 730 // This test assumes |histogrammed_thread_task_runner| gets assigned the same | |
| 731 // thread for each of its tasks. | |
| 732 PlatformThreadRef thread_ref; | |
| 733 histogrammed_thread_task_runner->PostTask( | |
| 734 FROM_HERE, Bind( | |
| 735 [](PlatformThreadRef* thread_ref) { | |
| 736 ASSERT_TRUE(thread_ref); | |
| 737 *thread_ref = PlatformThread::CurrentRef(); | |
| 738 }, | |
| 739 Unretained(&thread_ref))); | |
| 740 histogrammed_thread_task_runner->PostTask( | |
| 741 FROM_HERE, Bind( | |
| 742 [](PlatformThreadRef thread_ref) { | |
| 743 EXPECT_TRUE(thread_ref == PlatformThreadRef()); | |
|
gab
2017/02/24 16:40:22
EXPECT_EQ
robliao
2017/02/24 18:17:24
Done.
| |
| 744 }, | |
| 745 thread_ref)); | |
| 746 WaitableEvent detach_thread_running( | |
| 747 WaitableEvent::ResetPolicy::MANUAL, | |
| 748 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 749 WaitableEvent detach_thread_continue( | |
| 750 WaitableEvent::ResetPolicy::MANUAL, | |
| 751 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 752 histogrammed_thread_task_runner->PostTask( | |
| 753 FROM_HERE, | |
| 754 Bind( | |
| 755 [](PlatformThreadRef thread_ref, WaitableEvent* detach_thread_running, | |
| 756 WaitableEvent* detach_thread_continue) { | |
| 757 EXPECT_TRUE(thread_ref == PlatformThreadRef()); | |
|
gab
2017/02/24 16:40:22
ditto
robliao
2017/02/24 18:17:24
See above.
| |
| 758 detach_thread_running->Signal(); | |
| 759 detach_thread_continue->Wait(); | |
| 760 }, | |
| 761 thread_ref, Unretained(&detach_thread_running), | |
| 762 Unretained(&detach_thread_continue))); | |
| 763 | |
| 764 detach_thread_running.Wait(); | |
| 765 | |
| 766 // To allow the SchedulerWorker associated with | |
| 767 // |histogrammed_thread_task_runner| to detach, make sure it isn't on top of | |
| 768 // the idle stack by waking up another SchedulerWorker via | |
| 769 // |task_runner_for_top_idle|. |histogrammed_thread_task_runner| should | |
| 770 // release and go idle first and then |task_runner_for_top_idle| should | |
| 771 // release and go idle. This allows the SchedulerWorker associated with | |
| 772 // |histogrammed_thread_task_runner| to detach. | |
| 773 WaitableEvent top_idle_thread_running( | |
| 774 WaitableEvent::ResetPolicy::MANUAL, | |
| 775 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 776 WaitableEvent top_idle_thread_continue( | |
| 777 WaitableEvent::ResetPolicy::MANUAL, | |
| 778 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 779 auto task_runner_for_top_idle = | |
| 780 worker_pool_->CreateSequencedTaskRunnerWithTraits( | |
| 781 TaskTraits().WithBaseSyncPrimitives()); | |
| 782 task_runner_for_top_idle->PostTask( | |
| 783 FROM_HERE, Bind( | |
| 784 [](PlatformThreadRef thread_ref, | |
| 785 WaitableEvent* top_idle_thread_running, | |
| 786 WaitableEvent* top_idle_thread_continue) { | |
| 787 EXPECT_FALSE(thread_ref == PlatformThread::CurrentRef()) | |
|
gab
2017/02/24 16:40:22
EXPECT_NE
robliao
2017/02/24 18:17:24
See above.
| |
| 788 << "Worker reused. Thread will not detach and the " | |
| 789 "histogram value will be wrong."; | |
| 790 top_idle_thread_running->Signal(); | |
| 791 top_idle_thread_continue->Wait(); | |
| 792 }, | |
| 793 thread_ref, Unretained(&top_idle_thread_running), | |
| 794 Unretained(&top_idle_thread_continue))); | |
| 795 top_idle_thread_running.Wait(); | |
| 796 detach_thread_continue.Signal(); | |
| 797 // Wait for the thread processing the |histogrammed_thread_task_runner| work | |
| 798 // to go to the idle stack. | |
| 799 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
| 800 top_idle_thread_continue.Signal(); | |
| 801 // Allow the thread processing the |histogrammed_thread_task_runner| work to | |
| 802 // detach. | |
| 803 PlatformThread::Sleep(kReclaimTimeForDetachTests + | |
| 804 kReclaimTimeForDetachTests); | |
| 805 worker_pool_->WaitForAllWorkersIdleForTesting(); | |
| 806 worker_pool_->DisallowWorkerDetachmentForTesting(); | |
| 807 | |
| 808 // Verify that counts were recorded to the histogram as expected. | |
| 809 const auto* histogram = worker_pool_->num_tasks_before_detach_histogram(); | |
| 810 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); | |
| 811 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(1)); | |
| 812 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(2)); | |
| 813 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); | |
| 814 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(4)); | |
| 815 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(5)); | |
| 816 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(6)); | |
| 817 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | |
| 818 } | |
| 819 | |
| 722 namespace { | 820 namespace { |
| 723 | 821 |
| 724 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | 822 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
| 725 ADD_FAILURE() | 823 ADD_FAILURE() |
| 726 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; | 824 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; |
| 727 } | 825 } |
| 728 | 826 |
| 729 void CaptureThreadId(PlatformThreadId* thread_id) { | |
| 730 ASSERT_TRUE(thread_id); | |
| 731 *thread_id = PlatformThread::CurrentId(); | |
| 732 } | |
| 733 | |
| 734 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { | |
| 735 EXPECT_NE(thread_id, PlatformThread::CurrentId()); | |
| 736 } | |
| 737 | |
| 738 } // namespace | 827 } // namespace |
| 739 | 828 |
| 740 TEST_F(TaskSchedulerWorkerPoolHistogramTest, NumTasksBeforeDetach) { | |
| 741 InitializeWorkerPool(kReclaimTimeForDetachTests, kNumWorkersInWorkerPool); | |
| 742 | |
| 743 // This test assumes that the TaskRunners aren't assigned to the same worker. | |
| 744 auto task_runner = | |
| 745 worker_pool_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | |
| 746 auto other_task_runner = | |
| 747 worker_pool_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | |
| 748 | |
| 749 // Post 3 tasks and wait until they run. | |
| 750 PlatformThreadId thread_id; | |
| 751 task_runner->PostTask(FROM_HERE, | |
| 752 Bind(&CaptureThreadId, Unretained(&thread_id))); | |
| 753 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | |
| 754 task_runner->PostTask(FROM_HERE, Bind(&DoNothing)); | |
| 755 worker_pool_->WaitForAllWorkersIdleForTesting(); | |
| 756 | |
| 757 // To allow the SchedulerWorker associated with |task_runner| to detach: | |
| 758 // - Make sure it isn't on top of the idle stack by waking up another | |
| 759 // SchedulerWorker and waiting until it goes back to sleep. | |
| 760 // - Release |task_runner|. | |
| 761 other_task_runner->PostTask(FROM_HERE, Bind(&VerifyThreadIdIsNot, thread_id)); | |
| 762 worker_pool_->WaitForAllWorkersIdleForTesting(); | |
| 763 task_runner = nullptr; | |
| 764 | |
| 765 // Allow the SchedulerWorker that was associated with |task_runner| to detach. | |
| 766 PlatformThread::Sleep(kReclaimTimeForDetachTests + kExtraTimeToWaitForDetach); | |
| 767 worker_pool_->DisallowWorkerDetachmentForTesting(); | |
| 768 | |
| 769 // Verify that counts were recorded to the histogram as expected. | |
| 770 const auto* histogram = worker_pool_->num_tasks_before_detach_histogram(); | |
| 771 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(0)); | |
| 772 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); | |
| 773 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | |
| 774 } | |
| 775 | |
| 776 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { | 829 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { |
| 777 TaskTracker task_tracker; | 830 TaskTracker task_tracker; |
| 778 DelayedTaskManager delayed_task_manager( | 831 DelayedTaskManager delayed_task_manager( |
| 779 make_scoped_refptr(new TestSimpleTaskRunner)); | 832 make_scoped_refptr(new TestSimpleTaskRunner)); |
| 780 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 833 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
| 781 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, | 834 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, |
| 782 StandbyThreadPolicy::LAZY, 8U, | 835 StandbyThreadPolicy::LAZY, 8U, |
| 783 TimeDelta::Max()), | 836 TimeDelta::Max()), |
| 784 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 837 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 785 &delayed_task_manager); | 838 &delayed_task_manager); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 797 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), | 850 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), |
| 798 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 851 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 799 &delayed_task_manager); | 852 &delayed_task_manager); |
| 800 ASSERT_TRUE(worker_pool); | 853 ASSERT_TRUE(worker_pool); |
| 801 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); | 854 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 802 worker_pool->JoinForTesting(); | 855 worker_pool->JoinForTesting(); |
| 803 } | 856 } |
| 804 | 857 |
| 805 } // namespace internal | 858 } // namespace internal |
| 806 } // namespace base | 859 } // namespace base |
| OLD | NEW |