Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: base/task_scheduler/task_scheduler_impl.cc

Issue 2749303002: [reference - do not submit] Always create four pools in TaskSchedulerImpl. (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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" 13 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h"
14 #include "base/task_scheduler/scheduler_worker_pool_params.h" 14 #include "base/task_scheduler/scheduler_worker_pool_params.h"
15 #include "base/task_scheduler/sequence_sort_key.h" 15 #include "base/task_scheduler/sequence_sort_key.h"
16 #include "base/task_scheduler/task.h" 16 #include "base/task_scheduler/task.h"
17 #include "base/task_scheduler/task_tracker.h" 17 #include "base/task_scheduler/task_tracker.h"
18 #include "build/build_config.h" 18 #include "build/build_config.h"
19 19
20 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) 20 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
21 #include "base/task_scheduler/task_tracker_posix.h" 21 #include "base/task_scheduler/task_tracker_posix.h"
22 #endif 22 #endif
23 23
24 namespace base { 24 namespace base {
25 namespace internal { 25 namespace internal {
26 26
27 namespace {
28
29 enum EnvironmentType {
30 BACKGROUND = 0,
31 BACKGROUND_BLOCKING,
32 FOREGROUND,
33 FOREGROUND_BLOCKING,
34 ENVIRONMENT_COUNT // Always last.
35 };
36
37 // Order must match the EnvironmentType enum.
38 constexpr struct {
39 // The threads and histograms of this environment will be labeled with
40 // task scheduler name + |name_suffix|.
41 const char* name_suffix;
42
43 // Preferred priority for threads in this environment; the actual thread
44 // priority depends on shutdown state and platform capabilities.
45 ThreadPriority priority_hint;
46
47 // Offset of the SchedulerWorkerPoolParams corresponding to this environement
48 // in TaskSchedulerInitParams.
49 size_t offset;
50 } kEnvironmentParams[] = {
51 {"Background", base::ThreadPriority::BACKGROUND,
52 offsetof(TaskSchedulerInitParams, background_worker_pool_params)},
53 {"BackgroundBlocking", base::ThreadPriority::BACKGROUND,
54 offsetof(TaskSchedulerInitParams, background_blocking_worker_pool_params)},
55 {"Foreground", base::ThreadPriority::NORMAL,
56 offsetof(TaskSchedulerInitParams, foreground_worker_pool_params)},
57 {"ForegroundBlocking", base::ThreadPriority::NORMAL,
58 offsetof(TaskSchedulerInitParams, foreground_blocking_worker_pool_params)},
59 };
60
61 size_t GetEnvironmentIndexForTraits(const TaskTraits& traits) {
62 const bool is_background =
63 traits.priority() == base::TaskPriority::BACKGROUND;
64 if (traits.may_block() || traits.with_base_sync_primitives())
65 return is_background ? BACKGROUND_BLOCKING : FOREGROUND_BLOCKING;
66 return is_background ? BACKGROUND : FOREGROUND;
67 }
68
69 } // namespace
70
27 // static 71 // static
28 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( 72 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create(
29 const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector, 73 const std::string& name,
30 const WorkerPoolIndexForTraitsCallback& 74 const TaskSchedulerInitParams& init_params) {
31 worker_pool_index_for_traits_callback) { 75 std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl(name));
32 std::unique_ptr<TaskSchedulerImpl> scheduler( 76 scheduler->Initialize(init_params);
33 new TaskSchedulerImpl(worker_pool_index_for_traits_callback));
34 scheduler->Initialize(worker_pool_params_vector);
35 return scheduler; 77 return scheduler;
36 } 78 }
37 79
38 TaskSchedulerImpl::~TaskSchedulerImpl() { 80 TaskSchedulerImpl::~TaskSchedulerImpl() {
39 #if DCHECK_IS_ON() 81 #if DCHECK_IS_ON()
40 DCHECK(join_for_testing_returned_.IsSet()); 82 DCHECK(join_for_testing_returned_.IsSet());
41 #endif 83 #endif
42 } 84 }
43 85
44 void TaskSchedulerImpl::PostDelayedTaskWithTraits( 86 void TaskSchedulerImpl::PostDelayedTaskWithTraits(
(...skipping 15 matching lines...) Expand all
60 scoped_refptr<SequencedTaskRunner> 102 scoped_refptr<SequencedTaskRunner>
61 TaskSchedulerImpl::CreateSequencedTaskRunnerWithTraits( 103 TaskSchedulerImpl::CreateSequencedTaskRunnerWithTraits(
62 const TaskTraits& traits) { 104 const TaskTraits& traits) {
63 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits( 105 return GetWorkerPoolForTraits(traits)->CreateSequencedTaskRunnerWithTraits(
64 traits); 106 traits);
65 } 107 }
66 108
67 scoped_refptr<SingleThreadTaskRunner> 109 scoped_refptr<SingleThreadTaskRunner>
68 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits( 110 TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits(
69 const TaskTraits& traits) { 111 const TaskTraits& traits) {
112 const auto& environment =
113 kEnvironmentParams[GetEnvironmentIndexForTraits(traits)];
70 return single_thread_task_runner_manager_ 114 return single_thread_task_runner_manager_
71 ->CreateSingleThreadTaskRunnerWithTraits(traits); 115 ->CreateSingleThreadTaskRunnerWithTraits(
116 name_ + environment.name_suffix, environment.priority_hint, traits);
72 } 117 }
73 118
74 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const { 119 std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const {
75 std::vector<const HistogramBase*> histograms; 120 std::vector<const HistogramBase*> histograms;
76 for (const auto& worker_pool : worker_pools_) 121 for (const auto& worker_pool : worker_pools_)
77 worker_pool->GetHistograms(&histograms); 122 worker_pool->GetHistograms(&histograms);
78 123
79 return histograms; 124 return histograms;
80 } 125 }
81 126
(...skipping 21 matching lines...) Expand all
103 for (const auto& worker_pool : worker_pools_) 148 for (const auto& worker_pool : worker_pools_)
104 worker_pool->DisallowWorkerDetachmentForTesting(); 149 worker_pool->DisallowWorkerDetachmentForTesting();
105 for (const auto& worker_pool : worker_pools_) 150 for (const auto& worker_pool : worker_pools_)
106 worker_pool->JoinForTesting(); 151 worker_pool->JoinForTesting();
107 service_thread_.Stop(); 152 service_thread_.Stop();
108 #if DCHECK_IS_ON() 153 #if DCHECK_IS_ON()
109 join_for_testing_returned_.Set(); 154 join_for_testing_returned_.Set();
110 #endif 155 #endif
111 } 156 }
112 157
113 TaskSchedulerImpl::TaskSchedulerImpl(const WorkerPoolIndexForTraitsCallback& 158 TaskSchedulerImpl::TaskSchedulerImpl(const std::string& name)
114 worker_pool_index_for_traits_callback) 159 : name_(name), service_thread_("TaskSchedulerServiceThread") {
115 : service_thread_("TaskSchedulerServiceThread"), 160 static_assert(
116 worker_pool_index_for_traits_callback_( 161 sizeof(TaskSchedulerInitParams) / sizeof(SchedulerWorkerPoolParams) ==
117 worker_pool_index_for_traits_callback) { 162 ENVIRONMENT_COUNT,
118 DCHECK(!worker_pool_index_for_traits_callback_.is_null()); 163 "There must be the same number of elements in "
164 "TaskSchedulerInitParams and EnvironmentType.");
165 static_assert(arraysize(kEnvironmentParams) == ENVIRONMENT_COUNT,
166 "There must be the same number of elements in "
167 "|kEnvironmentParams| and EnvironmentType.");
168 static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT,
169 "There must be the same number of elements in |worker_pools_| "
170 "and EnvironmentType.");
119 } 171 }
120 172
121 void TaskSchedulerImpl::Initialize( 173 void TaskSchedulerImpl::Initialize(const TaskSchedulerInitParams& init_params) {
122 const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector) {
123 DCHECK(!worker_pool_params_vector.empty());
124
125 // Start the service thread. On platforms that support it (POSIX except NaCL 174 // Start the service thread. On platforms that support it (POSIX except NaCL
126 // SFI), the service thread runs a MessageLoopForIO which is used to support 175 // SFI), the service thread runs a MessageLoopForIO which is used to support
127 // FileDescriptorWatcher in the scope in which tasks run. 176 // FileDescriptorWatcher in the scope in which tasks run.
128 Thread::Options service_thread_options; 177 Thread::Options service_thread_options;
129 service_thread_options.message_loop_type = 178 service_thread_options.message_loop_type =
130 #if defined(OS_POSIX) && !defined(OS_NACL_SFI) 179 #if defined(OS_POSIX) && !defined(OS_NACL_SFI)
131 MessageLoop::TYPE_IO; 180 MessageLoop::TYPE_IO;
132 #else 181 #else
133 MessageLoop::TYPE_DEFAULT; 182 MessageLoop::TYPE_DEFAULT;
134 #endif 183 #endif
(...skipping 10 matching lines...) Expand all
145 base::MakeUnique<TaskTracker>(); 194 base::MakeUnique<TaskTracker>();
146 #endif 195 #endif
147 196
148 // Instantiate DelayedTaskManager. Needs to happen after starting the service 197 // Instantiate DelayedTaskManager. Needs to happen after starting the service
149 // thread to get its task_runner(). 198 // thread to get its task_runner().
150 delayed_task_manager_ = 199 delayed_task_manager_ =
151 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); 200 base::MakeUnique<DelayedTaskManager>(service_thread_.task_runner());
152 201
153 single_thread_task_runner_manager_ = 202 single_thread_task_runner_manager_ =
154 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( 203 MakeUnique<SchedulerSingleThreadTaskRunnerManager>(
155 worker_pool_params_vector, worker_pool_index_for_traits_callback_,
156 task_tracker_.get(), delayed_task_manager_.get()); 204 task_tracker_.get(), delayed_task_manager_.get());
157 205
158 // Callback invoked by workers to re-enqueue a sequence in the appropriate 206 // Callback invoked by workers to re-enqueue a sequence in the appropriate
159 // PriorityQueue. 207 // PriorityQueue.
160 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback 208 const SchedulerWorkerPoolImpl::ReEnqueueSequenceCallback
161 re_enqueue_sequence_callback = 209 re_enqueue_sequence_callback =
162 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); 210 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this));
163 211
164 // Start worker pools. 212 // Start worker pools.
165 for (const auto& worker_pool_params : worker_pool_params_vector) { 213 for (size_t index = 0; index < ENVIRONMENT_COUNT; ++index) {
166 // Passing pointers to objects owned by |this| to 214 // Passing pointers to objects owned by |this| to
167 // SchedulerWorkerPoolImpl::Create() is safe because a TaskSchedulerImpl 215 // SchedulerWorkerPoolImpl::Create() is safe because a TaskSchedulerImpl
168 // can't be deleted before all its worker pools have been joined. 216 // can't be deleted before all its worker pools have been joined.
169 worker_pools_.push_back(SchedulerWorkerPoolImpl::Create( 217 worker_pools_[index] = SchedulerWorkerPoolImpl::Create(
170 worker_pool_params, re_enqueue_sequence_callback, task_tracker_.get(), 218 name_ + kEnvironmentParams[index].name_suffix,
171 delayed_task_manager_.get())); 219 kEnvironmentParams[index].priority_hint,
172 CHECK(worker_pools_.back()); 220 *reinterpret_cast<const SchedulerWorkerPoolParams*>(
221 reinterpret_cast<const char*>(&init_params) +
222 kEnvironmentParams[index].offset),
223 re_enqueue_sequence_callback, task_tracker_.get(),
224 delayed_task_manager_.get());
225 CHECK(worker_pools_[index]);
173 } 226 }
174 } 227 }
175 228
176 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits( 229 SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits(
177 const TaskTraits& traits) const { 230 const TaskTraits& traits) const {
178 const size_t index = worker_pool_index_for_traits_callback_.Run(traits); 231 return worker_pools_[GetEnvironmentIndexForTraits(traits)].get();
179 DCHECK_LT(index, worker_pools_.size());
180 return worker_pools_[index].get();
181 } 232 }
182 233
183 void TaskSchedulerImpl::ReEnqueueSequenceCallback( 234 void TaskSchedulerImpl::ReEnqueueSequenceCallback(
184 scoped_refptr<Sequence> sequence) { 235 scoped_refptr<Sequence> sequence) {
185 DCHECK(sequence); 236 DCHECK(sequence);
186 237
187 const SequenceSortKey sort_key = sequence->GetSortKey(); 238 const SequenceSortKey sort_key = sequence->GetSortKey();
188 239
189 // The next task in |sequence| should run in a worker pool suited for its 240 // The next task in |sequence| should run in a worker pool suited for its
190 // traits, except for the priority which is adjusted to the highest priority 241 // traits, except for the priority which is adjusted to the highest priority
191 // in |sequence|. 242 // in |sequence|.
192 const TaskTraits traits = 243 const TaskTraits traits =
193 sequence->PeekTaskTraits().WithPriority(sort_key.priority()); 244 sequence->PeekTaskTraits().WithPriority(sort_key.priority());
194 245
195 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), 246 GetWorkerPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence),
196 sort_key); 247 sort_key);
197 } 248 }
198 249
199 } // namespace internal 250 } // namespace internal
200 } // namespace base 251 } // namespace base
OLDNEW
« no previous file with comments | « base/task_scheduler/task_scheduler_impl.h ('k') | base/task_scheduler/task_scheduler_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698