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 |