| 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" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/task_scheduler/delayed_task_manager.h" | 12 #include "base/task_scheduler/delayed_task_manager.h" |
| 13 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" | |
| 14 #include "base/task_scheduler/scheduler_worker_pool_params.h" | 13 #include "base/task_scheduler/scheduler_worker_pool_params.h" |
| 15 #include "base/task_scheduler/sequence_sort_key.h" | 14 #include "base/task_scheduler/sequence_sort_key.h" |
| 16 #include "base/task_scheduler/task.h" | 15 #include "base/task_scheduler/task.h" |
| 17 #include "base/task_scheduler/task_tracker.h" | 16 #include "base/task_scheduler/task_tracker.h" |
| 18 | 17 |
| 19 namespace base { | 18 namespace base { |
| 20 namespace internal { | 19 namespace internal { |
| 21 | 20 |
| 22 namespace { | 21 namespace { |
| 23 | 22 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits( | 91 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits( |
| 93 traits); | 92 traits); |
| 94 } | 93 } |
| 95 | 94 |
| 96 scoped_refptr<SingleThreadTaskRunner> | 95 scoped_refptr<SingleThreadTaskRunner> |
| 97 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits( | 96 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits( |
| 98 const TaskTraits& traits) { | 97 const TaskTraits& traits) { |
| 99 const auto& environment_params = | 98 const auto& environment_params = |
| 100 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; | 99 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; |
| 101 return single_thread_task_runner_manager_ | 100 return single_thread_task_runner_manager_ |
| 102 ->CreateSingleThreadTaskRunnerWithTraits( | 101 .CreateSingleThreadTaskRunnerWithTraits( |
| 103 name_ + environment_params.name_suffix, | 102 name_ + environment_params.name_suffix, |
| 104 environment_params.priority_hint, traits); | 103 environment_params.priority_hint, traits); |
| 105 } | 104 } |
| 106 | 105 |
| 107 #if defined(OS_WIN) | 106 #if defined(OS_WIN) |
| 108 scoped_refptr<SingleThreadTaskRunner> | 107 scoped_refptr<SingleThreadTaskRunner> |
| 109 TaskSchedulerImpl::CreateCOMSTATaskRunnerWithTraits(const TaskTraits& traits) { | 108 TaskSchedulerImpl::CreateCOMSTATaskRunnerWithTraits(const TaskTraits& traits) { |
| 110 const auto& environment_params = | 109 const auto& environment_params = |
| 111 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; | 110 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)]; |
| 112 return single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 111 return single_thread_task_runner_manager_.CreateCOMSTATaskRunnerWithTraits( |
| 113 environment_params.name_suffix, environment_params.priority_hint, traits); | 112 environment_params.name_suffix, environment_params.priority_hint, traits); |
| 114 } | 113 } |
| 115 #endif // defined(OS_WIN) | 114 #endif // defined(OS_WIN) |
| 116 | 115 |
| 117 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { | 116 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { |
| 118 std::vector<const HistogramBase*> histograms; | 117 std::vector<const HistogramBase*> histograms; |
| 119 for (const auto& worker_pool : worker_pools_) | 118 for (const auto& worker_pool : worker_pools_) |
| 120 worker_pool->GetHistograms(&histograms); | 119 worker_pool->GetHistograms(&histograms); |
| 121 | 120 |
| 122 return histograms; | 121 return histograms; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 133 } | 132 } |
| 134 | 133 |
| 135 void TaskSchedulerImpl::FlushForTesting() { | 134 void TaskSchedulerImpl::FlushForTesting() { |
| 136 task_tracker_.Flush(); | 135 task_tracker_.Flush(); |
| 137 } | 136 } |
| 138 | 137 |
| 139 void TaskSchedulerImpl::JoinForTesting() { | 138 void TaskSchedulerImpl::JoinForTesting() { |
| 140 #if DCHECK_IS_ON() | 139 #if DCHECK_IS_ON() |
| 141 DCHECK(!join_for_testing_returned_.IsSet()); | 140 DCHECK(!join_for_testing_returned_.IsSet()); |
| 142 #endif | 141 #endif |
| 143 single_thread_task_runner_manager_->JoinForTesting(); | 142 single_thread_task_runner_manager_.JoinForTesting(); |
| 144 for (const auto& worker_pool : worker_pools_) | 143 for (const auto& worker_pool : worker_pools_) |
| 145 worker_pool->DisallowWorkerDetachmentForTesting(); | 144 worker_pool->DisallowWorkerDetachmentForTesting(); |
| 146 for (const auto& worker_pool : worker_pools_) | 145 for (const auto& worker_pool : worker_pools_) |
| 147 worker_pool->JoinForTesting(); | 146 worker_pool->JoinForTesting(); |
| 148 service_thread_.Stop(); | 147 service_thread_.Stop(); |
| 149 #if DCHECK_IS_ON() | 148 #if DCHECK_IS_ON() |
| 150 join_for_testing_returned_.Set(); | 149 join_for_testing_returned_.Set(); |
| 151 #endif | 150 #endif |
| 152 } | 151 } |
| 153 | 152 |
| 154 TaskSchedulerImpl::TaskSchedulerImpl(const std::string& name) | 153 TaskSchedulerImpl::TaskSchedulerImpl(const std::string& name) |
| 155 : name_(name), service_thread_("TaskSchedulerServiceThread") {} | 154 : name_(name), |
| 155 service_thread_("TaskSchedulerServiceThread"), |
| 156 single_thread_task_runner_manager_(&task_tracker_, |
| 157 &delayed_task_manager_) {} |
| 156 | 158 |
| 157 void TaskSchedulerImpl::Initialize( | 159 void TaskSchedulerImpl::Initialize( |
| 158 const TaskScheduler::InitParams& init_params) { | 160 const TaskScheduler::InitParams& init_params) { |
| 159 // Start the service thread. On platforms that support it (POSIX except NaCL | 161 // Start the service thread. On platforms that support it (POSIX except NaCL |
| 160 // SFI), the service thread runs a MessageLoopForIO which is used to support | 162 // SFI), the service thread runs a MessageLoopForIO which is used to support |
| 161 // FileDescriptorWatcher in the scope in which tasks run. | 163 // FileDescriptorWatcher in the scope in which tasks run. |
| 162 Thread::Options service_thread_options; | 164 Thread::Options service_thread_options; |
| 163 service_thread_options.message_loop_type = | 165 service_thread_options.message_loop_type = |
| 164 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) | 166 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 165 MessageLoop::TYPE_IO; | 167 MessageLoop::TYPE_IO; |
| 166 #else | 168 #else |
| 167 MessageLoop::TYPE_DEFAULT; | 169 MessageLoop::TYPE_DEFAULT; |
| 168 #endif | 170 #endif |
| 169 service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM; | 171 service_thread_options.timer_slack = TIMER_SLACK_MAXIMUM; |
| 170 CHECK(service_thread_.StartWithOptions(service_thread_options)); | 172 CHECK(service_thread_.StartWithOptions(service_thread_options)); |
| 171 | 173 |
| 172 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) | 174 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) |
| 173 // Needs to happen after starting the service thread to get its | 175 // Needs to happen after starting the service thread to get its |
| 174 // message_loop(). | 176 // message_loop(). |
| 175 task_tracker_.set_watch_file_descriptor_message_loop( | 177 task_tracker_.set_watch_file_descriptor_message_loop( |
| 176 static_cast<MessageLoopForIO*>(service_thread_.message_loop())); | 178 static_cast<MessageLoopForIO*>(service_thread_.message_loop())); |
| 177 #endif | 179 #endif |
| 178 | 180 |
| 179 // Needs to happen after starting the service thread to get its task_runner(). | 181 // Needs to happen after starting the service thread to get its task_runner(). |
| 180 delayed_task_manager_ = | 182 delayed_task_manager_.Start(service_thread_.task_runner()); |
| 181 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | |
| 182 | 183 |
| 183 single_thread_task_runner_manager_ = | 184 single_thread_task_runner_manager_.Start(); |
| 184 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | |
| 185 &task_tracker_, delayed_task_manager_.get()); | |
| 186 single_thread_task_runner_manager_->Start(); | |
| 187 | 185 |
| 188 // Callback invoked by workers to re-enqueue a sequence in the appropriate | 186 // Callback invoked by workers to re-enqueue a sequence in the appropriate |
| 189 // PriorityQueue. | 187 // PriorityQueue. |
| 190 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback | 188 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback |
| 191 re_enqueue_sequence_callback = | 189 re_enqueue_sequence_callback = |
| 192 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | 190 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); |
| 193 | 191 |
| 194 // Order must match the EnvironmentType enum. | 192 // Order must match the EnvironmentType enum. |
| 195 const SchedulerWorkerPoolParams* worker_pool_params[] = { | 193 const SchedulerWorkerPoolParams* worker_pool_params[] = { |
| 196 &init_params.background_worker_pool_params, | 194 &init_params.background_worker_pool_params, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 209 | 207 |
| 210 // Start worker pools. | 208 // Start worker pools. |
| 211 for (int environment_type = 0; environment_type < ENVIRONMENT_COUNT; | 209 for (int environment_type = 0; environment_type < ENVIRONMENT_COUNT; |
| 212 ++environment_type) { | 210 ++environment_type) { |
| 213 // Passing pointers to objects owned by |this| to the constructor of | 211 // Passing pointers to objects owned by |this| to the constructor of |
| 214 // SchedulerWorkerPoolImpl is safe because a TaskSchedulerImpl can't be | 212 // SchedulerWorkerPoolImpl is safe because a TaskSchedulerImpl can't be |
| 215 // deleted before all its worker pools have been joined. | 213 // deleted before all its worker pools have been joined. |
| 216 worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( | 214 worker_pools_[environment_type] = MakeUnique<SchedulerWorkerPoolImpl>( |
| 217 name_ + kEnvironmentParams[environment_type].name_suffix, | 215 name_ + kEnvironmentParams[environment_type].name_suffix, |
| 218 kEnvironmentParams[environment_type].priority_hint, | 216 kEnvironmentParams[environment_type].priority_hint, |
| 219 re_enqueue_sequence_callback, &task_tracker_, | 217 re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); |
| 220 delayed_task_manager_.get()); | |
| 221 worker_pools_[environment_type]->Start( | 218 worker_pools_[environment_type]->Start( |
| 222 *worker_pool_params[environment_type]); | 219 *worker_pool_params[environment_type]); |
| 223 } | 220 } |
| 224 } | 221 } |
| 225 | 222 |
| 226 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( | 223 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( |
| 227 const TaskTraits& traits) const { | 224 const TaskTraits& traits) const { |
| 228 return worker_pools_[GetEnvironmentIndexForTraits(traits)].get(); | 225 return worker_pools_[GetEnvironmentIndexForTraits(traits)].get(); |
| 229 } | 226 } |
| 230 | 227 |
| 231 void TaskSchedulerImpl::ReEnqueueSequenceCallback( | 228 void TaskSchedulerImpl::ReEnqueueSequenceCallback( |
| 232 scoped_refptr<Sequence> sequence) { | 229 scoped_refptr<Sequence> sequence) { |
| 233 DCHECK(sequence); | 230 DCHECK(sequence); |
| 234 | 231 |
| 235 const SequenceSortKey sort_key = sequence->GetSortKey(); | 232 const SequenceSortKey sort_key = sequence->GetSortKey(); |
| 236 | 233 |
| 237 // The next task in |sequence| should run in a worker pool suited for its | 234 // The next task in |sequence| should run in a worker pool suited for its |
| 238 // traits, except for the priority which is adjusted to the highest priority | 235 // traits, except for the priority which is adjusted to the highest priority |
| 239 // in |sequence|. | 236 // in |sequence|. |
| 240 const TaskTraits traits = | 237 const TaskTraits traits = |
| 241 sequence->PeekTaskTraits().WithPriority(sort_key.priority()); | 238 sequence->PeekTaskTraits().WithPriority(sort_key.priority()); |
| 242 | 239 |
| 243 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | 240 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), |
| 244 sort_key); | 241 sort_key); |
| 245 } | 242 } |
| 246 | 243 |
| 247 } // namespace internal | 244 } // namespace internal |
| 248 } // namespace base | 245 } // namespace base |
| OLD | NEW |