| Index: base/task_scheduler/task_scheduler_impl.cc
|
| diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc
|
| index e5c8abf716306f8602b0cde8786e10dc292f1739..a82877cb7cd82e234776217bf16d605fed58a755 100644
|
| --- a/base/task_scheduler/task_scheduler_impl.cc
|
| +++ b/base/task_scheduler/task_scheduler_impl.cc
|
| @@ -24,14 +24,56 @@
|
| namespace base {
|
| namespace internal {
|
|
|
| +namespace {
|
| +
|
| +enum EnvironmentType {
|
| + BACKGROUND = 0,
|
| + BACKGROUND_BLOCKING,
|
| + FOREGROUND,
|
| + FOREGROUND_BLOCKING,
|
| + ENVIRONMENT_COUNT // Always last.
|
| +};
|
| +
|
| +// Order must match the EnvironmentType enum.
|
| +constexpr struct {
|
| + // The threads and histograms of this environment will be labeled with
|
| + // task scheduler name + |name_suffix|.
|
| + const char* name_suffix;
|
| +
|
| + // Preferred priority for threads in this environment; the actual thread
|
| + // priority depends on shutdown state and platform capabilities.
|
| + ThreadPriority priority_hint;
|
| +
|
| + // Offset of the SchedulerWorkerPoolParams corresponding to this environement
|
| + // in TaskSchedulerInitParams.
|
| + size_t offset;
|
| +} kEnvironmentParams[] = {
|
| + {"Background", base::ThreadPriority::BACKGROUND,
|
| + offsetof(TaskSchedulerInitParams, background_worker_pool_params)},
|
| + {"BackgroundBlocking", base::ThreadPriority::BACKGROUND,
|
| + offsetof(TaskSchedulerInitParams, background_blocking_worker_pool_params)},
|
| + {"Foreground", base::ThreadPriority::NORMAL,
|
| + offsetof(TaskSchedulerInitParams, foreground_worker_pool_params)},
|
| + {"ForegroundBlocking", base::ThreadPriority::NORMAL,
|
| + offsetof(TaskSchedulerInitParams, foreground_blocking_worker_pool_params)},
|
| +};
|
| +
|
| +size_t GetEnvironmentIndexForTraits(const TaskTraits& traits) {
|
| + const bool is_background =
|
| + traits.priority() == base::TaskPriority::BACKGROUND;
|
| + if (traits.may_block() || traits.with_base_sync_primitives())
|
| + return is_background ? BACKGROUND_BLOCKING : FOREGROUND_BLOCKING;
|
| + return is_background ? BACKGROUND : FOREGROUND;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| // static
|
| std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create(
|
| - const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector,
|
| - const WorkerPoolIndexForTraitsCallback&
|
| - worker_pool_index_for_traits_callback) {
|
| - std::unique_ptr<TaskSchedulerImpl> scheduler(
|
| - new TaskSchedulerImpl(worker_pool_index_for_traits_callback));
|
| - scheduler->Initialize(worker_pool_params_vector);
|
| + const std::string& name,
|
| + const TaskSchedulerInitParams& init_params) {
|
| + std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl(name));
|
| + scheduler->Initialize(init_params);
|
| return scheduler;
|
| }
|
|
|
| @@ -67,8 +109,11 @@ TaskSchedulerImpl::CreateSequencedTaskRunnerWithTraits(
|
| scoped_refptr<SingleThreadTaskRunner>
|
| TaskSchedulerImpl::CreateSingleThreadTaskRunnerWithTraits(
|
| const TaskTraits& traits) {
|
| + const auto& environment =
|
| + kEnvironmentParams[GetEnvironmentIndexForTraits(traits)];
|
| return single_thread_task_runner_manager_
|
| - ->CreateSingleThreadTaskRunnerWithTraits(traits);
|
| + ->CreateSingleThreadTaskRunnerWithTraits(
|
| + name_ + environment.name_suffix, environment.priority_hint, traits);
|
| }
|
|
|
| std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const {
|
| @@ -110,18 +155,22 @@ void TaskSchedulerImpl::JoinForTesting() {
|
| #endif
|
| }
|
|
|
| -TaskSchedulerImpl::TaskSchedulerImpl(const WorkerPoolIndexForTraitsCallback&
|
| - worker_pool_index_for_traits_callback)
|
| - : service_thread_("TaskSchedulerServiceThread"),
|
| - worker_pool_index_for_traits_callback_(
|
| - worker_pool_index_for_traits_callback) {
|
| - DCHECK(!worker_pool_index_for_traits_callback_.is_null());
|
| +TaskSchedulerImpl::TaskSchedulerImpl(const std::string& name)
|
| + : name_(name), service_thread_("TaskSchedulerServiceThread") {
|
| + static_assert(
|
| + sizeof(TaskSchedulerInitParams) / sizeof(SchedulerWorkerPoolParams) ==
|
| + ENVIRONMENT_COUNT,
|
| + "There must be the same number of elements in "
|
| + "TaskSchedulerInitParams and EnvironmentType.");
|
| + static_assert(arraysize(kEnvironmentParams) == ENVIRONMENT_COUNT,
|
| + "There must be the same number of elements in "
|
| + "|kEnvironmentParams| and EnvironmentType.");
|
| + static_assert(arraysize(worker_pools_) == ENVIRONMENT_COUNT,
|
| + "There must be the same number of elements in |worker_pools_| "
|
| + "and EnvironmentType.");
|
| }
|
|
|
| -void TaskSchedulerImpl::Initialize(
|
| - const std::vector<SchedulerWorkerPoolParams>& worker_pool_params_vector) {
|
| - DCHECK(!worker_pool_params_vector.empty());
|
| -
|
| +void TaskSchedulerImpl::Initialize(const TaskSchedulerInitParams& init_params) {
|
| // Start the service thread. On platforms that support it (POSIX except NaCL
|
| // SFI), the service thread runs a MessageLoopForIO which is used to support
|
| // FileDescriptorWatcher in the scope in which tasks run.
|
| @@ -152,7 +201,6 @@ void TaskSchedulerImpl::Initialize(
|
|
|
| single_thread_task_runner_manager_ =
|
| MakeUnique<SchedulerSingleThreadTaskRunnerManager>(
|
| - worker_pool_params_vector, worker_pool_index_for_traits_callback_,
|
| task_tracker_.get(), delayed_task_manager_.get());
|
|
|
| // Callback invoked by workers to re-enqueue a sequence in the appropriate
|
| @@ -162,22 +210,25 @@ void TaskSchedulerImpl::Initialize(
|
| Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this));
|
|
|
| // Start worker pools.
|
| - for (const auto& worker_pool_params : worker_pool_params_vector) {
|
| + for (size_t index = 0; index < ENVIRONMENT_COUNT; ++index) {
|
| // Passing pointers to objects owned by |this| to
|
| // SchedulerWorkerPoolImpl::Create() is safe because a TaskSchedulerImpl
|
| // can't be deleted before all its worker pools have been joined.
|
| - worker_pools_.push_back(SchedulerWorkerPoolImpl::Create(
|
| - worker_pool_params, re_enqueue_sequence_callback, task_tracker_.get(),
|
| - delayed_task_manager_.get()));
|
| - CHECK(worker_pools_.back());
|
| + worker_pools_[index] = SchedulerWorkerPoolImpl::Create(
|
| + name_ + kEnvironmentParams[index].name_suffix,
|
| + kEnvironmentParams[index].priority_hint,
|
| + *reinterpret_cast<const SchedulerWorkerPoolParams*>(
|
| + reinterpret_cast<const char*>(&init_params) +
|
| + kEnvironmentParams[index].offset),
|
| + re_enqueue_sequence_callback, task_tracker_.get(),
|
| + delayed_task_manager_.get());
|
| + CHECK(worker_pools_[index]);
|
| }
|
| }
|
|
|
| SchedulerWorkerPoolImpl* TaskSchedulerImpl::GetWorkerPoolForTraits(
|
| const TaskTraits& traits) const {
|
| - const size_t index = worker_pool_index_for_traits_callback_.Run(traits);
|
| - DCHECK_LT(index, worker_pools_.size());
|
| - return worker_pools_[index].get();
|
| + return worker_pools_[GetEnvironmentIndexForTraits(traits)].get();
|
| }
|
|
|
| void TaskSchedulerImpl::ReEnqueueSequenceCallback(
|
|
|