Chromium Code Reviews| 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 |