Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/task_scheduler/task_scheduler_impl.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/task_scheduler/sequence_sort_key.h" | |
| 13 | |
| 14 namespace base { | |
| 15 namespace internal { | |
| 16 | |
| 17 TaskSchedulerImpl::~TaskSchedulerImpl() { | |
| 18 DCHECK(join_for_testing_returned_.IsSignaled()); | |
| 19 } | |
| 20 | |
| 21 // static | |
| 22 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create() { | |
|
gab
2016/04/27 19:15:28
In SchedulerThreadPool we had a static Create() wi
fdoray
2016/04/28 18:36:32
Done.
robliao
2016/04/29 18:34:21
While this class doesn't support creation failure,
fdoray
2016/04/29 19:42:42
If TaskSchedulerImpl::Create successfully creates
gab
2016/04/29 20:33:18
Agreed, and I think the "doing work in the constru
| |
| 23 std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl); | |
| 24 scheduler->Initialize(); | |
| 25 return scheduler; | |
| 26 } | |
| 27 | |
| 28 scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits( | |
| 29 const TaskTraits& traits, | |
| 30 ExecutionMode execution_mode) { | |
| 31 return GetThreadPoolForTraits(traits)->CreateTaskRunnerWithTraits( | |
| 32 traits, execution_mode); | |
| 33 } | |
| 34 | |
| 35 void TaskSchedulerImpl::Shutdown() { | |
| 36 // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown. | |
| 37 task_tracker_.Shutdown(); | |
| 38 } | |
| 39 | |
| 40 void TaskSchedulerImpl::JoinForTesting() { | |
| 41 DCHECK(!join_for_testing_returned_.IsSignaled()); | |
| 42 background_thread_pool_->JoinForTesting(); | |
| 43 background_file_io_thread_pool_->JoinForTesting(); | |
| 44 normal_thread_pool_->JoinForTesting(); | |
| 45 normal_file_io_thread_pool_->JoinForTesting(); | |
| 46 join_for_testing_returned_.Signal(); | |
| 47 } | |
| 48 | |
| 49 TaskSchedulerImpl::TaskSchedulerImpl() | |
| 50 // TODO(robliao): Wake up the service thread instead of calling DoNothing() | |
| 51 // when the delayed run time changes. | |
| 52 : delayed_task_manager_(Bind(&DoNothing)), | |
| 53 join_for_testing_returned_(true, false) {} | |
| 54 | |
| 55 void TaskSchedulerImpl::Initialize() { | |
| 56 const SchedulerThreadPoolImpl::ReEnqueueSequenceCallback | |
| 57 re_enqueue_sequence_callback = | |
| 58 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | |
| 59 | |
| 60 // TODO(fdoray): Derive the number of threads per pool from hardware | |
| 61 // characteristics rather than using hard-coded constants. | |
| 62 | |
| 63 // Passing pointers to objects owned by |this| to | |
| 64 // SchedulerThreadPoolImpl::Create() is safe because a TaskSchedulerImpl can't | |
| 65 // be deleted before all its thread pools have been joined. | |
| 66 background_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 67 ThreadPriority::BACKGROUND, 1U, re_enqueue_sequence_callback, | |
| 68 &task_tracker_, &delayed_task_manager_); | |
| 69 CHECK(background_thread_pool_); | |
| 70 | |
| 71 background_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 72 ThreadPriority::BACKGROUND, 1U, re_enqueue_sequence_callback, | |
| 73 &task_tracker_, &delayed_task_manager_); | |
| 74 CHECK(background_file_io_thread_pool_); | |
| 75 | |
| 76 normal_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 77 ThreadPriority::NORMAL, 4U, re_enqueue_sequence_callback, &task_tracker_, | |
| 78 &delayed_task_manager_); | |
| 79 CHECK(normal_thread_pool_); | |
| 80 | |
| 81 normal_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 82 ThreadPriority::NORMAL, 12U, re_enqueue_sequence_callback, &task_tracker_, | |
| 83 &delayed_task_manager_); | |
| 84 CHECK(normal_file_io_thread_pool_); | |
| 85 } | |
| 86 | |
| 87 SchedulerThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits( | |
| 88 const TaskTraits& traits) { | |
| 89 if (traits.with_file_io()) { | |
| 90 if (traits.priority() == TaskPriority::BACKGROUND) | |
| 91 return background_file_io_thread_pool_.get(); | |
| 92 return normal_file_io_thread_pool_.get(); | |
| 93 } | |
| 94 | |
| 95 if (traits.priority() == TaskPriority::BACKGROUND) | |
| 96 return background_thread_pool_.get(); | |
| 97 return normal_thread_pool_.get(); | |
| 98 } | |
| 99 | |
| 100 void TaskSchedulerImpl::ReEnqueueSequenceCallback( | |
| 101 scoped_refptr<Sequence> sequence) { | |
| 102 DCHECK(sequence); | |
| 103 | |
| 104 const SequenceSortKey sort_key = sequence->GetSortKey(); | |
| 105 const Task* next_task_in_sequence = sequence->PeekTask(); | |
| 106 DCHECK(next_task_in_sequence); | |
| 107 | |
| 108 TaskTraits traits = TaskTraits().WithPriority(sort_key.priority); | |
| 109 if (next_task_in_sequence->traits.with_file_io()) | |
| 110 traits = traits.WithFileIO(); | |
| 111 | |
| 112 GetThreadPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | |
|
gab
2016/04/27 19:15:28
Why not use |next_task_in_sequence->traits| instea
fdoray
2016/04/28 18:36:32
Added comment to explain why I do this.
| |
| 113 sort_key); | |
| 114 } | |
| 115 | |
| 116 } // namespace internal | |
| 117 } // namespace base | |
| OLD | NEW |