time_domain.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. // Copyright 2018 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. #ifndef BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
  5. #define BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
  6. #include <map>
  7. #include "base/callback.h"
  8. #include "base/check.h"
  9. #include "base/task/common/intrusive_heap.h"
  10. #include "base/task/sequence_manager/lazy_now.h"
  11. #include "base/task/sequence_manager/task_queue_impl.h"
  12. #include "base/time/time.h"
  13. #include "base/values.h"
  14. namespace base {
  15. namespace sequence_manager {
  16. class SequenceManager;
  17. namespace internal {
  18. class AssociatedThreadId;
  19. class SequenceManagerImpl;
  20. class TaskQueueImpl;
  21. } // namespace internal
  22. // TimeDomain wakes up TaskQueues when their delayed tasks are due to run.
  23. // This class allows overrides to enable clock overriding on some TaskQueues
  24. // (e.g. auto-advancing virtual time, throttled clock, etc).
  25. //
  26. // TaskQueue maintains its own next wake-up time and communicates it
  27. // to the TimeDomain, which aggregates wake-ups across registered TaskQueues
  28. // into a global wake-up, which ultimately gets passed to the ThreadController.
  29. class BASE_EXPORT TimeDomain {
  30. public:
  31. TimeDomain(const TimeDomain&) = delete;
  32. TimeDomain& operator=(const TimeDomain&) = delete;
  33. virtual ~TimeDomain();
  34. // Returns LazyNow in TimeDomain's time.
  35. // Can be called from any thread.
  36. // TODO(alexclarke): Make this main thread only.
  37. virtual LazyNow CreateLazyNow() const = 0;
  38. // Evaluates TimeDomain's time.
  39. // Can be called from any thread.
  40. // TODO(alexclarke): Make this main thread only.
  41. virtual TimeTicks Now() const = 0;
  42. // Computes the delay until the time when TimeDomain needs to wake up some
  43. // TaskQueue on the main thread. Specific time domains (e.g. virtual or
  44. // throttled) may return TimeDelta() if TaskQueues have any delayed tasks they
  45. // deem eligible to run. It's also allowed to advance time domains's internal
  46. // clock when this method is called.
  47. // Can be called from main thread only.
  48. // NOTE: |lazy_now| and the return value are in the SequenceManager's time.
  49. virtual Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) = 0;
  50. Value AsValue() const;
  51. bool has_pending_high_resolution_tasks() const {
  52. return pending_high_res_wake_up_count_;
  53. }
  54. // Returns true if there are no pending delayed tasks.
  55. bool empty() const { return delayed_wake_up_queue_.empty(); }
  56. // This is the signal that virtual time should step forward. If
  57. // RunLoop::QuitWhenIdle has been called then |quit_when_idle_requested| will
  58. // be true. Returns true if there is a task to run now.
  59. virtual bool MaybeFastForwardToNextTask(bool quit_when_idle_requested) = 0;
  60. protected:
  61. TimeDomain();
  62. SequenceManager* sequence_manager() const;
  63. // Returns the earliest scheduled wake up in the TimeDomain's time.
  64. Optional<TimeTicks> NextScheduledRunTime() const;
  65. size_t NumberOfScheduledWakeUps() const {
  66. return delayed_wake_up_queue_.size();
  67. }
  68. // Tells SequenceManager to schedule delayed work, use TimeTicks::Max()
  69. // to unschedule. Also cancels any previous requests.
  70. // May be overriden to control wake ups manually.
  71. virtual void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time);
  72. // Tells SequenceManager to schedule immediate work.
  73. // May be overriden to control wake ups manually.
  74. virtual void RequestDoWork();
  75. virtual const char* GetName() const = 0;
  76. // Called when the TimeDomain is registered. |sequence_manager| is expected to
  77. // be valid for the duration of TimeDomain's existence.
  78. // TODO(scheduler-dev): Pass SequenceManager in the constructor.
  79. virtual void OnRegisterWithSequenceManager(
  80. internal::SequenceManagerImpl* sequence_manager);
  81. private:
  82. friend class internal::TaskQueueImpl;
  83. friend class internal::SequenceManagerImpl;
  84. friend class TestTimeDomain;
  85. // Schedule TaskQueue to wake up at certain time, repeating calls with
  86. // the same |queue| invalidate previous requests.
  87. // Nullopt |wake_up| cancels a previously set wake up for |queue|.
  88. // NOTE: |lazy_now| is provided in TimeDomain's time.
  89. void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue,
  90. Optional<internal::DelayedWakeUp> wake_up,
  91. internal::WakeUpResolution resolution,
  92. LazyNow* lazy_now);
  93. // Remove the TaskQueue from any internal data sctructures.
  94. void UnregisterQueue(internal::TaskQueueImpl* queue);
  95. // Wake up each TaskQueue where the delay has elapsed. Note this doesn't
  96. // ScheduleWork.
  97. void MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now);
  98. struct ScheduledDelayedWakeUp {
  99. internal::DelayedWakeUp wake_up;
  100. internal::WakeUpResolution resolution;
  101. internal::TaskQueueImpl* queue;
  102. bool operator<=(const ScheduledDelayedWakeUp& other) const {
  103. if (wake_up == other.wake_up) {
  104. return static_cast<int>(resolution) <=
  105. static_cast<int>(other.resolution);
  106. }
  107. return wake_up <= other.wake_up;
  108. }
  109. void SetHeapHandle(base::internal::HeapHandle handle) {
  110. DCHECK(handle.IsValid());
  111. queue->set_heap_handle(handle);
  112. }
  113. void ClearHeapHandle() {
  114. DCHECK(queue->heap_handle().IsValid());
  115. queue->set_heap_handle(base::internal::HeapHandle());
  116. }
  117. HeapHandle GetHeapHandle() const { return queue->heap_handle(); }
  118. };
  119. internal::SequenceManagerImpl* sequence_manager_; // Not owned.
  120. base::internal::IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wake_up_queue_;
  121. int pending_high_res_wake_up_count_ = 0;
  122. scoped_refptr<internal::AssociatedThreadId> associated_thread_;
  123. };
  124. } // namespace sequence_manager
  125. } // namespace base
  126. #endif // BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_