| 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 |