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 |