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/task_scheduler/sequence_sort_key.h" | |
| 12 | |
| 13 namespace base { | |
| 14 namespace internal { | |
| 15 | |
| 16 TaskSchedulerImpl::TaskSchedulerImpl() | |
| 17 // TODO(robliao): Wake up the service thread instead of calling DoNothing() | |
| 18 // when the delayed run time changes. | |
| 19 : delayed_task_manager_(Bind(&DoNothing)) | |
| 20 #if DCHECK_IS_ON() | |
| 21 , | |
| 22 join_for_testing_returned_(true, false) | |
| 23 #endif | |
| 24 { | |
| 25 Initialize(); | |
| 26 } | |
| 27 | |
| 28 TaskSchedulerImpl::~TaskSchedulerImpl() { | |
| 29 #if DCHECK_IS_ON() | |
| 30 // This is surrounded by DCHECK_IS_ON() to avoid referencing | |
| 31 // |join_for_testing_returned_| in non-DCHECK builds. | |
| 32 DCHECK(join_for_testing_returned_.IsSignaled()); | |
|
gab
2016/04/28 19:29:02
DLOG_ASSERT?! :-)
fdoray
2016/04/28 21:02:24
Done.
| |
| 33 #endif | |
| 34 } | |
| 35 | |
| 36 scoped_refptr<TaskRunner> TaskSchedulerImpl::CreateTaskRunnerWithTraits( | |
| 37 const TaskTraits& traits, | |
| 38 ExecutionMode execution_mode) { | |
| 39 return GetThreadPoolForTraits(traits)->CreateTaskRunnerWithTraits( | |
| 40 traits, execution_mode); | |
| 41 } | |
| 42 | |
| 43 void TaskSchedulerImpl::Shutdown() { | |
| 44 // TODO(fdoray): Increase the priority of BACKGROUND tasks blocking shutdown. | |
| 45 task_tracker_.Shutdown(); | |
| 46 } | |
| 47 | |
| 48 void TaskSchedulerImpl::JoinForTesting() { | |
| 49 #if DCHECK_IS_ON() | |
| 50 DCHECK(!join_for_testing_returned_.IsSignaled()); | |
| 51 #endif | |
| 52 background_thread_pool_->JoinForTesting(); | |
| 53 background_file_io_thread_pool_->JoinForTesting(); | |
| 54 normal_thread_pool_->JoinForTesting(); | |
| 55 normal_file_io_thread_pool_->JoinForTesting(); | |
| 56 #if DCHECK_IS_ON() | |
| 57 join_for_testing_returned_.Signal(); | |
| 58 #endif | |
| 59 } | |
| 60 | |
| 61 void TaskSchedulerImpl::Initialize() { | |
| 62 using IORestriction = SchedulerThreadPoolImpl::IORestriction; | |
| 63 | |
| 64 const SchedulerThreadPoolImpl::ReEnqueueSequenceCallback | |
| 65 re_enqueue_sequence_callback = | |
| 66 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | |
| 67 | |
| 68 // TODO(fdoray): Derive the number of threads per pool from hardware | |
| 69 // characteristics rather than using hard-coded constants. | |
| 70 | |
| 71 // Passing pointers to objects owned by |this| to | |
| 72 // SchedulerThreadPoolImpl::Create() is safe because a TaskSchedulerImpl can't | |
| 73 // be deleted before all its thread pools have been joined. | |
| 74 background_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 75 ThreadPriority::BACKGROUND, 1U, IORestriction::IO_DISALLOWED, | |
| 76 re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); | |
| 77 CHECK(background_thread_pool_); | |
| 78 | |
| 79 background_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 80 ThreadPriority::BACKGROUND, 1U, IORestriction::IO_ALLOWED, | |
| 81 re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); | |
| 82 CHECK(background_file_io_thread_pool_); | |
| 83 | |
| 84 normal_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 85 ThreadPriority::NORMAL, 4U, IORestriction::IO_DISALLOWED, | |
| 86 re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); | |
| 87 CHECK(normal_thread_pool_); | |
| 88 | |
| 89 normal_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | |
| 90 ThreadPriority::NORMAL, 12U, IORestriction::IO_ALLOWED, | |
| 91 re_enqueue_sequence_callback, &task_tracker_, &delayed_task_manager_); | |
| 92 CHECK(normal_file_io_thread_pool_); | |
| 93 } | |
| 94 | |
| 95 SchedulerThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits( | |
| 96 const TaskTraits& traits) { | |
| 97 if (traits.with_file_io()) { | |
| 98 if (traits.priority() == TaskPriority::BACKGROUND) | |
| 99 return background_file_io_thread_pool_.get(); | |
| 100 return normal_file_io_thread_pool_.get(); | |
| 101 } | |
| 102 | |
| 103 if (traits.priority() == TaskPriority::BACKGROUND) | |
| 104 return background_thread_pool_.get(); | |
| 105 return normal_thread_pool_.get(); | |
| 106 } | |
| 107 | |
| 108 void TaskSchedulerImpl::ReEnqueueSequenceCallback( | |
| 109 scoped_refptr<Sequence> sequence) { | |
| 110 DCHECK(sequence); | |
| 111 | |
| 112 const SequenceSortKey sort_key = sequence->GetSortKey(); | |
| 113 TaskTraits traits(sequence->PeekTask()->traits); | |
| 114 | |
| 115 // Update the priority of |traits| so that the next task in |sequence| runs | |
| 116 // with the highest priority in |sequence|. | |
|
gab
2016/04/28 19:29:02
s/./as opposed to the next task's specific priorit
fdoray
2016/04/28 21:02:24
Done.
| |
| 117 traits.WithPriority(sort_key.priority); | |
| 118 | |
| 119 GetThreadPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | |
| 120 sort_key); | |
| 121 } | |
| 122 | |
| 123 } // namespace internal | |
| 124 } // namespace base | |
| OLD | NEW |