| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 constexpr size_t kNumThreadsPostingTasks = 4; | 51 constexpr size_t kNumThreadsPostingTasks = 4; |
| 52 constexpr size_t kNumTasksPostedPerThread = 150; | 52 constexpr size_t kNumTasksPostedPerThread = 150; |
| 53 // This can't be lower because Windows' WaitableEvent wakes up too early when a | 53 // This can't be lower because Windows' WaitableEvent wakes up too early when a |
| 54 // small timeout is used. This results in many spurious wake ups before a worker | 54 // small timeout is used. This results in many spurious wake ups before a worker |
| 55 // is allowed to detach. | 55 // is allowed to detach. |
| 56 constexpr TimeDelta kReclaimTimeForDetachTests = | 56 constexpr TimeDelta kReclaimTimeForDetachTests = |
| 57 TimeDelta::FromMilliseconds(500); | 57 TimeDelta::FromMilliseconds(500); |
| 58 constexpr TimeDelta kExtraTimeToWaitForDetach = | 58 constexpr TimeDelta kExtraTimeToWaitForDetach = |
| 59 TimeDelta::FromSeconds(1); | 59 TimeDelta::FromSeconds(1); |
| 60 | 60 |
| 61 using IORestriction = SchedulerWorkerPoolParams::IORestriction; | |
| 62 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; | 61 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; |
| 63 | 62 |
| 64 class TaskSchedulerWorkerPoolImplTest | 63 class TaskSchedulerWorkerPoolImplTest |
| 65 : public testing::TestWithParam<test::ExecutionMode> { | 64 : public testing::TestWithParam<test::ExecutionMode> { |
| 66 protected: | 65 protected: |
| 67 TaskSchedulerWorkerPoolImplTest() | 66 TaskSchedulerWorkerPoolImplTest() |
| 68 : service_thread_("TaskSchedulerServiceThread") {} | 67 : service_thread_("TaskSchedulerServiceThread") {} |
| 69 | 68 |
| 70 void SetUp() override { | 69 void SetUp() override { |
| 71 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); | 70 InitializeWorkerPool(TimeDelta::Max(), kNumWorkersInWorkerPool); |
| 72 } | 71 } |
| 73 | 72 |
| 74 void TearDown() override { | 73 void TearDown() override { |
| 75 service_thread_.Stop(); | 74 service_thread_.Stop(); |
| 76 worker_pool_->WaitForAllWorkersIdleForTesting(); | 75 worker_pool_->WaitForAllWorkersIdleForTesting(); |
| 77 worker_pool_->JoinForTesting(); | 76 worker_pool_->JoinForTesting(); |
| 78 } | 77 } |
| 79 | 78 |
| 80 void InitializeWorkerPool(const TimeDelta& suggested_reclaim_time, | 79 void InitializeWorkerPool(const TimeDelta& suggested_reclaim_time, |
| 81 size_t num_workers) { | 80 size_t num_workers) { |
| 82 ASSERT_FALSE(worker_pool_); | 81 ASSERT_FALSE(worker_pool_); |
| 83 ASSERT_FALSE(delayed_task_manager_); | 82 ASSERT_FALSE(delayed_task_manager_); |
| 84 service_thread_.Start(); | 83 service_thread_.Start(); |
| 85 delayed_task_manager_ = | 84 delayed_task_manager_ = |
| 86 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 85 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); |
| 87 worker_pool_ = SchedulerWorkerPoolImpl::Create( | 86 worker_pool_ = SchedulerWorkerPoolImpl::Create( |
| 88 SchedulerWorkerPoolParams( | 87 SchedulerWorkerPoolParams("TestWorkerPool", ThreadPriority::NORMAL, |
| 89 "TestWorkerPool", ThreadPriority::NORMAL, IORestriction::ALLOWED, | 88 StandbyThreadPolicy::LAZY, num_workers, |
| 90 StandbyThreadPolicy::LAZY, num_workers, suggested_reclaim_time), | 89 suggested_reclaim_time), |
| 91 Bind(&TaskSchedulerWorkerPoolImplTest::ReEnqueueSequenceCallback, | 90 Bind(&TaskSchedulerWorkerPoolImplTest::ReEnqueueSequenceCallback, |
| 92 Unretained(this)), | 91 Unretained(this)), |
| 93 &task_tracker_, delayed_task_manager_.get()); | 92 &task_tracker_, delayed_task_manager_.get()); |
| 94 ASSERT_TRUE(worker_pool_); | 93 ASSERT_TRUE(worker_pool_); |
| 95 } | 94 } |
| 96 | 95 |
| 97 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool_; | 96 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool_; |
| 98 | 97 |
| 99 TaskTracker task_tracker_; | 98 TaskTracker task_tracker_; |
| 100 Thread service_thread_; | 99 Thread service_thread_; |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 INSTANTIATE_TEST_CASE_P(Sequenced, | 430 INSTANTIATE_TEST_CASE_P(Sequenced, |
| 432 TaskSchedulerWorkerPoolImplSingleWorkerTest, | 431 TaskSchedulerWorkerPoolImplSingleWorkerTest, |
| 433 ::testing::Values(test::ExecutionMode::SEQUENCED)); | 432 ::testing::Values(test::ExecutionMode::SEQUENCED)); |
| 434 INSTANTIATE_TEST_CASE_P( | 433 INSTANTIATE_TEST_CASE_P( |
| 435 SingleThreaded, | 434 SingleThreaded, |
| 436 TaskSchedulerWorkerPoolImplSingleWorkerTest, | 435 TaskSchedulerWorkerPoolImplSingleWorkerTest, |
| 437 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); | 436 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); |
| 438 | 437 |
| 439 namespace { | 438 namespace { |
| 440 | 439 |
| 441 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | |
| 442 ADD_FAILURE() | |
| 443 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; | |
| 444 } | |
| 445 | |
| 446 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED | |
| 447 // and disallows it otherwise. Signals |event| before returning. | |
| 448 void ExpectIORestriction(IORestriction io_restriction, WaitableEvent* event) { | |
| 449 DCHECK(event); | |
| 450 | |
| 451 if (io_restriction == IORestriction::ALLOWED) { | |
| 452 ThreadRestrictions::AssertIOAllowed(); | |
| 453 } else { | |
| 454 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }); | |
| 455 } | |
| 456 | |
| 457 event->Signal(); | |
| 458 } | |
| 459 | |
| 460 class TaskSchedulerWorkerPoolImplIORestrictionTest | |
| 461 : public testing::TestWithParam<IORestriction> { | |
| 462 public: | |
| 463 TaskSchedulerWorkerPoolImplIORestrictionTest() = default; | |
| 464 | |
| 465 private: | |
| 466 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplIORestrictionTest); | |
| 467 }; | |
| 468 | |
| 469 } // namespace | |
| 470 | |
| 471 TEST_P(TaskSchedulerWorkerPoolImplIORestrictionTest, IORestriction) { | |
| 472 TaskTracker task_tracker; | |
| 473 DelayedTaskManager delayed_task_manager( | |
| 474 make_scoped_refptr(new TestSimpleTaskRunner)); | |
| 475 | |
| 476 auto worker_pool = SchedulerWorkerPoolImpl::Create( | |
| 477 SchedulerWorkerPoolParams( | |
| 478 "TestWorkerPoolWithParam", ThreadPriority::NORMAL, GetParam(), | |
| 479 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()), | |
| 480 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | |
| 481 &delayed_task_manager); | |
| 482 ASSERT_TRUE(worker_pool); | |
| 483 | |
| 484 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | |
| 485 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 486 worker_pool->CreateTaskRunnerWithTraits(TaskTraits()) | |
| 487 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); | |
| 488 task_ran.Wait(); | |
| 489 | |
| 490 worker_pool->JoinForTesting(); | |
| 491 } | |
| 492 | |
| 493 INSTANTIATE_TEST_CASE_P(IOAllowed, | |
| 494 TaskSchedulerWorkerPoolImplIORestrictionTest, | |
| 495 ::testing::Values(IORestriction::ALLOWED)); | |
| 496 INSTANTIATE_TEST_CASE_P(IODisallowed, | |
| 497 TaskSchedulerWorkerPoolImplIORestrictionTest, | |
| 498 ::testing::Values(IORestriction::DISALLOWED)); | |
| 499 | |
| 500 namespace { | |
| 501 | |
| 502 class TaskSchedulerWorkerPoolSingleThreadedTest | 440 class TaskSchedulerWorkerPoolSingleThreadedTest |
| 503 : public TaskSchedulerWorkerPoolImplTest { | 441 : public TaskSchedulerWorkerPoolImplTest { |
| 504 public: | 442 public: |
| 505 void InitializeThreadChecker() { | 443 void InitializeThreadChecker() { |
| 506 thread_checker_.reset(new ThreadCheckerImpl()); | 444 thread_checker_.reset(new ThreadCheckerImpl()); |
| 507 } | 445 } |
| 508 | 446 |
| 509 void CheckValidThread() { | 447 void CheckValidThread() { |
| 510 EXPECT_TRUE(thread_checker_->CalledOnValidThread()); | 448 EXPECT_TRUE(thread_checker_->CalledOnValidThread()); |
| 511 } | 449 } |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 772 histogram->SnapshotSamples()->GetCount(1)); | 710 histogram->SnapshotSamples()->GetCount(1)); |
| 773 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 711 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
| 774 | 712 |
| 775 tasks_can_exit_event.Signal(); | 713 tasks_can_exit_event.Signal(); |
| 776 worker_pool_->WaitForAllWorkersIdleForTesting(); | 714 worker_pool_->WaitForAllWorkersIdleForTesting(); |
| 777 worker_pool_->DisallowWorkerDetachmentForTesting(); | 715 worker_pool_->DisallowWorkerDetachmentForTesting(); |
| 778 } | 716 } |
| 779 | 717 |
| 780 namespace { | 718 namespace { |
| 781 | 719 |
| 720 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
| 721 ADD_FAILURE() |
| 722 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; |
| 723 } |
| 724 |
| 782 void CaptureThreadId(PlatformThreadId* thread_id) { | 725 void CaptureThreadId(PlatformThreadId* thread_id) { |
| 783 ASSERT_TRUE(thread_id); | 726 ASSERT_TRUE(thread_id); |
| 784 *thread_id = PlatformThread::CurrentId(); | 727 *thread_id = PlatformThread::CurrentId(); |
| 785 } | 728 } |
| 786 | 729 |
| 787 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { | 730 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { |
| 788 EXPECT_NE(thread_id, PlatformThread::CurrentId()); | 731 EXPECT_NE(thread_id, PlatformThread::CurrentId()); |
| 789 } | 732 } |
| 790 | 733 |
| 791 } // namespace | 734 } // namespace |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); | 768 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); |
| 826 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 769 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
| 827 } | 770 } |
| 828 | 771 |
| 829 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { | 772 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { |
| 830 TaskTracker task_tracker; | 773 TaskTracker task_tracker; |
| 831 DelayedTaskManager delayed_task_manager( | 774 DelayedTaskManager delayed_task_manager( |
| 832 make_scoped_refptr(new TestSimpleTaskRunner)); | 775 make_scoped_refptr(new TestSimpleTaskRunner)); |
| 833 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 776 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
| 834 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, | 777 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, |
| 835 IORestriction::DISALLOWED, | |
| 836 StandbyThreadPolicy::LAZY, 8U, | 778 StandbyThreadPolicy::LAZY, 8U, |
| 837 TimeDelta::Max()), | 779 TimeDelta::Max()), |
| 838 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 780 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 839 &delayed_task_manager); | 781 &delayed_task_manager); |
| 840 ASSERT_TRUE(worker_pool); | 782 ASSERT_TRUE(worker_pool); |
| 841 EXPECT_EQ(0U, worker_pool->NumberOfAliveWorkersForTesting()); | 783 EXPECT_EQ(0U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 842 worker_pool->JoinForTesting(); | 784 worker_pool->JoinForTesting(); |
| 843 } | 785 } |
| 844 | 786 |
| 845 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitOne) { | 787 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitOne) { |
| 846 TaskTracker task_tracker; | 788 TaskTracker task_tracker; |
| 847 DelayedTaskManager delayed_task_manager( | 789 DelayedTaskManager delayed_task_manager( |
| 848 make_scoped_refptr(new TestSimpleTaskRunner)); | 790 make_scoped_refptr(new TestSimpleTaskRunner)); |
| 849 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 791 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
| 850 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, | 792 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, |
| 851 IORestriction::DISALLOWED, | |
| 852 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), | 793 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), |
| 853 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 794 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 854 &delayed_task_manager); | 795 &delayed_task_manager); |
| 855 ASSERT_TRUE(worker_pool); | 796 ASSERT_TRUE(worker_pool); |
| 856 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); | 797 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 857 worker_pool->JoinForTesting(); | 798 worker_pool->JoinForTesting(); |
| 858 } | 799 } |
| 859 | 800 |
| 860 } // namespace internal | 801 } // namespace internal |
| 861 } // namespace base | 802 } // namespace base |
| OLD | NEW |