OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ | 5 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ |
6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ | 6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
67 // Requests that a task to process work is posted on the main task runner. | 67 // Requests that a task to process work is posted on the main task runner. |
68 // These tasks are de-duplicated in two buckets: main-thread and all other | 68 // These tasks are de-duplicated in two buckets: main-thread and all other |
69 // threads. This distinction is done to reduce the overehead from locks, we | 69 // threads. This distinction is done to reduce the overehead from locks, we |
70 // assume the main-thread path will be hot. | 70 // assume the main-thread path will be hot. |
71 void MaybeScheduleImmediateWork(const tracked_objects::Location& from_here); | 71 void MaybeScheduleImmediateWork(const tracked_objects::Location& from_here); |
72 | 72 |
73 // Requests that a delayed task to process work is posted on the main task | 73 // Requests that a delayed task to process work is posted on the main task |
74 // runner. These delayed tasks are de-duplicated. Must be called on the thread | 74 // runner. These delayed tasks are de-duplicated. Must be called on the thread |
75 // this class was created on. | 75 // this class was created on. |
76 void MaybeScheduleDelayedWork(const tracked_objects::Location& from_here, | 76 void MaybeScheduleDelayedWork(const tracked_objects::Location& from_here, |
77 base::TimeTicks now, | 77 TimeDomain* requesting_time_domain, |
78 base::TimeDelta delay); | 78 LazyNow* lazy_now, |
79 base::TimeTicks run_time); | |
80 | |
81 // Cancels a delayed task to process work at |run_time|, previously requested | |
82 // with MaybeScheduleDelayedWork. | |
83 void CancelDelayedWork(TimeDomain* requesting_time_domain, | |
84 base::TimeTicks run_time); | |
79 | 85 |
80 // Set the number of tasks executed in a single invocation of the task queue | 86 // Set the number of tasks executed in a single invocation of the task queue |
81 // manager. Increasing the batch size can reduce the overhead of yielding | 87 // manager. Increasing the batch size can reduce the overhead of yielding |
82 // back to the main message loop -- at the cost of potentially delaying other | 88 // back to the main message loop -- at the cost of potentially delaying other |
83 // tasks posted to the main loop. The batch size is 1 by default. | 89 // tasks posted to the main loop. The batch size is 1 by default. |
84 void SetWorkBatchSize(int work_batch_size); | 90 void SetWorkBatchSize(int work_batch_size); |
85 | 91 |
86 // These functions can only be called on the same thread that the task queue | 92 // These functions can only be called on the same thread that the task queue |
87 // manager executes its tasks on. | 93 // manager executes its tasks on. |
88 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); | 94 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 // Returns true if there is a task that could be executed immediately. | 148 // Returns true if there is a task that could be executed immediately. |
143 bool HasImmediateWorkForTesting() const; | 149 bool HasImmediateWorkForTesting() const; |
144 | 150 |
145 // Removes all canceled delayed tasks. | 151 // Removes all canceled delayed tasks. |
146 void SweepCanceledDelayedTasks(); | 152 void SweepCanceledDelayedTasks(); |
147 | 153 |
148 // There is a small overhead to recording task delay histograms. If you don't | 154 // There is a small overhead to recording task delay histograms. If you don't |
149 // need them, you can turn them off. | 155 // need them, you can turn them off. |
150 void SetRecordTaskDelayHistograms(bool record_task_delay_histograms); | 156 void SetRecordTaskDelayHistograms(bool record_task_delay_histograms); |
151 | 157 |
158 // Intermediate data structure, used to compute NextDelayedDoWork. | |
159 // Only public for testing. | |
160 class NextTaskDelay { | |
Sami
2017/02/01 07:30:05
TaskQueueManagerTest is a friend -- could these tw
alex clarke (OOO till 29th)
2017/02/01 14:50:11
I found a way for NextDelayedDoWork to be private
| |
161 public: | |
162 NextTaskDelay() : time_domain_(nullptr) {} | |
163 | |
164 NextTaskDelay(base::TimeDelta delay, TimeDomain* time_domain) | |
165 : delay_(delay), time_domain_(time_domain) { | |
166 DCHECK_GT(delay, base::TimeDelta()); | |
167 DCHECK(time_domain); | |
168 } | |
169 | |
170 base::TimeDelta delay() const { return delay_; } | |
171 TimeDomain* time_domain() const { return time_domain_; } | |
172 | |
173 bool operator<(const NextTaskDelay& other) const { | |
174 return delay_ < other.delay_; | |
175 } | |
176 | |
177 private: | |
178 base::TimeDelta delay_; | |
179 TimeDomain* time_domain_; | |
180 }; | |
181 | |
182 // Represents a scheduled delayed DoWork (if any). Only public for testing. | |
183 class NextDelayedDoWork { | |
184 public: | |
185 NextDelayedDoWork() : time_domain_(nullptr) {} | |
186 NextDelayedDoWork(base::TimeTicks run_time, TimeDomain* time_domain) | |
187 : run_time_(run_time), time_domain_(time_domain) { | |
188 DCHECK_NE(run_time, base::TimeTicks()); | |
189 DCHECK(time_domain); | |
190 } | |
191 | |
192 base::TimeTicks run_time() const { return run_time_; } | |
193 TimeDomain* time_domain() const { return time_domain_; } | |
194 | |
195 void Clear() { | |
196 run_time_ = base::TimeTicks(); | |
197 time_domain_ = nullptr; | |
198 } | |
199 | |
200 explicit operator bool() const { return !run_time_.is_null(); } | |
201 | |
202 private: | |
203 base::TimeTicks run_time_; | |
204 TimeDomain* time_domain_; | |
205 }; | |
206 | |
152 private: | 207 private: |
153 friend class LazyNow; | 208 friend class LazyNow; |
154 friend class internal::TaskQueueImpl; | 209 friend class internal::TaskQueueImpl; |
155 friend class TaskQueueManagerTest; | 210 friend class TaskQueueManagerTest; |
156 | 211 |
157 class DeletionSentinel : public base::RefCounted<DeletionSentinel> { | 212 class DeletionSentinel : public base::RefCounted<DeletionSentinel> { |
158 private: | 213 private: |
159 friend class base::RefCounted<DeletionSentinel>; | 214 friend class base::RefCounted<DeletionSentinel>; |
160 ~DeletionSentinel() {} | 215 ~DeletionSentinel() {} |
161 }; | 216 }; |
162 | 217 |
163 // Unregisters a TaskQueue previously created by |NewTaskQueue()|. | 218 // Unregisters a TaskQueue previously created by |NewTaskQueue()|. |
164 void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue); | 219 void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue); |
165 | 220 |
166 // TaskQueueSelector::Observer implementation: | 221 // TaskQueueSelector::Observer implementation: |
167 void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; | 222 void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; |
168 void OnTriedToSelectBlockedWorkQueue( | 223 void OnTriedToSelectBlockedWorkQueue( |
169 internal::WorkQueue* work_queue) override; | 224 internal::WorkQueue* work_queue) override; |
170 | 225 |
171 // base::MessageLoop::NestingObserver implementation: | 226 // base::MessageLoop::NestingObserver implementation: |
172 void OnBeginNestedMessageLoop() override; | 227 void OnBeginNestedMessageLoop() override; |
173 | 228 |
174 // Called by the task queue to register a new pending task. | 229 // Called by the task queue to register a new pending task. |
175 void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); | 230 void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); |
176 | 231 |
177 // Use the selector to choose a pending task and run it. | 232 // Use the selector to choose a pending task and run it. |
178 void DoWork(bool delayed); | 233 void DoWork(bool delayed); |
179 | 234 |
180 // Post a DoWork continuation if |next_delay| is not empty. | 235 // Post a DoWork continuation if |next_delay| is not empty. |
181 void PostDoWorkContinuationLocked(base::Optional<base::TimeDelta> next_delay, | 236 void PostDoWorkContinuationLocked(base::Optional<NextTaskDelay> next_delay, |
182 LazyNow* lazy_now, | 237 LazyNow* lazy_now, |
183 MoveableAutoLock&& lock); | 238 MoveableAutoLock&& lock); |
184 | 239 |
185 // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and | 240 // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and |
186 // reloads any empty work queues. | 241 // reloads any empty work queues. |
187 void WakeupReadyDelayedQueues(LazyNow* lazy_now); | 242 void WakeupReadyDelayedQueues(LazyNow* lazy_now); |
188 | 243 |
189 // Chooses the next work queue to service. Returns true if |out_queue| | 244 // Chooses the next work queue to service. Returns true if |out_queue| |
190 // indicates the queue from which the next task should be run, false to | 245 // indicates the queue from which the next task should be run, false to |
191 // avoid running any tasks. | 246 // avoid running any tasks. |
(...skipping 17 matching lines...) Expand all Loading... | |
209 | 264 |
210 bool RunsTasksOnCurrentThread() const; | 265 bool RunsTasksOnCurrentThread() const; |
211 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 266 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
212 const base::Closure& task, | 267 const base::Closure& task, |
213 base::TimeDelta delay); | 268 base::TimeDelta delay); |
214 | 269 |
215 internal::EnqueueOrder GetNextSequenceNumber(); | 270 internal::EnqueueOrder GetNextSequenceNumber(); |
216 | 271 |
217 // Calls DelayTillNextTask on all time domains and returns the smallest delay | 272 // Calls DelayTillNextTask on all time domains and returns the smallest delay |
218 // requested if any. | 273 // requested if any. |
219 base::Optional<base::TimeDelta> ComputeDelayTillNextTaskLocked( | 274 base::Optional<NextTaskDelay> ComputeDelayTillNextTaskLocked( |
220 LazyNow* lazy_now); | 275 LazyNow* lazy_now); |
221 | 276 |
222 void MaybeRecordTaskDelayHistograms( | 277 void MaybeRecordTaskDelayHistograms( |
223 const internal::TaskQueueImpl::Task& pending_task, | 278 const internal::TaskQueueImpl::Task& pending_task, |
224 const internal::TaskQueueImpl* queue); | 279 const internal::TaskQueueImpl* queue); |
225 | 280 |
226 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 281 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
227 AsValueWithSelectorResult(bool should_run, | 282 AsValueWithSelectorResult(bool should_run, |
228 internal::WorkQueue* selected_work_queue) const; | 283 internal::WorkQueue* selected_work_queue) const; |
229 | 284 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 | 341 |
287 struct AnyThread& any_thread() { | 342 struct AnyThread& any_thread() { |
288 any_thread_lock_.AssertAcquired(); | 343 any_thread_lock_.AssertAcquired(); |
289 return any_thread_; | 344 return any_thread_; |
290 } | 345 } |
291 const struct AnyThread& any_thread() const { | 346 const struct AnyThread& any_thread() const { |
292 any_thread_lock_.AssertAcquired(); | 347 any_thread_lock_.AssertAcquired(); |
293 return any_thread_; | 348 return any_thread_; |
294 } | 349 } |
295 | 350 |
296 base::TimeTicks next_scheduled_delayed_do_work_time_; | 351 NextDelayedDoWork next_delayed_do_work_; |
297 | 352 |
298 bool record_task_delay_histograms_; | 353 bool record_task_delay_histograms_; |
299 | 354 |
300 int work_batch_size_; | 355 int work_batch_size_; |
301 size_t task_count_; | 356 size_t task_count_; |
302 | 357 |
303 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_; | 358 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_; |
304 | 359 |
305 base::ObserverList<TaskTimeObserver> task_time_observers_; | 360 base::ObserverList<TaskTimeObserver> task_time_observers_; |
306 | 361 |
307 const char* tracing_category_; | 362 const char* tracing_category_; |
308 const char* disabled_by_default_tracing_category_; | 363 const char* disabled_by_default_tracing_category_; |
309 const char* disabled_by_default_verbose_tracing_category_; | 364 const char* disabled_by_default_verbose_tracing_category_; |
310 | 365 |
311 internal::TaskQueueImpl* currently_executing_task_queue_; // NOT OWNED | 366 internal::TaskQueueImpl* currently_executing_task_queue_; // NOT OWNED |
312 | 367 |
313 Observer* observer_; // NOT OWNED | 368 Observer* observer_; // NOT OWNED |
314 scoped_refptr<DeletionSentinel> deletion_sentinel_; | 369 scoped_refptr<DeletionSentinel> deletion_sentinel_; |
315 base::WeakPtrFactory<TaskQueueManager> weak_factory_; | 370 base::WeakPtrFactory<TaskQueueManager> weak_factory_; |
316 | 371 |
317 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager); | 372 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager); |
318 }; | 373 }; |
319 | 374 |
320 } // namespace scheduler | 375 } // namespace scheduler |
321 } // namespace blink | 376 } // namespace blink |
322 | 377 |
323 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_ H_ | 378 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_ H_ |
OLD | NEW |