OLD | NEW |
---|---|
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 <algorithm> | |
7 #include <utility> | 8 #include <utility> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/logging.h" | |
11 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "base/sys_info.h" | |
12 #include "base/task_scheduler/scheduler_service_thread.h" | 16 #include "base/task_scheduler/scheduler_service_thread.h" |
13 #include "base/task_scheduler/scheduler_thread_pool_impl.h" | 17 #include "base/task_scheduler/scheduler_thread_pool_impl.h" |
14 #include "base/task_scheduler/sequence_sort_key.h" | 18 #include "base/task_scheduler/sequence_sort_key.h" |
15 #include "base/task_scheduler/task.h" | 19 #include "base/task_scheduler/task.h" |
16 #include "base/time/time.h" | 20 #include "base/time/time.h" |
17 | 21 |
18 namespace base { | 22 namespace base { |
19 namespace internal { | 23 namespace internal { |
20 | 24 |
25 namespace { | |
26 | |
27 constexpr char kTaskSchedulerThreadNamePrefix[] = "TaskScheduler"; | |
28 | |
29 struct ThreadPoolSettings { | |
30 // Name of the pool. Used to name threads and to find variation params that | |
31 // apply to this pool. | |
32 const char* name; | |
33 | |
34 // Default values used to compute the maximum number of threads in the pool | |
35 // (used when not specified by variation params). | |
36 int default_min_threads; | |
robliao
2016/06/14 21:43:44
uint32_t might be more appropriate.
fdoray
2016/06/15 17:14:32
Does this rule apply here?
"You should not use the
robliao
2016/06/15 17:32:37
Hrm... interesting. I guess we'll stick with that
| |
37 int default_max_threads; | |
38 int default_threads_percentage_num_processors; | |
39 }; | |
40 | |
41 constexpr ThreadPoolSettings kBackgroundPoolSettings{"Background", 1, 1, 0}; | |
robliao
2016/06/14 21:43:44
This shouldn't trigger a static init, right?
fdoray
2016/06/15 17:14:32
No (constexpr + POD)
| |
42 constexpr ThreadPoolSettings kBackgroundFileIOPoolSettings{"BackgroundFileIO", | |
43 3, 3, 0}; | |
44 constexpr ThreadPoolSettings kForegroundPoolSettings{"Foreground", 4, 16, 100}; | |
45 constexpr ThreadPoolSettings kForegroundFileIOPoolSettings{"ForegroundFileIO", | |
46 8, 32, 200}; | |
47 | |
48 // Returns the integer associated with |key| in |map| or |default_value| there | |
49 // is no such integer. | |
50 int ReadIntegerFromMap(const std::string& key, | |
51 int default_value, | |
52 const std::map<std::string, std::string>& map) { | |
robliao
2016/06/14 21:43:44
Consider having the map argument first. This would
fdoray
2016/06/15 17:14:32
Done.
| |
53 auto it = map.find(key); | |
54 int value = 0; | |
55 if (it == map.end() || !StringToInt(it->second, &value)) | |
56 return default_value; | |
57 return value; | |
58 } | |
59 | |
60 int GetMaxThreadsForPool( | |
61 const ThreadPoolSettings& settings, | |
62 const std::map<std::string, std::string>& variation_params) { | |
63 DCHECK_GT(settings.default_min_threads, 0); | |
64 const std::string pool_name(settings.name); | |
65 const int min_threads = ReadIntegerFromMap( | |
66 pool_name + "MinThreads", settings.default_min_threads, variation_params); | |
67 DCHECK_GT(min_threads, 0); | |
68 const int max_threads = ReadIntegerFromMap( | |
69 pool_name + "MaxThreads", settings.default_max_threads, variation_params); | |
70 const int threads_percentage_num_processors = ReadIntegerFromMap( | |
71 pool_name + "ThreadsPercentageNumProcessors", | |
72 settings.default_threads_percentage_num_processors, variation_params); | |
73 | |
74 return std::max( | |
75 min_threads, | |
76 std::min(max_threads, threads_percentage_num_processors * | |
77 SysInfo::NumberOfProcessors() / 100)); | |
78 } | |
79 | |
80 } // namespace | |
81 | |
21 // static | 82 // static |
22 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create() { | 83 std::unique_ptr<TaskSchedulerImpl> TaskSchedulerImpl::Create( |
84 const std::map<std::string, std::string>& variation_params) { | |
23 std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl); | 85 std::unique_ptr<TaskSchedulerImpl> scheduler(new TaskSchedulerImpl); |
24 scheduler->Initialize(); | 86 scheduler->Initialize(variation_params); |
25 return scheduler; | 87 return scheduler; |
26 } | 88 } |
27 | 89 |
28 TaskSchedulerImpl::~TaskSchedulerImpl() { | 90 TaskSchedulerImpl::~TaskSchedulerImpl() { |
29 #if DCHECK_IS_ON() | 91 #if DCHECK_IS_ON() |
30 DCHECK(join_for_testing_returned_.IsSignaled()); | 92 DCHECK(join_for_testing_returned_.IsSignaled()); |
31 #endif | 93 #endif |
32 } | 94 } |
33 | 95 |
34 void TaskSchedulerImpl::PostTaskWithTraits( | 96 void TaskSchedulerImpl::PostTaskWithTraits( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 : delayed_task_manager_( | 133 : delayed_task_manager_( |
72 Bind(&TaskSchedulerImpl::OnDelayedRunTimeUpdated, Unretained(this))) | 134 Bind(&TaskSchedulerImpl::OnDelayedRunTimeUpdated, Unretained(this))) |
73 #if DCHECK_IS_ON() | 135 #if DCHECK_IS_ON() |
74 , | 136 , |
75 join_for_testing_returned_(WaitableEvent::ResetPolicy::MANUAL, | 137 join_for_testing_returned_(WaitableEvent::ResetPolicy::MANUAL, |
76 WaitableEvent::InitialState::NOT_SIGNALED) | 138 WaitableEvent::InitialState::NOT_SIGNALED) |
77 #endif | 139 #endif |
78 { | 140 { |
79 } | 141 } |
80 | 142 |
81 void TaskSchedulerImpl::Initialize() { | 143 void TaskSchedulerImpl::Initialize( |
144 const std::map<std::string, std::string>& variation_params) { | |
82 using IORestriction = SchedulerThreadPoolImpl::IORestriction; | 145 using IORestriction = SchedulerThreadPoolImpl::IORestriction; |
83 | 146 |
147 const std::string thread_name_prefix(kTaskSchedulerThreadNamePrefix); | |
148 | |
84 const SchedulerThreadPoolImpl::ReEnqueueSequenceCallback | 149 const SchedulerThreadPoolImpl::ReEnqueueSequenceCallback |
85 re_enqueue_sequence_callback = | 150 re_enqueue_sequence_callback = |
86 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); | 151 Bind(&TaskSchedulerImpl::ReEnqueueSequenceCallback, Unretained(this)); |
87 | 152 |
88 // TODO(fdoray): Derive the number of threads per pool from hardware | |
89 // characteristics rather than using hard-coded constants. | |
90 | |
91 // Passing pointers to objects owned by |this| to | 153 // Passing pointers to objects owned by |this| to |
92 // SchedulerThreadPoolImpl::Create() is safe because a TaskSchedulerImpl can't | 154 // SchedulerThreadPoolImpl::Create() is safe because a TaskSchedulerImpl can't |
93 // be deleted before all its thread pools have been joined. | 155 // be deleted before all its thread pools have been joined. |
94 background_thread_pool_ = SchedulerThreadPoolImpl::Create( | 156 background_thread_pool_ = SchedulerThreadPoolImpl::Create( |
95 "TaskSchedulerBackground", ThreadPriority::BACKGROUND, 1U, | 157 thread_name_prefix + kBackgroundPoolSettings.name, |
158 ThreadPriority::BACKGROUND, | |
159 GetMaxThreadsForPool(kBackgroundPoolSettings, variation_params), | |
96 IORestriction::DISALLOWED, re_enqueue_sequence_callback, &task_tracker_, | 160 IORestriction::DISALLOWED, re_enqueue_sequence_callback, &task_tracker_, |
97 &delayed_task_manager_); | 161 &delayed_task_manager_); |
98 CHECK(background_thread_pool_); | 162 CHECK(background_thread_pool_); |
99 | 163 |
100 background_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | 164 background_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( |
101 "TaskSchedulerBackgroundFileIO", ThreadPriority::BACKGROUND, 1U, | 165 thread_name_prefix + kBackgroundFileIOPoolSettings.name, |
166 ThreadPriority::BACKGROUND, | |
167 GetMaxThreadsForPool(kBackgroundFileIOPoolSettings, variation_params), | |
102 IORestriction::ALLOWED, re_enqueue_sequence_callback, &task_tracker_, | 168 IORestriction::ALLOWED, re_enqueue_sequence_callback, &task_tracker_, |
103 &delayed_task_manager_); | 169 &delayed_task_manager_); |
104 CHECK(background_file_io_thread_pool_); | 170 CHECK(background_file_io_thread_pool_); |
105 | 171 |
106 normal_thread_pool_ = SchedulerThreadPoolImpl::Create( | 172 normal_thread_pool_ = SchedulerThreadPoolImpl::Create( |
107 "TaskSchedulerForeground", ThreadPriority::NORMAL, 4U, | 173 thread_name_prefix + kForegroundPoolSettings.name, ThreadPriority::NORMAL, |
174 GetMaxThreadsForPool(kForegroundPoolSettings, variation_params), | |
108 IORestriction::DISALLOWED, re_enqueue_sequence_callback, &task_tracker_, | 175 IORestriction::DISALLOWED, re_enqueue_sequence_callback, &task_tracker_, |
109 &delayed_task_manager_); | 176 &delayed_task_manager_); |
110 CHECK(normal_thread_pool_); | 177 CHECK(normal_thread_pool_); |
111 | 178 |
112 normal_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( | 179 normal_file_io_thread_pool_ = SchedulerThreadPoolImpl::Create( |
113 "TaskSchedulerForegroundFileIO", ThreadPriority::NORMAL, 12U, | 180 thread_name_prefix + kForegroundFileIOPoolSettings.name, |
181 ThreadPriority::NORMAL, | |
182 GetMaxThreadsForPool(kForegroundFileIOPoolSettings, variation_params), | |
114 IORestriction::ALLOWED, re_enqueue_sequence_callback, &task_tracker_, | 183 IORestriction::ALLOWED, re_enqueue_sequence_callback, &task_tracker_, |
115 &delayed_task_manager_); | 184 &delayed_task_manager_); |
116 CHECK(normal_file_io_thread_pool_); | 185 CHECK(normal_file_io_thread_pool_); |
117 | 186 |
118 service_thread_ = SchedulerServiceThread::Create(&task_tracker_, | 187 service_thread_ = SchedulerServiceThread::Create(&task_tracker_, |
119 &delayed_task_manager_); | 188 &delayed_task_manager_); |
120 CHECK(service_thread_); | 189 CHECK(service_thread_); |
121 } | 190 } |
122 | 191 |
123 SchedulerThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits( | 192 SchedulerThreadPool* TaskSchedulerImpl::GetThreadPoolForTraits( |
(...skipping 24 matching lines...) Expand all Loading... | |
148 GetThreadPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), | 217 GetThreadPoolForTraits(traits)->ReEnqueueSequence(std::move(sequence), |
149 sort_key); | 218 sort_key); |
150 } | 219 } |
151 | 220 |
152 void TaskSchedulerImpl::OnDelayedRunTimeUpdated() { | 221 void TaskSchedulerImpl::OnDelayedRunTimeUpdated() { |
153 service_thread_->WakeUp(); | 222 service_thread_->WakeUp(); |
154 } | 223 } |
155 | 224 |
156 } // namespace internal | 225 } // namespace internal |
157 } // namespace base | 226 } // namespace base |
OLD | NEW |