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_EQ(thread_ref, PlatformThreadRef()); |
| 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_EQ(thread_ref, PlatformThreadRef()); |
| 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_NE(thread_ref, PlatformThread::CurrentRef()) |
| 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 |