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 |