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
3 // found in the LICENSE file.
5 #ifndef CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_
6 #define CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_
8 #include "cc/test/test_now_source.h"
9 #include "content/child/scheduler/cancelable_closure_holder.h"
10 #include "content/child/scheduler/single_thread_idle_task_runner.h"
11 #include "content/child/scheduler/task_queue_manager.h"
15 class PrioritizingTaskQueueSelector
;
16 class NestableSingleThreadTaskRunner
;
18 // Common scheduler functionality for Default and Idle tasks.
19 class CONTENT_EXPORT SchedulerHelper
{
21 // Used to by scheduler implementations to customize idle behaviour.
22 class CONTENT_EXPORT SchedulerHelperDelegate
{
24 SchedulerHelperDelegate();
25 virtual ~SchedulerHelperDelegate();
27 // If it's ok to enter a Long Idle period, return true. Otherwise return
28 // false and set next_long_idle_period_delay_out so we know when to try
30 virtual bool CanEnterLongIdlePeriod(
32 base::TimeDelta
* next_long_idle_period_delay_out
) = 0;
35 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperDelegate
);
38 // NOTE |total_task_queue_count| must be >= TASK_QUEUE_COUNT.
39 // Category strings must have application lifetime (statics or
40 // literals). They may not include " chars.
42 scoped_refptr
<NestableSingleThreadTaskRunner
> main_task_runner
,
43 SchedulerHelperDelegate
* scheduler_helper_delegate
,
44 const char* tracing_category
,
45 const char* disabled_by_default_tracing_category
,
46 size_t total_task_queue_count
);
49 // Returns the default task runner.
50 scoped_refptr
<base::SingleThreadTaskRunner
> DefaultTaskRunner();
52 // Returns the idle task runner. Tasks posted to this runner may be reordered
53 // relative to other task types and may be starved for an arbitrarily long
54 // time if no idle time is available.
55 scoped_refptr
<SingleThreadIdleTaskRunner
> IdleTaskRunner();
57 // Returns the control task runner. Tasks posted to this runner are executed
58 // with the highest priority. Care must be taken to avoid starvation of other
60 scoped_refptr
<base::SingleThreadTaskRunner
> ControlTaskRunner();
62 // Returns true if a currently running idle task could exceed its deadline
63 // without impacting user experience too much. This should only be used if
64 // there is a task which cannot be pre-empted and is likely to take longer
65 // than the largest expected idle task deadline. It should NOT be polled to
66 // check whether more work can be performed on the current idle task after
67 // its deadline has expired - post a new idle task for the continuation of the
69 // Must be called from the thread this class was created on.
70 bool CanExceedIdleDeadlineIfRequired() const;
72 // Adds or removes a task observer from the scheduler. The observer will be
73 // notified before and after every executed task. These functions can only be
74 // called on the thread this class was created on.
75 void AddTaskObserver(base::MessageLoop::TaskObserver
* task_observer
);
76 void RemoveTaskObserver(base::MessageLoop::TaskObserver
* task_observer
);
78 // Shuts down the scheduler by dropping any remaining pending work in the work
79 // queues. After this call any work posted to the task runners will be
83 // Returns true if Shutdown() has been called. Otherwise returns false.
84 bool IsShutdown() const { return !task_queue_manager_
.get(); }
86 // Keep SchedulerHelper::TaskQueueIdToString in sync with this enum.
91 CONTROL_TASK_AFTER_WAKEUP_QUEUE
,
92 // Must be the last entry.
96 // Keep SchedulerHelper::IdlePeriodStateToString in sync with this enum.
97 enum class IdlePeriodState
{
101 IN_LONG_IDLE_PERIOD_WITH_MAX_DEADLINE
,
102 ENDING_LONG_IDLE_PERIOD
105 static const char* TaskQueueIdToString(QueueId queue_id
);
106 static const char* IdlePeriodStateToString(IdlePeriodState state
);
108 // The maximum length of an idle period.
109 static const int kMaximumIdlePeriodMillis
= 50;
111 // The minimum delay to wait between retrying to initiate a long idle time.
112 static const int kRetryInitiateLongIdlePeriodDelayMillis
= 1;
114 // IdleTaskDeadlineSupplier Implementation:
115 void CurrentIdleTaskDeadlineCallback(base::TimeTicks
* deadline_out
) const;
117 // 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
119 // initiate the next idle period.
120 IdlePeriodState
ComputeNewLongIdlePeriodState(
121 const base::TimeTicks now
,
122 base::TimeDelta
* next_long_idle_period_delay_out
);
124 // Initiate a long idle period.
125 void InitiateLongIdlePeriod();
126 void InitiateLongIdlePeriodAfterWakeup();
128 // Start and end an idle period. If |post_end_idle_period| is true, it will
129 // post a delayed EndIdlePeriod scheduled to occur at |idle_period_deadline|.
130 void StartIdlePeriod(IdlePeriodState new_idle_period_state
,
132 base::TimeTicks idle_period_deadline
,
133 bool post_end_idle_period
);
135 void EndIdlePeriod();
137 // Returns true if |state| represents being within an idle period state.
138 static bool IsInIdlePeriod(IdlePeriodState state
);
140 void CheckOnValidThread() const {
141 DCHECK(thread_checker_
.CalledOnValidThread());
145 base::TimeTicks
Now() const;
146 IdlePeriodState
SchedulerIdlePeriodState() const;
147 PrioritizingTaskQueueSelector
* SchedulerTaskQueueSelector() const;
148 TaskQueueManager
* SchedulerTaskQueueManager() const;
151 void SetTimeSourceForTesting(scoped_refptr
<cc::TestNowSource
> time_source
);
152 void SetWorkBatchSizeForTesting(size_t work_batch_size
);
155 friend class SchedulerHelperTest
;
157 base::ThreadChecker thread_checker_
;
158 scoped_ptr
<PrioritizingTaskQueueSelector
> task_queue_selector_
;
159 scoped_ptr
<TaskQueueManager
> task_queue_manager_
;
161 CancelableClosureHolder end_idle_period_closure_
;
162 CancelableClosureHolder initiate_next_long_idle_period_closure_
;
163 CancelableClosureHolder initiate_next_long_idle_period_after_wakeup_closure_
;
165 IdlePeriodState idle_period_state_
;
166 SchedulerHelperDelegate
* scheduler_helper_delegate_
; // NOT OWNED
168 scoped_refptr
<base::SingleThreadTaskRunner
> control_task_runner_
;
169 scoped_refptr
<base::SingleThreadTaskRunner
> control_task_after_wakeup_runner_
;
170 scoped_refptr
<base::SingleThreadTaskRunner
> default_task_runner_
;
171 scoped_refptr
<SingleThreadIdleTaskRunner
> idle_task_runner_
;
173 base::TimeTicks idle_period_deadline_
;
174 scoped_refptr
<cc::TestNowSource
> time_source_
;
176 const char* tracing_category_
;
177 const char* disabled_by_default_tracing_category_
;
179 base::WeakPtr
<SchedulerHelper
> weak_scheduler_ptr_
;
180 base::WeakPtrFactory
<SchedulerHelper
> weak_factory_
;
182 DISALLOW_COPY_AND_ASSIGN(SchedulerHelper
);
185 } // namespace content
187 #endif // CONTENT_CHILD_SCHEDULER_SCHEDULER_HELPER_H_