• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #ifndef BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
6 #define BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
7 
8 #include <map>
9 
10 #include "base/callback.h"
11 #include "base/logging.h"
12 #include "base/macros.h"
13 #include "base/task/sequence_manager/intrusive_heap.h"
14 #include "base/task/sequence_manager/lazy_now.h"
15 #include "base/task/sequence_manager/task_queue_impl.h"
16 #include "base/time/time.h"
17 
18 namespace base {
19 namespace sequence_manager {
20 
21 class SequenceManager;
22 
23 namespace internal {
24 class SequenceManagerImpl;
25 class TaskQueueImpl;
26 }  // namespace internal
27 
28 // TimeDomain wakes up TaskQueues when their delayed tasks are due to run.
29 // This class allows overrides to enable clock overriding on some TaskQueues
30 // (e.g. auto-advancing virtual time, throttled clock, etc).
31 //
32 // TaskQueue maintains its own next wake-up time and communicates it
33 // to the TimeDomain, which aggregates wake-ups across registered TaskQueues
34 // into a global wake-up, which ultimately gets passed to the ThreadController.
35 class BASE_EXPORT TimeDomain {
36  public:
37   virtual ~TimeDomain();
38 
39   // Returns LazyNow in TimeDomain's time.
40   // Can be called from any thread.
41   // TODO(alexclarke): Make this main thread only.
42   virtual LazyNow CreateLazyNow() const = 0;
43 
44   // Evaluates TimeDomain's time.
45   // Can be called from any thread.
46   // TODO(alexclarke): Make this main thread only.
47   virtual TimeTicks Now() const = 0;
48 
49   // Computes the delay until the time when TimeDomain needs to wake up
50   // some TaskQueue. Specific time domains (e.g. virtual or throttled) may
51   // return TimeDelata() if TaskQueues have any delayed tasks they deem
52   // eligible to run. It's also allowed to advance time domains's internal
53   // clock when this method is called.
54   // Can be called from main thread only.
55   // NOTE: |lazy_now| and the return value are in the SequenceManager's time.
56   virtual Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) = 0;
57 
58   void AsValueInto(trace_event::TracedValue* state) const;
59 
60  protected:
61   TimeDomain();
62 
63   SequenceManager* sequence_manager() const;
64 
65   // Returns the earliest scheduled wake up in the TimeDomain's time.
66   Optional<TimeTicks> NextScheduledRunTime() const;
67 
NumberOfScheduledWakeUps()68   size_t NumberOfScheduledWakeUps() const {
69     return delayed_wake_up_queue_.size();
70   }
71 
72   // Tells SequenceManager to schedule delayed work, use TimeTicks::Max()
73   // to unschedule. Also cancels any previous requests.
74   // May be overriden to control wake ups manually.
75   virtual void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time);
76 
77   // Tells SequenceManager to schedule immediate work.
78   // May be overriden to control wake ups manually.
79   virtual void RequestDoWork();
80 
81   // For implementation-specific tracing.
82   virtual void AsValueIntoInternal(trace_event::TracedValue* state) const;
83   virtual const char* GetName() const = 0;
84 
85  private:
86   friend class internal::TaskQueueImpl;
87   friend class internal::SequenceManagerImpl;
88   friend class TestTimeDomain;
89 
90   // Called when the TimeDomain is registered.
91   // TODO(kraynov): Pass SequenceManager in the constructor.
92   void OnRegisterWithSequenceManager(
93       internal::SequenceManagerImpl* sequence_manager);
94 
95   // Schedule TaskQueue to wake up at certain time, repeating calls with
96   // the same |queue| invalidate previous requests.
97   // Nullopt |wake_up| cancels a previously set wake up for |queue|.
98   // NOTE: |lazy_now| is provided in TimeDomain's time.
99   void SetNextWakeUpForQueue(
100       internal::TaskQueueImpl* queue,
101       Optional<internal::TaskQueueImpl::DelayedWakeUp> wake_up,
102       LazyNow* lazy_now);
103 
104   // Remove the TaskQueue from any internal data sctructures.
105   void UnregisterQueue(internal::TaskQueueImpl* queue);
106 
107   // Wake up each TaskQueue where the delay has elapsed.
108   void WakeUpReadyDelayedQueues(LazyNow* lazy_now);
109 
110   struct ScheduledDelayedWakeUp {
111     internal::TaskQueueImpl::DelayedWakeUp wake_up;
112     internal::TaskQueueImpl* queue;
113 
114     bool operator<=(const ScheduledDelayedWakeUp& other) const {
115       return wake_up <= other.wake_up;
116     }
117 
SetHeapHandleScheduledDelayedWakeUp118     void SetHeapHandle(internal::HeapHandle handle) {
119       DCHECK(handle.IsValid());
120       queue->set_heap_handle(handle);
121     }
122 
ClearHeapHandleScheduledDelayedWakeUp123     void ClearHeapHandle() {
124       DCHECK(queue->heap_handle().IsValid());
125       queue->set_heap_handle(internal::HeapHandle());
126     }
127   };
128 
129   internal::SequenceManagerImpl* sequence_manager_;  // Not owned.
130   internal::IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wake_up_queue_;
131 
132   ThreadChecker main_thread_checker_;
133   DISALLOW_COPY_AND_ASSIGN(TimeDomain);
134 };
135 
136 }  // namespace sequence_manager
137 }  // namespace base
138 
139 #endif  // BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_
140