Chromium Code Reviews| 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 <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 std::unique_ptr<SchedulerWorkerPoolImpl> SchedulerWorkerPoolImpl::Create( | 306 std::unique_ptr<SchedulerWorkerPoolImpl> SchedulerWorkerPoolImpl::Create( |
| 307 const SchedulerWorkerPoolParams& params, | 307 const SchedulerWorkerPoolParams& params, |
| 308 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, | 308 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback, |
| 309 TaskTracker* task_tracker, | 309 TaskTracker* task_tracker, |
| 310 DelayedTaskManager* delayed_task_manager) { | 310 DelayedTaskManager* delayed_task_manager) { |
| 311 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool( | 311 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool( |
| 312 new SchedulerWorkerPoolImpl(params.name(), | 312 new SchedulerWorkerPoolImpl(params.name(), |
| 313 params.io_restriction(), | 313 params.io_restriction(), |
| 314 params.suggested_reclaim_time(), | 314 params.suggested_reclaim_time(), |
| 315 task_tracker, delayed_task_manager)); | 315 task_tracker, delayed_task_manager)); |
| 316 if (worker_pool->Initialize(params.priority_hint(), params.max_threads(), | 316 if (worker_pool->Initialize( |
| 317 re_enqueue_sequence_callback)) { | 317 params.priority_hint(), params.standby_thread_policy(), |
| 318 params.max_threads(), re_enqueue_sequence_callback)) { | |
| 318 return worker_pool; | 319 return worker_pool; |
| 319 } | 320 } |
| 320 return nullptr; | 321 return nullptr; |
| 321 } | 322 } |
| 322 | 323 |
| 323 scoped_refptr<TaskRunner> SchedulerWorkerPoolImpl::CreateTaskRunnerWithTraits( | 324 scoped_refptr<TaskRunner> SchedulerWorkerPoolImpl::CreateTaskRunnerWithTraits( |
| 324 const TaskTraits& traits) { | 325 const TaskTraits& traits) { |
| 325 return make_scoped_refptr(new SchedulerParallelTaskRunner(traits, this)); | 326 return make_scoped_refptr(new SchedulerParallelTaskRunner(traits, this)); |
| 326 } | 327 } |
| 327 | 328 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 worker->JoinForTesting(); | 446 worker->JoinForTesting(); |
| 446 | 447 |
| 447 DCHECK(!join_for_testing_returned_.IsSignaled()); | 448 DCHECK(!join_for_testing_returned_.IsSignaled()); |
| 448 join_for_testing_returned_.Signal(); | 449 join_for_testing_returned_.Signal(); |
| 449 } | 450 } |
| 450 | 451 |
| 451 void SchedulerWorkerPoolImpl::DisallowWorkerDetachmentForTesting() { | 452 void SchedulerWorkerPoolImpl::DisallowWorkerDetachmentForTesting() { |
| 452 worker_detachment_disallowed_.Set(); | 453 worker_detachment_disallowed_.Set(); |
| 453 } | 454 } |
| 454 | 455 |
| 456 size_t SchedulerWorkerPoolImpl::NumberOfAliveWorkersForTesting() { | |
| 457 size_t num_alive_workers = 0; | |
| 458 for (const auto& worker : workers_) { | |
| 459 if (worker->ThreadAliveForTesting()) | |
| 460 num_alive_workers++; | |
| 461 } | |
| 462 return num_alive_workers; | |
| 463 } | |
| 464 | |
| 455 SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner:: | 465 SchedulerWorkerPoolImpl::SchedulerSingleThreadTaskRunner:: |
| 456 SchedulerSingleThreadTaskRunner(const TaskTraits& traits, | 466 SchedulerSingleThreadTaskRunner(const TaskTraits& traits, |
| 457 SchedulerWorkerPool* worker_pool, | 467 SchedulerWorkerPool* worker_pool, |
| 458 SchedulerWorker* worker) | 468 SchedulerWorker* worker) |
| 459 : traits_(traits), | 469 : traits_(traits), |
| 460 worker_pool_(worker_pool), | 470 worker_pool_(worker_pool), |
| 461 worker_(worker) { | 471 worker_(worker) { |
| 462 DCHECK(worker_pool_); | 472 DCHECK(worker_pool_); |
| 463 DCHECK(worker_); | 473 DCHECK(worker_); |
| 464 static_cast<SchedulerWorkerDelegateImpl*>(worker_->delegate())-> | 474 static_cast<SchedulerWorkerDelegateImpl*>(worker_->delegate())-> |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 50, | 719 50, |
| 710 HistogramBase::kUmaTargetedHistogramFlag)), | 720 HistogramBase::kUmaTargetedHistogramFlag)), |
| 711 task_tracker_(task_tracker), | 721 task_tracker_(task_tracker), |
| 712 delayed_task_manager_(delayed_task_manager) { | 722 delayed_task_manager_(delayed_task_manager) { |
| 713 DCHECK(task_tracker_); | 723 DCHECK(task_tracker_); |
| 714 DCHECK(delayed_task_manager_); | 724 DCHECK(delayed_task_manager_); |
| 715 } | 725 } |
| 716 | 726 |
| 717 bool SchedulerWorkerPoolImpl::Initialize( | 727 bool SchedulerWorkerPoolImpl::Initialize( |
| 718 ThreadPriority priority_hint, | 728 ThreadPriority priority_hint, |
| 729 SchedulerWorkerPoolParams::StandbyThreadPolicy standby_thread_policy, | |
| 719 size_t max_threads, | 730 size_t max_threads, |
| 720 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback) { | 731 const ReEnqueueSequenceCallback& re_enqueue_sequence_callback) { |
| 721 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); | 732 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); |
| 722 | 733 |
| 723 DCHECK(workers_.empty()); | 734 DCHECK(workers_.empty()); |
| 724 workers_.resize(max_threads); | 735 workers_.resize(max_threads); |
| 725 | 736 |
| 726 // Create workers and push them to the idle stack in reverse order of index. | 737 // Create workers and push them to the idle stack in reverse order of index. |
| 727 // This ensures that they are woken up in order of index and that the ALIVE | 738 // This ensures that they are woken up in order of index and that the ALIVE |
| 728 // worker is on top of the stack. | 739 // worker is on top of the stack. |
| 729 for (int index = max_threads - 1; index >= 0; --index) { | 740 for (int index = max_threads - 1; index >= 0; --index) { |
| 741 const bool is_standby_lazy = | |
| 742 standby_thread_policy == | |
| 743 SchedulerWorkerPoolParams::StandbyThreadPolicy::LAZY; | |
| 730 const SchedulerWorker::InitialState initial_state = | 744 const SchedulerWorker::InitialState initial_state = |
| 731 (index == 0) ? SchedulerWorker::InitialState::ALIVE | 745 (index == 0 && !is_standby_lazy) |
| 732 : SchedulerWorker::InitialState::DETACHED; | 746 ? SchedulerWorker::InitialState::ALIVE |
| 747 : SchedulerWorker::InitialState::DETACHED; | |
| 733 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( | 748 std::unique_ptr<SchedulerWorker> worker = SchedulerWorker::Create( |
| 734 priority_hint, | 749 priority_hint, |
| 735 MakeUnique<SchedulerWorkerDelegateImpl>( | 750 MakeUnique<SchedulerWorkerDelegateImpl>( |
| 736 this, re_enqueue_sequence_callback, &shared_priority_queue_, index), | 751 this, re_enqueue_sequence_callback, &shared_priority_queue_, index), |
| 737 task_tracker_, initial_state); | 752 task_tracker_, initial_state); |
| 738 if (!worker) | 753 if (!worker) |
| 739 break; | 754 break; |
| 740 idle_workers_stack_.Push(worker.get()); | 755 idle_workers_stack_.Push(worker.get()); |
| 741 workers_[index] = std::move(worker); | 756 workers_[index] = std::move(worker); |
| 742 } | 757 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 781 } | 796 } |
| 782 | 797 |
| 783 const SchedulerWorker* SchedulerWorkerPoolImpl::PeekAtIdleWorkersStack() const { | 798 const SchedulerWorker* SchedulerWorkerPoolImpl::PeekAtIdleWorkersStack() const { |
| 784 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); | 799 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); |
| 785 return idle_workers_stack_.Peek(); | 800 return idle_workers_stack_.Peek(); |
| 786 } | 801 } |
| 787 | 802 |
| 788 void SchedulerWorkerPoolImpl::RemoveFromIdleWorkersStack( | 803 void SchedulerWorkerPoolImpl::RemoveFromIdleWorkersStack( |
| 789 SchedulerWorker* worker) { | 804 SchedulerWorker* worker) { |
| 790 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); | 805 AutoSchedulerLock auto_lock(idle_workers_stack_lock_); |
| 791 idle_workers_stack_.Remove(worker); | 806 idle_workers_stack_.Remove(worker); |
|
fdoray
2016/11/15 15:27:02
Add a TODO to honor StandbyThreadPolicy::ONE here.
robliao
2016/11/15 15:57:19
It's a good question. I've captured this part of t
| |
| 792 } | 807 } |
| 793 | 808 |
| 794 bool SchedulerWorkerPoolImpl::CanWorkerDetachForTesting() { | 809 bool SchedulerWorkerPoolImpl::CanWorkerDetachForTesting() { |
| 795 return !worker_detachment_disallowed_.IsSet(); | 810 return !worker_detachment_disallowed_.IsSet(); |
| 796 } | 811 } |
| 797 | 812 |
| 798 } // namespace internal | 813 } // namespace internal |
| 799 } // namespace base | 814 } // namespace base |
| OLD | NEW |