| 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 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 INSTANTIATE_TEST_CASE_P(Sequenced, | 432 INSTANTIATE_TEST_CASE_P(Sequenced, |
| 434 TaskSchedulerWorkerPoolImplSingleWorkerTest, | 433 TaskSchedulerWorkerPoolImplSingleWorkerTest, |
| 435 ::testing::Values(test::ExecutionMode::SEQUENCED)); | 434 ::testing::Values(test::ExecutionMode::SEQUENCED)); |
| 436 INSTANTIATE_TEST_CASE_P( | 435 INSTANTIATE_TEST_CASE_P( |
| 437 SingleThreaded, | 436 SingleThreaded, |
| 438 TaskSchedulerWorkerPoolImplSingleWorkerTest, | 437 TaskSchedulerWorkerPoolImplSingleWorkerTest, |
| 439 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); | 438 ::testing::Values(test::ExecutionMode::SINGLE_THREADED)); |
| 440 | 439 |
| 441 namespace { | 440 namespace { |
| 442 | 441 |
| 443 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | |
| 444 ADD_FAILURE() | |
| 445 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; | |
| 446 } | |
| 447 | |
| 448 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED | |
| 449 // and disallows it otherwise. Signals |event| before returning. | |
| 450 void ExpectIORestriction(IORestriction io_restriction, WaitableEvent* event) { | |
| 451 DCHECK(event); | |
| 452 | |
| 453 if (io_restriction == IORestriction::ALLOWED) { | |
| 454 ThreadRestrictions::AssertIOAllowed(); | |
| 455 } else { | |
| 456 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }); | |
| 457 } | |
| 458 | |
| 459 event->Signal(); | |
| 460 } | |
| 461 | |
| 462 class TaskSchedulerWorkerPoolImplIORestrictionTest | |
| 463 : public testing::TestWithParam<IORestriction> { | |
| 464 public: | |
| 465 TaskSchedulerWorkerPoolImplIORestrictionTest() = default; | |
| 466 | |
| 467 private: | |
| 468 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplIORestrictionTest); | |
| 469 }; | |
| 470 | |
| 471 } // namespace | |
| 472 | |
| 473 TEST_P(TaskSchedulerWorkerPoolImplIORestrictionTest, IORestriction) { | |
| 474 TaskTracker task_tracker; | |
| 475 DelayedTaskManager delayed_task_manager( | |
| 476 make_scoped_refptr(new TestSimpleTaskRunner)); | |
| 477 | |
| 478 auto worker_pool = SchedulerWorkerPoolImpl::Create( | |
| 479 SchedulerWorkerPoolParams( | |
| 480 "TestWorkerPoolWithParam", ThreadPriority::NORMAL, GetParam(), | |
| 481 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()), | |
| 482 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | |
| 483 &delayed_task_manager); | |
| 484 ASSERT_TRUE(worker_pool); | |
| 485 | |
| 486 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | |
| 487 WaitableEvent::InitialState::NOT_SIGNALED); | |
| 488 worker_pool->CreateTaskRunnerWithTraits(TaskTraits()) | |
| 489 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); | |
| 490 task_ran.Wait(); | |
| 491 | |
| 492 worker_pool->JoinForTesting(); | |
| 493 } | |
| 494 | |
| 495 INSTANTIATE_TEST_CASE_P(IOAllowed, | |
| 496 TaskSchedulerWorkerPoolImplIORestrictionTest, | |
| 497 ::testing::Values(IORestriction::ALLOWED)); | |
| 498 INSTANTIATE_TEST_CASE_P(IODisallowed, | |
| 499 TaskSchedulerWorkerPoolImplIORestrictionTest, | |
| 500 ::testing::Values(IORestriction::DISALLOWED)); | |
| 501 | |
| 502 namespace { | |
| 503 | |
| 504 class TaskSchedulerWorkerPoolSingleThreadedTest | 442 class TaskSchedulerWorkerPoolSingleThreadedTest |
| 505 : public TaskSchedulerWorkerPoolImplTest { | 443 : public TaskSchedulerWorkerPoolImplTest { |
| 506 public: | 444 public: |
| 507 void InitializeThreadChecker() { | 445 void InitializeThreadChecker() { |
| 508 thread_checker_.reset(new ThreadCheckerImpl()); | 446 thread_checker_.reset(new ThreadCheckerImpl()); |
| 509 } | 447 } |
| 510 | 448 |
| 511 void CheckValidThread() { | 449 void CheckValidThread() { |
| 512 EXPECT_TRUE(thread_checker_->CalledOnValidThread()); | 450 EXPECT_TRUE(thread_checker_->CalledOnValidThread()); |
| 513 } | 451 } |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 775 histogram->SnapshotSamples()->GetCount(1)); | 713 histogram->SnapshotSamples()->GetCount(1)); |
| 776 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 714 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
| 777 | 715 |
| 778 tasks_can_exit_event.Signal(); | 716 tasks_can_exit_event.Signal(); |
| 779 worker_pool_->WaitForAllWorkersIdleForTesting(); | 717 worker_pool_->WaitForAllWorkersIdleForTesting(); |
| 780 worker_pool_->DisallowWorkerDetachmentForTesting(); | 718 worker_pool_->DisallowWorkerDetachmentForTesting(); |
| 781 } | 719 } |
| 782 | 720 |
| 783 namespace { | 721 namespace { |
| 784 | 722 |
| 723 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
| 724 ADD_FAILURE() |
| 725 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; |
| 726 } |
| 727 |
| 785 void CaptureThreadId(PlatformThreadId* thread_id) { | 728 void CaptureThreadId(PlatformThreadId* thread_id) { |
| 786 ASSERT_TRUE(thread_id); | 729 ASSERT_TRUE(thread_id); |
| 787 *thread_id = PlatformThread::CurrentId(); | 730 *thread_id = PlatformThread::CurrentId(); |
| 788 } | 731 } |
| 789 | 732 |
| 790 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { | 733 void VerifyThreadIdIsNot(PlatformThreadId thread_id) { |
| 791 EXPECT_NE(thread_id, PlatformThread::CurrentId()); | 734 EXPECT_NE(thread_id, PlatformThread::CurrentId()); |
| 792 } | 735 } |
| 793 | 736 |
| 794 } // namespace | 737 } // namespace |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 828 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); | 771 EXPECT_EQ(1, histogram->SnapshotSamples()->GetCount(3)); |
| 829 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); | 772 EXPECT_EQ(0, histogram->SnapshotSamples()->GetCount(10)); |
| 830 } | 773 } |
| 831 | 774 |
| 832 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { | 775 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitLazy) { |
| 833 TaskTracker task_tracker; | 776 TaskTracker task_tracker; |
| 834 DelayedTaskManager delayed_task_manager( | 777 DelayedTaskManager delayed_task_manager( |
| 835 make_scoped_refptr(new TestSimpleTaskRunner)); | 778 make_scoped_refptr(new TestSimpleTaskRunner)); |
| 836 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 779 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
| 837 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, | 780 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, |
| 838 IORestriction::DISALLOWED, | |
| 839 StandbyThreadPolicy::LAZY, 8U, | 781 StandbyThreadPolicy::LAZY, 8U, |
| 840 TimeDelta::Max()), | 782 TimeDelta::Max()), |
| 841 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 783 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 842 &delayed_task_manager); | 784 &delayed_task_manager); |
| 843 ASSERT_TRUE(worker_pool); | 785 ASSERT_TRUE(worker_pool); |
| 844 EXPECT_EQ(0U, worker_pool->NumberOfAliveWorkersForTesting()); | 786 EXPECT_EQ(0U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 845 worker_pool->JoinForTesting(); | 787 worker_pool->JoinForTesting(); |
| 846 } | 788 } |
| 847 | 789 |
| 848 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitOne) { | 790 TEST(TaskSchedulerWorkerPoolStandbyPolicyTest, InitOne) { |
| 849 TaskTracker task_tracker; | 791 TaskTracker task_tracker; |
| 850 DelayedTaskManager delayed_task_manager( | 792 DelayedTaskManager delayed_task_manager( |
| 851 make_scoped_refptr(new TestSimpleTaskRunner)); | 793 make_scoped_refptr(new TestSimpleTaskRunner)); |
| 852 auto worker_pool = SchedulerWorkerPoolImpl::Create( | 794 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
| 853 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, | 795 SchedulerWorkerPoolParams("LazyPolicyWorkerPool", ThreadPriority::NORMAL, |
| 854 IORestriction::DISALLOWED, | |
| 855 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), | 796 StandbyThreadPolicy::ONE, 8U, TimeDelta::Max()), |
| 856 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 797 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
| 857 &delayed_task_manager); | 798 &delayed_task_manager); |
| 858 ASSERT_TRUE(worker_pool); | 799 ASSERT_TRUE(worker_pool); |
| 859 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); | 800 EXPECT_EQ(1U, worker_pool->NumberOfAliveWorkersForTesting()); |
| 860 worker_pool->JoinForTesting(); | 801 worker_pool->JoinForTesting(); |
| 861 } | 802 } |
| 862 | 803 |
| 863 } // namespace internal | 804 } // namespace internal |
| 864 } // namespace base | 805 } // namespace base |
| OLD | NEW |