Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: components/scheduler/child/idle_helper.h

Issue 1151353003: [scheduler]: Avoid waking up the scheduler to end long idle periods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@end_idle_sync_2
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_ 5 #ifndef COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_
6 #define COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_ 6 #define COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_
7 7
8 #include "base/message_loop/message_loop.h"
8 #include "components/scheduler/child/cancelable_closure_holder.h" 9 #include "components/scheduler/child/cancelable_closure_holder.h"
9 #include "components/scheduler/child/prioritizing_task_queue_selector.h" 10 #include "components/scheduler/child/prioritizing_task_queue_selector.h"
10 #include "components/scheduler/child/single_thread_idle_task_runner.h" 11 #include "components/scheduler/child/single_thread_idle_task_runner.h"
11 #include "components/scheduler/scheduler_export.h" 12 #include "components/scheduler/scheduler_export.h"
12 13
13 namespace scheduler { 14 namespace scheduler {
14 15
15 class SchedulerHelper; 16 class SchedulerHelper;
16 17
17 // Common scheduler functionality for Idle tasks. 18 // Common scheduler functionality for Idle tasks.
18 class SCHEDULER_EXPORT IdleHelper { 19 class SCHEDULER_EXPORT IdleHelper
20 : public base::MessageLoop::TaskObserver,
21 public SingleThreadIdleTaskRunner::Observer {
19 public: 22 public:
20 // Used to by scheduler implementations to customize idle behaviour. 23 // Used to by scheduler implementations to customize idle behaviour.
21 class SCHEDULER_EXPORT Delegate { 24 class SCHEDULER_EXPORT Delegate {
22 public: 25 public:
23 Delegate(); 26 Delegate();
24 virtual ~Delegate(); 27 virtual ~Delegate();
25 28
26 // If it's ok to enter a long idle period, return true. Otherwise return 29 // If it's ok to enter a long idle period, return true. Otherwise return
27 // false and set next_long_idle_period_delay_out so we know when to try 30 // false and set next_long_idle_period_delay_out so we know when to try
28 // again. 31 // again.
29 virtual bool CanEnterLongIdlePeriod( 32 virtual bool CanEnterLongIdlePeriod(
30 base::TimeTicks now, 33 base::TimeTicks now,
31 base::TimeDelta* next_long_idle_period_delay_out) = 0; 34 base::TimeDelta* next_long_idle_period_delay_out) = 0;
32 35
33 // Signals that the Long Idle Period hasn't started yet because the system 36 // Signals that the Long Idle Period hasn't started yet because the system
34 // isn't quiescent. 37 // isn't quiescent.
35 virtual void IsNotQuiescent() = 0; 38 virtual void IsNotQuiescent() = 0;
36 39
37 private: 40 private:
38 DISALLOW_COPY_AND_ASSIGN(Delegate); 41 DISALLOW_COPY_AND_ASSIGN(Delegate);
39 }; 42 };
40 43
41 // Keep IdleHelper::IdlePeriodStateToString in sync with this enum. 44 // Keep IdleHelper::IdlePeriodStateToString in sync with this enum.
42 enum class IdlePeriodState { 45 enum class IdlePeriodState {
43 NOT_IN_IDLE_PERIOD, 46 NOT_IN_IDLE_PERIOD,
44 IN_SHORT_IDLE_PERIOD, 47 IN_SHORT_IDLE_PERIOD,
45 IN_LONG_IDLE_PERIOD, 48 IN_LONG_IDLE_PERIOD,
46 IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE, 49 IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE,
47 ENDING_LONG_IDLE_PERIOD, 50 IN_LONG_IDLE_PERIOD_PAUSED,
48 // Must be the last entry. 51 // Must be the last entry.
49 IDLE_PERIOD_STATE_COUNT, 52 IDLE_PERIOD_STATE_COUNT,
50 FIRST_IDLE_PERIOD_STATE = NOT_IN_IDLE_PERIOD, 53 FIRST_IDLE_PERIOD_STATE = NOT_IN_IDLE_PERIOD,
51 }; 54 };
52 55
53 // The maximum length of an idle period. 56 // The maximum length of an idle period.
54 static const int kMaximumIdlePeriodMillis = 50; 57 static const int kMaximumIdlePeriodMillis = 50;
55 58
56 // |helper| and |delegate| are not owned by IdleHelper object and must 59 // |helper| and |delegate| are not owned by IdleHelper object and must
57 // outlive it. 60 // outlive it.
58 IdleHelper( 61 IdleHelper(
59 SchedulerHelper* helper, 62 SchedulerHelper* helper,
60 Delegate* delegate, 63 Delegate* delegate,
61 size_t idle_queue_index, 64 size_t idle_queue_index,
62 const char* tracing_category, 65 const char* tracing_category,
63 const char* disabled_by_default_tracing_category, 66 const char* disabled_by_default_tracing_category,
64 const char* idle_period_tracing_name, 67 const char* idle_period_tracing_name,
65 base::TimeDelta required_quiescence_duration_before_long_idle_period); 68 base::TimeDelta required_quiescence_duration_before_long_idle_period);
66 ~IdleHelper(); 69 ~IdleHelper() override;
67 70
68 // Returns the idle task runner. Tasks posted to this runner may be reordered 71 // Returns the idle task runner. Tasks posted to this runner may be reordered
69 // relative to other task types and may be starved for an arbitrarily long 72 // relative to other task types and may be starved for an arbitrarily long
70 // time if no idle time is available. 73 // time if no idle time is available.
71 scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner(); 74 scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner();
72 75
73 // If |required_quiescence_duration_before_long_idle_period_| is zero then 76 // If |required_quiescence_duration_before_long_idle_period_| is zero then
74 // immediately initiate a long idle period, otherwise check if any tasks have 77 // immediately initiate a long idle period, otherwise check if any tasks have
75 // run recently and if so, check again after a delay of 78 // run recently and if so, check again after a delay of
76 // |required_quiescence_duration_before_long_idle_period_|. 79 // |required_quiescence_duration_before_long_idle_period_|.
77 // Calling this function will end any previous idle period immediately, and 80 // Calling this function will end any previous idle period immediately, and
78 // potentially again later if 81 // potentially again later if
79 // |required_quiescence_duration_before_long_idle_period_| is non-zero. 82 // |required_quiescence_duration_before_long_idle_period_| is non-zero.
80 // NOTE EndIdlePeriod will disable the long idle periods. 83 // NOTE EndIdlePeriod will disable the long idle periods.
81 void EnableLongIdlePeriod(); 84 void EnableLongIdlePeriod();
82 85
83 // Start and end an idle period. If |post_end_idle_period| is true, it will 86 // Start an idle period with a given idle period deadline.
84 // post a delayed EndIdlePeriod scheduled to occur at |idle_period_deadline|.
85 void StartIdlePeriod(IdlePeriodState new_idle_period_state, 87 void StartIdlePeriod(IdlePeriodState new_idle_period_state,
86 base::TimeTicks now, 88 base::TimeTicks now,
87 base::TimeTicks idle_period_deadline, 89 base::TimeTicks idle_period_deadline);
88 bool post_end_idle_period);
89 90
90 // This will end an idle period either started with StartIdlePeriod or 91 // This will end an idle period either started with StartIdlePeriod or
91 // EnableLongIdlePeriod. 92 // EnableLongIdlePeriod.
92 void EndIdlePeriod(); 93 void EndIdlePeriod();
93 94
94 // Returns true if a currently running idle task could exceed its deadline 95 // Returns true if a currently running idle task could exceed its deadline
95 // without impacting user experience too much. This should only be used if 96 // without impacting user experience too much. This should only be used if
96 // there is a task which cannot be pre-empted and is likely to take longer 97 // there is a task which cannot be pre-empted and is likely to take longer
97 // than the largest expected idle task deadline. It should NOT be polled to 98 // than the largest expected idle task deadline. It should NOT be polled to
98 // check whether more work can be performed on the current idle task after 99 // check whether more work can be performed on the current idle task after
99 // its deadline has expired - post a new idle task for the continuation of the 100 // its deadline has expired - post a new idle task for the continuation of the
100 // work in this case. 101 // work in this case.
101 // Must be called from the thread this class was created on. 102 // Must be called from the thread this class was created on.
102 bool CanExceedIdleDeadlineIfRequired() const; 103 bool CanExceedIdleDeadlineIfRequired() const;
103 104
104 IdlePeriodState SchedulerIdlePeriodState() const; 105 // Returns the deadline for the current idle task.
105
106 // IdleTaskDeadlineSupplier Implementation:
107 void CurrentIdleTaskDeadlineCallback(base::TimeTicks* deadline_out) const; 106 void CurrentIdleTaskDeadlineCallback(base::TimeTicks* deadline_out) const;
108 107
108 // SingleThreadIdleTaskRunner:Observer implementation:
Sami 2015/05/26 13:35:41 s/:/::/
rmcilroy 2015/05/27 11:58:36 Done.
109 void OnIdleTaskPosted() override;
110 void OnWillRunIdleTask(base::TimeTicks* deadline_out) const override;
Sami 2015/05/26 13:35:41 Should we make deadline_out a normal return value
rmcilroy 2015/05/27 11:58:37 Done.
111 void OnDidRunIdleTask() override;
112
113 // base::MessageLoop::TaskObserver implementation:
114 void WillProcessTask(const base::PendingTask& pending_task) override;
115 void DidProcessTask(const base::PendingTask& pending_task) override;
116
117 IdlePeriodState SchedulerIdlePeriodState() const;
109 static const char* IdlePeriodStateToString(IdlePeriodState state); 118 static const char* IdlePeriodStateToString(IdlePeriodState state);
110 119
111 private: 120 private:
112 friend class IdleHelperTest; 121 friend class IdleHelperTest;
113 122
114 // The minimum delay to wait between retrying to initiate a long idle time. 123 // The minimum delay to wait between retrying to initiate a long idle time.
115 static const int kRetryEnableLongIdlePeriodDelayMillis = 1; 124 static const int kRetryEnableLongIdlePeriodDelayMillis = 1;
116 125
117 // Returns the new idle period state for the next long idle period. Fills in 126 // Returns the new idle period state for the next long idle period. Fills in
118 // |next_long_idle_period_delay_out| with the next time we should try to 127 // |next_long_idle_period_delay_out| with the next time we should try to
119 // initiate the next idle period. 128 // initiate the next idle period.
120 IdlePeriodState ComputeNewLongIdlePeriodState( 129 IdlePeriodState ComputeNewLongIdlePeriodState(
121 const base::TimeTicks now, 130 const base::TimeTicks now,
122 base::TimeDelta* next_long_idle_period_delay_out); 131 base::TimeDelta* next_long_idle_period_delay_out);
123 132
124 bool ShouldWaitForQuiescence(); 133 bool ShouldWaitForQuiescence();
125 void EnableLongIdlePeriodAfterWakeup(); 134 void CheckLongIdlePeriodSentinel();
135
136 void SetIdlePeriodState(IdlePeriodState new_state,
137 base::TimeTicks new_deadline,
138 base::TimeTicks optional_now);
126 139
127 // Returns true if |state| represents being within an idle period state. 140 // Returns true if |state| represents being within an idle period state.
128 static bool IsInIdlePeriod(IdlePeriodState state); 141 static bool IsInIdlePeriod(IdlePeriodState state);
142 // Returns true if |state| represents being within a long idle period state.
143 static bool IsInLongIdlePeriod(IdlePeriodState state);
144
145 void TraceEventIdlePeriodStateChange(IdlePeriodState new_state,
146 base::TimeTicks new_deadline,
147 base::TimeTicks optional_now) const;
129 148
130 SchedulerHelper* helper_; // NOT OWNED 149 SchedulerHelper* helper_; // NOT OWNED
131 Delegate* delegate_; // NOT OWNED 150 Delegate* delegate_; // NOT OWNED
132 size_t idle_queue_index_; 151 size_t idle_queue_index_;
133 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; 152 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
134 153
135 CancelableClosureHolder end_idle_period_closure_; 154 CancelableClosureHolder enable_next_long_idle_period_closure_;;
136 CancelableClosureHolder enable_next_long_idle_period_closure_;
137 CancelableClosureHolder enable_next_long_idle_period_after_wakeup_closure_;
138 155
156 // Do not modify these field directly, instead call SetIdlePeriodState.
139 IdlePeriodState idle_period_state_; 157 IdlePeriodState idle_period_state_;
158 base::TimeTicks idle_period_deadline_;
140 159
141 // A bitmap which controls the set of queues that are checked for quiescence 160 // A bitmap which controls the set of queues that are checked for quiescence
142 // before triggering a long idle period. 161 // before triggering a long idle period.
143 uint64 quiescence_monitored_task_queue_mask_; 162 uint64 quiescence_monitored_task_queue_mask_;
144 base::TimeDelta required_quiescence_duration_before_long_idle_period_; 163 base::TimeDelta required_quiescence_duration_before_long_idle_period_;
145 164
146 base::TimeTicks idle_period_deadline_; 165 mutable base::TimeTicks last_traced_start_running_idle_task_;
147 166 mutable bool nestable_events_started_;
148 const char* tracing_category_; 167 const char* tracing_category_;
149 const char* disabled_by_default_tracing_category_; 168 const char* disabled_by_default_tracing_category_;
150 const char* idle_period_tracing_name_; 169 const char* idle_period_tracing_name_;
151 170
152 base::WeakPtr<IdleHelper> weak_idle_helper_ptr_; 171 base::WeakPtr<IdleHelper> weak_idle_helper_ptr_;
153 base::WeakPtrFactory<IdleHelper> weak_factory_; 172 base::WeakPtrFactory<IdleHelper> weak_factory_;
154 173
155 DISALLOW_COPY_AND_ASSIGN(IdleHelper); 174 DISALLOW_COPY_AND_ASSIGN(IdleHelper);
156 }; 175 };
157 176
158 } // namespace scheduler 177 } // namespace scheduler
159 178
160 #endif // COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_ 179 #endif // COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698