ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / renderer / scheduler / task_queue_manager.h
blob8f32b93a0ace6674cfa227db573ca5bad6f4540d
1 // Copyright 2014 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_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
6 #define CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_
8 #include "base/atomic_sequence_num.h"
9 #include "base/debug/task_annotator.h"
10 #include "base/macros.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/pending_task.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/synchronization/lock.h"
16 #include "base/threading/thread_checker.h"
17 #include "content/common/content_export.h"
19 namespace base {
20 namespace trace_event {
21 class ConvertableToTraceFormat;
22 class TracedValue;
26 namespace cc {
27 class TestNowSource;
30 namespace content {
31 namespace internal {
32 class TaskQueue;
34 class TaskQueueSelector;
36 // The task queue manager provides N task queues and a selector interface for
37 // choosing which task queue to service next. Each task queue consists of two
38 // sub queues:
40 // 1. Incoming task queue. Tasks that are posted get immediately appended here.
41 // When a task is appended into an empty incoming queue, the task manager
42 // work function (DoWork) is scheduled to run on the main task runner.
44 // 2. Work queue. If a work queue is empty when DoWork() is entered, tasks from
45 // the incoming task queue (if any) are moved here. The work queues are
46 // registered with the selector as input to the scheduling decision.
48 class CONTENT_EXPORT TaskQueueManager {
49 public:
50 // Keep TaskQueue::PumpPolicyToString in sync with this enum.
51 enum class PumpPolicy {
52 // Tasks posted to an incoming queue with an AUTO pump policy will be
53 // automatically scheduled for execution or transferred to the work queue
54 // automatically.
55 AUTO,
56 // Tasks posted to an incoming queue with an AFTER_WAKEUP pump policy
57 // will be scheduled for execution or transferred to the work queue
58 // automatically but only after another queue has executed a task.
59 AFTER_WAKEUP,
60 // Tasks posted to an incoming queue with a MANUAL will not be
61 // automatically scheduled for execution or transferred to the work queue.
62 // Instead, the selector should call PumpQueue() when necessary to bring
63 // in new tasks for execution.
64 MANUAL
67 // Create a task queue manager with |task_queue_count| task queues.
68 // |main_task_runner| identifies the thread on which where the tasks are
69 // eventually run. |selector| is used to choose which task queue to service.
70 // It should outlive this class.
71 TaskQueueManager(size_t task_queue_count,
72 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
73 TaskQueueSelector* selector);
74 ~TaskQueueManager();
76 // Returns the task runner which targets the queue selected by |queue_index|.
77 scoped_refptr<base::SingleThreadTaskRunner> TaskRunnerForQueue(
78 size_t queue_index) const;
80 // Sets the pump policy for the |queue_index| to |pump_policy|. By
81 // default queues are created with AUTO_PUMP_POLICY.
82 void SetPumpPolicy(size_t queue_index, PumpPolicy pump_policy);
84 // Reloads new tasks from the incoming queue for |queue_index| into the work
85 // queue, regardless of whether the work queue is empty or not. After this,
86 // this function ensures that the tasks in the work queue, if any, are
87 // scheduled for execution.
89 // This function only needs to be called if automatic pumping is disabled
90 // for |queue_index|. See |SetQueueAutoPumpPolicy|. By default automatic
91 // pumping is enabled for all queues.
92 void PumpQueue(size_t queue_index);
94 // Returns true if there no tasks in either the work or incoming task queue
95 // identified by |queue_index|. Note that this function involves taking a
96 // lock, so calling it has some overhead.
97 bool IsQueueEmpty(size_t queue_index) const;
99 // Set the name |queue_index| for tracing purposes. |name| must be a pointer
100 // to a static string.
101 void SetQueueName(size_t queue_index, const char* name);
103 // Set the number of tasks executed in a single invocation of the task queue
104 // manager. Increasing the batch size can reduce the overhead of yielding
105 // back to the main message loop -- at the cost of potentially delaying other
106 // tasks posted to the main loop. The batch size is 1 by default.
107 void SetWorkBatchSize(int work_batch_size);
109 // These functions can only be called on the same thread that the task queue
110 // manager executes its tasks on.
111 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer);
112 void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer);
114 void SetTimeSourceForTesting(scoped_refptr<cc::TestNowSource> time_source);
116 private:
117 friend class internal::TaskQueue;
119 // Called by the task queue to register a new pending task and allocate a
120 // sequence number for it.
121 void DidQueueTask(base::PendingTask* pending_task);
123 // Post a task to call DoWork() on the main task runner. Only one pending
124 // DoWork is allowed from the main thread, to prevent an explosion of pending
125 // DoWorks.
126 void MaybePostDoWorkOnMainRunner();
128 // Use the selector to choose a pending task and run it.
129 void DoWork(bool posted_from_main_thread);
131 // Reloads any empty work queues which have automatic pumping enabled and
132 // which are eligible to be auto pumped based on the |previous_task| which was
133 // run. Call with an empty |previous_task| if no task was just run. Returns
134 // true if any work queue has tasks after doing this.
135 // |next_pending_delayed_task| should be the time of the next known delayed
136 // task. It is updated if any task is found which should run earlier.
137 bool UpdateWorkQueues(base::TimeTicks* next_pending_delayed_task,
138 const base::PendingTask* previous_task);
140 // Chooses the next work queue to service. Returns true if |out_queue_index|
141 // indicates the queue from which the next task should be run, false to
142 // avoid running any tasks.
143 bool SelectWorkQueueToService(size_t* out_queue_index);
145 // Runs a single nestable task from the work queue designated by
146 // |queue_index|. If |has_previous_task| is true, |previous_task| should
147 // contain the previous task in this work batch. Non-nestable task are
148 // reposted on the run loop. The queue must not be empty.
149 void ProcessTaskFromWorkQueue(size_t queue_index,
150 bool has_previous_task,
151 base::PendingTask* previous_task);
153 bool RunsTasksOnCurrentThread() const;
154 bool PostDelayedTask(const tracked_objects::Location& from_here,
155 const base::Closure& task,
156 base::TimeDelta delay);
157 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
158 const base::Closure& task,
159 base::TimeDelta delay);
160 internal::TaskQueue* Queue(size_t queue_index) const;
162 base::TimeTicks Now() const;
164 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
165 AsValueWithSelectorResult(bool should_run, size_t selected_queue) const;
167 std::vector<scoped_refptr<internal::TaskQueue>> queues_;
168 base::AtomicSequenceNumber task_sequence_num_;
169 base::debug::TaskAnnotator task_annotator_;
171 base::ThreadChecker main_thread_checker_;
172 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
173 TaskQueueSelector* selector_;
175 base::WeakPtr<TaskQueueManager> task_queue_manager_weak_ptr_;
177 // The pending_dowork_count_ is only tracked on the main thread since that's
178 // where re-entrant problems happen.
179 int pending_dowork_count_;
181 int work_batch_size_;
183 scoped_refptr<cc::TestNowSource> time_source_;
185 ObserverList<base::MessageLoop::TaskObserver> task_observers_;
187 base::WeakPtrFactory<TaskQueueManager> weak_factory_;
189 DISALLOW_COPY_AND_ASSIGN(TaskQueueManager);
192 } // namespace content
194 #endif // CONTENT_RENDERER_SCHEDULER_TASK_QUEUE_MANAGER_H_