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 TimeDomain* requesting_time_domain, |
77 base::TimeTicks now, | 78 base::TimeTicks now, |
78 base::TimeDelta delay); | 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 |
152 private: | 158 protected: |
153 friend class LazyNow; | 159 friend class LazyNow; |
154 friend class internal::TaskQueueImpl; | 160 friend class internal::TaskQueueImpl; |
155 friend class TaskQueueManagerTest; | 161 friend class TaskQueueManagerTest; |
156 | 162 |
| 163 // Intermediate data structure, used to compute NextDelayedDoWork. |
| 164 class NextTaskDelay { |
| 165 public: |
| 166 NextTaskDelay() : time_domain_(nullptr) {} |
| 167 |
| 168 using AllowAnyDelayForTesting = int; |
| 169 |
| 170 NextTaskDelay(base::TimeDelta delay, TimeDomain* time_domain) |
| 171 : delay_(delay), time_domain_(time_domain) { |
| 172 DCHECK_GT(delay, base::TimeDelta()); |
| 173 DCHECK(time_domain); |
| 174 } |
| 175 |
| 176 NextTaskDelay(base::TimeDelta delay, |
| 177 TimeDomain* time_domain, |
| 178 AllowAnyDelayForTesting) |
| 179 : delay_(delay), time_domain_(time_domain) { |
| 180 DCHECK(time_domain); |
| 181 } |
| 182 |
| 183 base::TimeDelta delay() const { return delay_; } |
| 184 TimeDomain* time_domain() const { return time_domain_; } |
| 185 |
| 186 bool operator>(const NextTaskDelay& other) const { |
| 187 return delay_ > other.delay_; |
| 188 } |
| 189 |
| 190 bool operator<(const NextTaskDelay& other) const { |
| 191 return delay_ < other.delay_; |
| 192 } |
| 193 |
| 194 private: |
| 195 base::TimeDelta delay_; |
| 196 TimeDomain* time_domain_; |
| 197 }; |
| 198 |
| 199 private: |
| 200 // Represents a scheduled delayed DoWork (if any). Only public for testing. |
| 201 class NextDelayedDoWork { |
| 202 public: |
| 203 NextDelayedDoWork() : time_domain_(nullptr) {} |
| 204 NextDelayedDoWork(base::TimeTicks run_time, TimeDomain* time_domain) |
| 205 : run_time_(run_time), time_domain_(time_domain) { |
| 206 DCHECK_NE(run_time, base::TimeTicks()); |
| 207 DCHECK(time_domain); |
| 208 } |
| 209 |
| 210 base::TimeTicks run_time() const { return run_time_; } |
| 211 TimeDomain* time_domain() const { return time_domain_; } |
| 212 |
| 213 void Clear() { |
| 214 run_time_ = base::TimeTicks(); |
| 215 time_domain_ = nullptr; |
| 216 } |
| 217 |
| 218 explicit operator bool() const { return !run_time_.is_null(); } |
| 219 |
| 220 private: |
| 221 base::TimeTicks run_time_; |
| 222 TimeDomain* time_domain_; |
| 223 }; |
| 224 |
157 class DeletionSentinel : public base::RefCounted<DeletionSentinel> { | 225 class DeletionSentinel : public base::RefCounted<DeletionSentinel> { |
158 private: | 226 private: |
159 friend class base::RefCounted<DeletionSentinel>; | 227 friend class base::RefCounted<DeletionSentinel>; |
160 ~DeletionSentinel() {} | 228 ~DeletionSentinel() {} |
161 }; | 229 }; |
162 | 230 |
163 // Unregisters a TaskQueue previously created by |NewTaskQueue()|. | 231 // Unregisters a TaskQueue previously created by |NewTaskQueue()|. |
164 void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue); | 232 void UnregisterTaskQueue(scoped_refptr<internal::TaskQueueImpl> task_queue); |
165 | 233 |
166 // TaskQueueSelector::Observer implementation: | 234 // TaskQueueSelector::Observer implementation: |
167 void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; | 235 void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; |
168 void OnTriedToSelectBlockedWorkQueue( | 236 void OnTriedToSelectBlockedWorkQueue( |
169 internal::WorkQueue* work_queue) override; | 237 internal::WorkQueue* work_queue) override; |
170 | 238 |
171 // base::MessageLoop::NestingObserver implementation: | 239 // base::MessageLoop::NestingObserver implementation: |
172 void OnBeginNestedMessageLoop() override; | 240 void OnBeginNestedMessageLoop() override; |
173 | 241 |
174 // Called by the task queue to register a new pending task. | 242 // Called by the task queue to register a new pending task. |
175 void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); | 243 void DidQueueTask(const internal::TaskQueueImpl::Task& pending_task); |
176 | 244 |
177 // Use the selector to choose a pending task and run it. | 245 // Use the selector to choose a pending task and run it. |
178 void DoWork(bool delayed); | 246 void DoWork(bool delayed); |
179 | 247 |
180 // Post a DoWork continuation if |next_delay| is not empty. | 248 // Post a DoWork continuation if |next_delay| is not empty. |
181 void PostDoWorkContinuationLocked(base::Optional<base::TimeDelta> next_delay, | 249 void PostDoWorkContinuationLocked(base::Optional<NextTaskDelay> next_delay, |
182 LazyNow* lazy_now, | 250 LazyNow* lazy_now, |
183 MoveableAutoLock&& lock); | 251 MoveableAutoLock&& lock); |
184 | 252 |
185 // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and | 253 // Delayed Tasks with run_times <= Now() are enqueued onto the work queue and |
186 // reloads any empty work queues. | 254 // reloads any empty work queues. |
187 void WakeupReadyDelayedQueues(LazyNow* lazy_now); | 255 void WakeupReadyDelayedQueues(LazyNow* lazy_now); |
188 | 256 |
189 // Chooses the next work queue to service. Returns true if |out_queue| | 257 // 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 | 258 // indicates the queue from which the next task should be run, false to |
191 // avoid running any tasks. | 259 // avoid running any tasks. |
(...skipping 17 matching lines...) Expand all Loading... |
209 | 277 |
210 bool RunsTasksOnCurrentThread() const; | 278 bool RunsTasksOnCurrentThread() const; |
211 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 279 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
212 const base::Closure& task, | 280 const base::Closure& task, |
213 base::TimeDelta delay); | 281 base::TimeDelta delay); |
214 | 282 |
215 internal::EnqueueOrder GetNextSequenceNumber(); | 283 internal::EnqueueOrder GetNextSequenceNumber(); |
216 | 284 |
217 // Calls DelayTillNextTask on all time domains and returns the smallest delay | 285 // Calls DelayTillNextTask on all time domains and returns the smallest delay |
218 // requested if any. | 286 // requested if any. |
219 base::Optional<base::TimeDelta> ComputeDelayTillNextTaskLocked( | 287 base::Optional<NextTaskDelay> ComputeDelayTillNextTaskLocked( |
220 LazyNow* lazy_now); | 288 LazyNow* lazy_now); |
221 | 289 |
222 void MaybeRecordTaskDelayHistograms( | 290 void MaybeRecordTaskDelayHistograms( |
223 const internal::TaskQueueImpl::Task& pending_task, | 291 const internal::TaskQueueImpl::Task& pending_task, |
224 const internal::TaskQueueImpl* queue); | 292 const internal::TaskQueueImpl* queue); |
225 | 293 |
226 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> | 294 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> |
227 AsValueWithSelectorResult(bool should_run, | 295 AsValueWithSelectorResult(bool should_run, |
228 internal::WorkQueue* selected_work_queue) const; | 296 internal::WorkQueue* selected_work_queue) const; |
229 | 297 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 | 354 |
287 struct AnyThread& any_thread() { | 355 struct AnyThread& any_thread() { |
288 any_thread_lock_.AssertAcquired(); | 356 any_thread_lock_.AssertAcquired(); |
289 return any_thread_; | 357 return any_thread_; |
290 } | 358 } |
291 const struct AnyThread& any_thread() const { | 359 const struct AnyThread& any_thread() const { |
292 any_thread_lock_.AssertAcquired(); | 360 any_thread_lock_.AssertAcquired(); |
293 return any_thread_; | 361 return any_thread_; |
294 } | 362 } |
295 | 363 |
296 base::TimeTicks next_scheduled_delayed_do_work_time_; | 364 NextDelayedDoWork next_delayed_do_work_; |
297 | 365 |
298 bool record_task_delay_histograms_; | 366 bool record_task_delay_histograms_; |
299 | 367 |
300 int work_batch_size_; | 368 int work_batch_size_; |
301 size_t task_count_; | 369 size_t task_count_; |
302 | 370 |
303 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_; | 371 base::ObserverList<base::MessageLoop::TaskObserver> task_observers_; |
304 | 372 |
305 base::ObserverList<TaskTimeObserver> task_time_observers_; | 373 base::ObserverList<TaskTimeObserver> task_time_observers_; |
306 | 374 |
307 const char* tracing_category_; | 375 const char* tracing_category_; |
308 const char* disabled_by_default_tracing_category_; | 376 const char* disabled_by_default_tracing_category_; |
309 const char* disabled_by_default_verbose_tracing_category_; | 377 const char* disabled_by_default_verbose_tracing_category_; |
310 | 378 |
311 internal::TaskQueueImpl* currently_executing_task_queue_; // NOT OWNED | 379 internal::TaskQueueImpl* currently_executing_task_queue_; // NOT OWNED |
312 | 380 |
313 Observer* observer_; // NOT OWNED | 381 Observer* observer_; // NOT OWNED |
314 scoped_refptr<DeletionSentinel> deletion_sentinel_; | 382 scoped_refptr<DeletionSentinel> deletion_sentinel_; |
315 base::WeakPtrFactory<TaskQueueManager> weak_factory_; | 383 base::WeakPtrFactory<TaskQueueManager> weak_factory_; |
316 | 384 |
317 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager); | 385 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager); |
318 }; | 386 }; |
319 | 387 |
320 } // namespace scheduler | 388 } // namespace scheduler |
321 } // namespace blink | 389 } // namespace blink |
322 | 390 |
323 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_
H_ | 391 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_
H_ |
OLD | NEW |