| 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/task_scheduler_impl.h" | 5 #include "base/task_scheduler/task_scheduler_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 }; | 51 }; |
| 52 | 52 |
| 53 size_t GetEnvironmentIndexForTraits(const TaskTraits& traits) { | 53 size_t GetEnvironmentIndexForTraits(const TaskTraits& traits) { |
| 54 const bool is_background = | 54 const bool is_background = |
| 55 traits.priority() == base::TaskPriority::BACKGROUND; | 55 traits.priority() == base::TaskPriority::BACKGROUND; |
| 56 if (traits.may_block() || traits.with_base_sync_primitives()) | 56 if (traits.may_block() || traits.with_base_sync_primitives()) |
| 57 return is_background ? BACKGROUND_BLOCKING : FOREGROUND_BLOCKING; | 57 return is_background ? BACKGROUND_BLOCKING : FOREGROUND_BLOCKING; |
| 58 return is_background ? BACKGROUND : FOREGROUND; | 58 return is_background ? BACKGROUND : FOREGROUND; |
| 59 } | 59 } |
| 60 | 60 |
| 61 void AddAugmentedSchedulerWorkerPoolParamsToVector( | |
| 62 EnvironmentType environment_type, | |
| 63 const std::string& task_scheduler_name, | |
| 64 const SchedulerWorkerPoolParams& params, | |
| 65 std::vector<SchedulerWorkerPoolParams>* | |
| 66 scheduler_worker_pool_params_vector) { | |
| 67 DCHECK_EQ(static_cast<size_t>(environment_type), | |
| 68 scheduler_worker_pool_params_vector->size()); | |
| 69 scheduler_worker_pool_params_vector->emplace_back( | |
| 70 task_scheduler_name + kEnvironmentParams[environment_type].name_suffix, | |
| 71 kEnvironmentParams[environment_type].priority_hint, | |
| 72 params.standby_thread_policy(), params.max_threads(), | |
| 73 params.suggested_reclaim_time(), params.backward_compatibility()); | |
| 74 } | |
| 75 | |
| 76 } // namespace | 61 } // namespace |
| 77 | 62 |
| 78 // static | 63 // static |
| 79 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( | 64 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( |
| 80 const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector, | |
| 81 const WorkerPoolIndexForTraitsCallback& | |
| 82 worker_pool_index_for_traits_callback) { | |
| 83 std::unique_ptr<TaskSchedulerImpl> scheduler( | |
| 84 new TaskSchedulerImpl(worker_pool_index_for_traits_callback)); | |
| 85 scheduler->Initialize(worker_pool_params_vector); | |
| 86 return scheduler; | |
| 87 } | |
| 88 | |
| 89 // static | |
| 90 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( | |
| 91 const std::string& name, | 65 const std::string& name, |
| 92 const TaskScheduler::InitParams& init_params) { | 66 const TaskScheduler::InitParams& init_params) { |
| 93 // Create a vector of SchedulerWorkerPoolParams using names and priority hints | 67 auto task_scheduler = WrapUnique(new TaskSchedulerImpl(name)); |
| 94 // derived from |kEnvironmentParams| and other params from |init_params|. | 68 task_scheduler->Initialize(init_params); |
| 95 std::vector<SchedulerWorkerPoolParams> worker_pool_params_vector; | 69 return task_scheduler; |
| 96 AddAugmentedSchedulerWorkerPoolParamsToVector( | |
| 97 BACKGROUND, name, init_params.background_worker_pool_params, | |
| 98 &worker_pool_params_vector); | |
| 99 AddAugmentedSchedulerWorkerPoolParamsToVector( | |
| 100 BACKGROUND_BLOCKING, name, | |
| 101 init_params.background_blocking_worker_pool_params, | |
| 102 &worker_pool_params_vector); | |
| 103 AddAugmentedSchedulerWorkerPoolParamsToVector( | |
| 104 FOREGROUND, name, init_params.foreground_worker_pool_params, | |
| 105 &worker_pool_params_vector); | |
| 106 AddAugmentedSchedulerWorkerPoolParamsToVector( | |
| 107 FOREGROUND_BLOCKING, name, | |
| 108 init_params.foreground_blocking_worker_pool_params, | |
| 109 &worker_pool_params_vector); | |
| 110 DCHECK_EQ(static_cast<size_t>(ENVIRONMENT_COUNT), | |
| 111 worker_pool_params_vector.size()); | |
| 112 | |
| 113 return Create(worker_pool_params_vector, Bind(&GetEnvironmentIndexForTraits)); | |
| 114 } | 70 } |
| 115 | 71 |
| 116 TaskSchedulerImpl::~TaskSchedulerImpl() { | 72 TaskSchedulerImpl::~TaskSchedulerImpl() { |
| 117 #if DCHECK_IS_ON() | 73 #if DCHECK_IS_ON() |
| 118 DCHECK(join_for_testing_returned_.IsSet()); | 74 DCHECK(join_for_testing_returned_.IsSet()); |
| 119 #endif | 75 #endif |
| 120 } | 76 } |
| 121 | 77 |
| 122 void TaskSchedulerImpl::PostDelayedTaskWithTraits( | 78 void TaskSchedulerImpl::PostDelayedTaskWithTraits( |
| 123 const tracked_objects::Location& from_here, | 79 const tracked_objects::Location& from_here, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 138 scoped_refptr<SequencedTaskRunner> | 94 scoped_refptr<SequencedTaskRunner> |
| 139 TaskSchedulerImpl::CreateSequencedTaskRunnerWithTraits( | 95 TaskSchedulerImpl::CreateSequencedTaskRunnerWithTraits( |
| 140 const TaskTraits& traits) { | 96 const TaskTraits& traits) { |
| 141 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits( | 97 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits( |
| 142 traits); | 98 traits); |
| 143 } | 99 } |
| 144 | 100 |
| 145 scoped_refptr<SingleThreadTaskRunner> | 101 scoped_refptr<SingleThreadTaskRunner> |
| 146 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits( | 102 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits( |
| 147 const TaskTraits& traits) { | 103 const TaskTraits& traits) { |
| 104 const auto& environment_params = |
| 105 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; |
| 148 return single_thread_task_runner_manager_ | 106 return single_thread_task_runner_manager_ |
| 149 ->CreateSingleThreadTaskRunnerWithTraits(traits); | 107 ->CreateSingleThreadTaskRunnerWithTraits( |
| 108 name_ + environment_params.name_suffix, |
| 109 environment_params.priority_hint, traits); |
| 150 } | 110 } |
| 151 | 111 |
| 152 #if defined(OS_WIN) | 112 #if defined(OS_WIN) |
| 153 scoped_refptr<SingleThreadTaskRunner> | 113 scoped_refptr<SingleThreadTaskRunner> |
| 154 TaskSchedulerImpl::CreateCOMSTATaskRunnerWithTraits(const TaskTraits& traits) { | 114 TaskSchedulerImpl::CreateCOMSTATaskRunnerWithTraits(const TaskTraits& traits) { |
| 115 const auto& environment_params = |
| 116 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; |
| 155 return single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 117 return single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 156 traits); | 118 environment_params.name_suffix, environment_params.priority_hint, traits); |
| 157 } | 119 } |
| 158 #endif // defined(OS_WIN) | 120 #endif // defined(OS_WIN) |
| 159 | 121 |
| 160 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { | 122 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { |
| 161 std::vector<const HistogramBase*> histograms; | 123 std::vector<const HistogramBase*> histograms; |
| 162 for (const auto& worker_pool : worker_pools_) | 124 for (const auto& worker_pool : worker_pools_) |
| 163 worker_pool->GetHistograms(&histograms); | 125 worker_pool->GetHistograms(&histograms); |
| 164 | 126 |
| 165 return histograms; | 127 return histograms; |
| 166 } | 128 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 189 for (const auto& worker_pool : worker_pools_) | 151 for (const auto& worker_pool : worker_pools_) |
| 190 worker_pool->DisallowWorkerDetachmentForTesting(); | 152 worker_pool->DisallowWorkerDetachmentForTesting(); |
| 191 for (const auto& worker_pool : worker_pools_) | 153 for (const auto& worker_pool : worker_pools_) |
| 192 worker_pool->JoinForTesting(); | 154 worker_pool->JoinForTesting(); |
| 193 service_thread_.Stop(); | 155 service_thread_.Stop(); |
| 194 #if DCHECK_IS_ON() | 156 #if DCHECK_IS_ON() |
| 195 join_for_testing_returned_.Set(); | 157 join_for_testing_returned_.Set(); |
| 196 #endif | 158 #endif |
| 197 } | 159 } |
| 198 | 160 |
| 199 TaskSchedulerImpl::TaskSchedulerImpl(const WorkerPoolIndexForTraitsCallback& | 161 TaskSchedulerImpl::TaskSchedulerImpl(const std::string& name) |
| 200 worker_pool_index_for_traits_callback) | 162 : name_(name), service_thread_("TaskSchedulerServiceThread") {} |
| 201 : service_thread_("TaskSchedulerServiceThread"), | |
| 202 worker_pool_index_for_traits_callback_( | |
| 203 worker_pool_index_for_traits_callback) { | |
| 204 DCHECK(!worker_pool_index_for_traits_callback_.is_null()); | |
| 205 } | |
| 206 | 163 |
| 207 void TaskSchedulerImpl::Initialize( | 164 void TaskSchedulerImpl::Initialize( |
| 208 const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector) { | 165 const TaskScheduler::InitParams& init_params) { |
| 209 DCHECK(!worker_pool_params_vector.empty()); | |
| 210 | |
| 211 // Start the service thread. On platforms that support it (POSIX except NaCL | 166 // Start the service thread. On platforms that support it (POSIX except NaCL |
| 212 // SFI), the service thread runs a MessageLoopForIO which is used to support | 167 // SFI), the service thread runs a MessageLoopForIO which is used to support |
| 213 // FileDescriptorWatcher in the scope in which tasks run. | 168 // FileDescriptorWatcher in the scope in which tasks run. |
| 214 Thread::Options service_thread_options; | 169 Thread::Options service_thread_options; |
| 215 service_thread_options.message_loop_type = | 170 service_thread_options.message_loop_type = |
| 216 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) | 171 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 217 MessageLoop::TYPE_IO; | 172 MessageLoop::TYPE_IO; |
| 218 #else | 173 #else |
| 219 MessageLoop::TYPE_DEFAULT; | 174 MessageLoop::TYPE_DEFAULT; |
| 220 #endif | 175 #endif |
| (...skipping 10 matching lines...) Expand all Loading... |
| 231 base::MakeUnique<TaskTracker>(); | 186 base::MakeUnique<TaskTracker>(); |
| 232 #endif | 187 #endif |
| 233 | 188 |
| 234 // Instantiate DelayedTaskManager. Needs to happen after starting the service | 189 // Instantiate DelayedTaskManager. Needs to happen after starting the service |
| 235 // thread to get its task_runner(). | 190 // thread to get its task_runner(). |
| 236 delayed_task_manager_ = | 191 delayed_task_manager_ = |
| 237 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 192 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); |
| 238 | 193 |
| 239 single_thread_task_runner_manager_ = | 194 single_thread_task_runner_manager_ = |
| 240 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | 195 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( |
| 241 worker_pool_params_vector, worker_pool_index_for_traits_callback_, | |
| 242 task_tracker_.get(), delayed_task_manager_.get()); | 196 task_tracker_.get(), delayed_task_manager_.get()); |
| 243 single_thread_task_runner_manager_->Start(); | 197 single_thread_task_runner_manager_->Start(); |
| 244 | 198 |
| 245 // Callback invoked by workers to re-enqueue a sequence in the appropriate | 199 // Callback invoked by workers to re-enqueue a sequence in the appropriate |
| 246 // PriorityQueue. | 200 // PriorityQueue. |
| 247 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback | 201 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback |
| 248 re_enqueue_sequence_callback = | 202 re_enqueue_sequence_callback = |
| 249 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | 203 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); |
| 250 | 204 |
| 205 // Order must match the EnvironmentType enum. |
| 206 const SchedulerWorkerPoolParams* worker_pool_params[] = { |
| 207 &init_params.background_worker_pool_params, |
| 208 &init_params.background_blocking_worker_pool_params, |
| 209 &init_params.foreground_worker_pool_params, |
| 210 &init_params.foreground_blocking_worker_pool_params}; |
| 211 |
| 212 static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT, |
| 213 "The size of |worker_pools_| must match ENVIRONMENT_COUNT."); |
| 214 static_assert( |
| 215 arraysize(kEnvironmentParams) == ENVIRONMENT_COUNT, |
| 216 "The size of |kEnvironmentParams| must match ENVIRONMENT_COUNT."); |
| 217 static_assert( |
| 218 arraysize(worker_pool_params) == ENVIRONMENT_COUNT, |
| 219 "The size of |worker_pool_params| must match ENVIRONMENT_COUNT."); |
| 220 |
| 251 // Start worker pools. | 221 // Start worker pools. |
| 252 for (const auto& worker_pool_params : worker_pool_params_vector) { | 222 for (int environment_type = 0; environment_type < ENVIRONMENT_COUNT; |
| 253 // Passing pointers to objects owned by |this| to | 223 ++environment_type) { |
| 254 // SchedulerWorkerPoolImpl::Create() is safe because a TaskSchedulerImpl | 224 // Passing pointers to objects owned by |this| to the constructor of |
| 255 // can't be deleted before all its worker pools have been joined. | 225 // SchedulerWorkerPoolImpl is safe because a TaskSchedulerImpl can't be |
| 256 worker_pools_.push_back(MakeUnique<SchedulerWorkerPoolImpl>( | 226 // deleted before all its worker pools have been joined. |
| 257 worker_pool_params.name(), worker_pool_params.priority_hint(), | 227 worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( |
| 228 name_ + kEnvironmentParams[environment_type].name_suffix, |
| 229 kEnvironmentParams[environment_type].priority_hint, |
| 258 re_enqueue_sequence_callback, task_tracker_.get(), | 230 re_enqueue_sequence_callback, task_tracker_.get(), |
| 259 delayed_task_manager_.get())); | 231 delayed_task_manager_.get()); |
| 260 worker_pools_.back()->Start(worker_pool_params); | 232 worker_pools_[environment_type]->Start( |
| 233 *worker_pool_params[environment_type]); |
| 261 } | 234 } |
| 262 } | 235 } |
| 263 | 236 |
| 264 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( | 237 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( |
| 265 const TaskTraits& traits) const { | 238 const TaskTraits& traits) const { |
| 266 const size_t index = worker_pool_index_for_traits_callback_.Run(traits); | 239 return worker_pools_[GetEnvironmentIndexForTraits(traits)].get(); |
| 267 DCHECK_LT(index, worker_pools_.size()); | |
| 268 return worker_pools_[index].get(); | |
| 269 } | 240 } |
| 270 | 241 |
| 271 void TaskSchedulerImpl::ReEnqueueSequenceCallback( | 242 void TaskSchedulerImpl::ReEnqueueSequenceCallback( |
| 272 scoped_refptr<Sequence> sequence) { | 243 scoped_refptr<Sequence> sequence) { |
| 273 DCHECK(sequence); | 244 DCHECK(sequence); |
| 274 | 245 |
| 275 const SequenceSortKey sort_key = sequence->GetSortKey(); | 246 const SequenceSortKey sort_key = sequence->GetSortKey(); |
| 276 | 247 |
| 277 // The next task in |sequence| should run in a worker pool suited for its | 248 // The next task in |sequence| should run in a worker pool suited for its |
| 278 // traits, except for the priority which is adjusted to the highest priority | 249 // traits, except for the priority which is adjusted to the highest priority |
| 279 // in |sequence|. | 250 // in |sequence|. |
| 280 const TaskTraits traits = | 251 const TaskTraits traits = |
| 281 sequence->PeekTaskTraits().WithPriority(sort_key.priority()); | 252 sequence->PeekTaskTraits().WithPriority(sort_key.priority()); |
| 282 | 253 |
| 283 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | 254 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), |
| 284 sort_key); | 255 sort_key); |
| 285 } | 256 } |
| 286 | 257 |
| 287 } // namespace internal | 258 } // namespace internal |
| 288 } // namespace base | 259 } // namespace base |
| OLD | NEW |