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

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: Fix Win for realz hopefully... Created 5 years, 6 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
« no previous file with comments | « base/trace_event/trace_event.h ('k') | components/scheduler/child/idle_helper.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::Delegate {
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
105 // Returns the deadline for the current idle task.
106 base::TimeTicks CurrentIdleTaskDeadline() const;
107
108 // SingleThreadIdleTaskRunner::Delegate implementation:
109 void OnIdleTaskPosted() override;
110 base::TimeTicks WillProcessIdleTask() override;
111 void DidProcessIdleTask() 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
104 IdlePeriodState SchedulerIdlePeriodState() const; 117 IdlePeriodState SchedulerIdlePeriodState() const;
105
106 // IdleTaskDeadlineSupplier Implementation:
107 void CurrentIdleTaskDeadlineCallback(base::TimeTicks* deadline_out) const;
108
109 static const char* IdlePeriodStateToString(IdlePeriodState state); 118 static const char* IdlePeriodStateToString(IdlePeriodState state);
110 119
111 private: 120 private:
121 friend class BaseIdleHelperTest;
112 friend class IdleHelperTest; 122 friend class IdleHelperTest;
113 123
124 class State {
125 public:
126 State(SchedulerHelper* helper,
127 const char* tracing_category,
128 const char* disabled_by_default_tracing_category,
129 const char* idle_period_tracing_name);
130 virtual ~State();
131
132 void UpdateState(IdlePeriodState new_state,
133 base::TimeTicks new_deadline,
134 base::TimeTicks optional_now);
135 bool IsIdlePeriodPaused() const;
136
137 IdlePeriodState idle_period_state() const;
138 base::TimeTicks idle_period_deadline() const;
139
140 void TraceIdleIdleTaskStart();
141 void TraceIdleIdleTaskEnd();
142 void TraceEventIdlePeriodStateChange(IdlePeriodState new_state,
143 base::TimeTicks new_deadline,
144 base::TimeTicks optional_now);
145
146 private:
147 SchedulerHelper* helper_; // NOT OWNED
148
149 IdlePeriodState idle_period_state_;
150 base::TimeTicks idle_period_deadline_;
151
152 base::TraceTicks idle_period_deadline_for_tracing_;
153 base::TraceTicks last_idle_task_trace_time_;
154 bool nestable_events_started_;
155 const char* tracing_category_;
156 const char* disabled_by_default_tracing_category_;
157 const char* idle_period_tracing_name_;
158
159 DISALLOW_COPY_AND_ASSIGN(State);
160 };
161
114 // The minimum delay to wait between retrying to initiate a long idle time. 162 // The minimum delay to wait between retrying to initiate a long idle time.
115 static const int kRetryEnableLongIdlePeriodDelayMillis = 1; 163 static const int kRetryEnableLongIdlePeriodDelayMillis = 1;
116 164
117 // Returns the new idle period state for the next long idle period. Fills in 165 // 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 166 // |next_long_idle_period_delay_out| with the next time we should try to
119 // initiate the next idle period. 167 // initiate the next idle period.
120 IdlePeriodState ComputeNewLongIdlePeriodState( 168 IdlePeriodState ComputeNewLongIdlePeriodState(
121 const base::TimeTicks now, 169 const base::TimeTicks now,
122 base::TimeDelta* next_long_idle_period_delay_out); 170 base::TimeDelta* next_long_idle_period_delay_out);
123 171
124 bool ShouldWaitForQuiescence(); 172 bool ShouldWaitForQuiescence();
125 void EnableLongIdlePeriodAfterWakeup(); 173 void OnIdleTaskPostedOnMainThread();
174 void UpdateLongIdlePeriodStateAfterIdleTask();
175
176 void SetIdlePeriodState(IdlePeriodState new_state,
177 base::TimeTicks new_deadline,
178 base::TimeTicks optional_now);
126 179
127 // Returns true if |state| represents being within an idle period state. 180 // Returns true if |state| represents being within an idle period state.
128 static bool IsInIdlePeriod(IdlePeriodState state); 181 static bool IsInIdlePeriod(IdlePeriodState state);
182 // Returns true if |state| represents being within a long idle period state.
183 static bool IsInLongIdlePeriod(IdlePeriodState state);
129 184
130 SchedulerHelper* helper_; // NOT OWNED 185 SchedulerHelper* helper_; // NOT OWNED
131 Delegate* delegate_; // NOT OWNED 186 Delegate* delegate_; // NOT OWNED
132 size_t idle_queue_index_; 187 size_t idle_queue_index_;
133 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; 188 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
134 189
135 CancelableClosureHolder end_idle_period_closure_;
136 CancelableClosureHolder enable_next_long_idle_period_closure_; 190 CancelableClosureHolder enable_next_long_idle_period_closure_;
137 CancelableClosureHolder enable_next_long_idle_period_after_wakeup_closure_; 191 CancelableClosureHolder on_idle_task_posted_closure_;
138 192
139 IdlePeriodState idle_period_state_; 193 State state_;
140 194
141 // A bitmap which controls the set of queues that are checked for quiescence 195 // A bitmap which controls the set of queues that are checked for quiescence
142 // before triggering a long idle period. 196 // before triggering a long idle period.
143 uint64 quiescence_monitored_task_queue_mask_; 197 uint64 quiescence_monitored_task_queue_mask_;
144 base::TimeDelta required_quiescence_duration_before_long_idle_period_; 198 base::TimeDelta required_quiescence_duration_before_long_idle_period_;
145 199
146 base::TimeTicks idle_period_deadline_;
147
148 const char* tracing_category_;
149 const char* disabled_by_default_tracing_category_; 200 const char* disabled_by_default_tracing_category_;
150 const char* idle_period_tracing_name_;
151 201
152 base::WeakPtr<IdleHelper> weak_idle_helper_ptr_; 202 base::WeakPtr<IdleHelper> weak_idle_helper_ptr_;
153 base::WeakPtrFactory<IdleHelper> weak_factory_; 203 base::WeakPtrFactory<IdleHelper> weak_factory_;
154 204
155 DISALLOW_COPY_AND_ASSIGN(IdleHelper); 205 DISALLOW_COPY_AND_ASSIGN(IdleHelper);
156 }; 206 };
157 207
158 } // namespace scheduler 208 } // namespace scheduler
159 209
160 #endif // COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_ 210 #endif // COMPONENTS_SCHEDULER_CHILD_IDLE_HELPER_H_
OLDNEW
« no previous file with comments | « base/trace_event/trace_event.h ('k') | components/scheduler/child/idle_helper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698