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

Side by Side Diff: components/scheduler/base/task_queue_impl.h

Issue 2118903002: scheduler: Move the Blink scheduler into Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 4 years, 4 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 | « components/scheduler/base/task_queue.h ('k') | components/scheduler/base/task_queue_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #ifndef CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
6 #define CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
7
8 #include <stddef.h>
9
10 #include <memory>
11 #include <set>
12
13 #include "base/macros.h"
14 #include "base/pending_task.h"
15 #include "base/threading/thread_checker.h"
16 #include "base/trace_event/trace_event.h"
17 #include "base/trace_event/trace_event_argument.h"
18 #include "components/scheduler/base/enqueue_order.h"
19 #include "components/scheduler/base/task_queue.h"
20 #include "components/scheduler/scheduler_export.h"
21
22 namespace scheduler {
23 class LazyNow;
24 class TimeDomain;
25 class TaskQueueManager;
26
27 namespace internal {
28 class WorkQueue;
29 class WorkQueueSets;
30
31 class SCHEDULER_EXPORT TaskQueueImpl final : public TaskQueue {
32 public:
33 TaskQueueImpl(TaskQueueManager* task_queue_manager,
34 TimeDomain* time_domain,
35 const Spec& spec,
36 const char* disabled_by_default_tracing_category,
37 const char* disabled_by_default_verbose_tracing_category);
38
39 class SCHEDULER_EXPORT Task : public base::PendingTask {
40 public:
41 Task();
42 Task(const tracked_objects::Location& posted_from,
43 const base::Closure& task,
44 base::TimeTicks desired_run_time,
45 EnqueueOrder sequence_number,
46 bool nestable);
47
48 Task(const tracked_objects::Location& posted_from,
49 const base::Closure& task,
50 base::TimeTicks desired_run_time,
51 EnqueueOrder sequence_number,
52 bool nestable,
53 EnqueueOrder enqueue_order);
54
55 EnqueueOrder enqueue_order() const {
56 #ifndef NDEBUG
57 DCHECK(enqueue_order_set_);
58 #endif
59 return enqueue_order_;
60 }
61
62 void set_enqueue_order(EnqueueOrder enqueue_order) {
63 #ifndef NDEBUG
64 DCHECK(!enqueue_order_set_);
65 enqueue_order_set_ = true;
66 #endif
67 enqueue_order_ = enqueue_order;
68 }
69
70 #ifndef NDEBUG
71 bool enqueue_order_set() const { return enqueue_order_set_; }
72 #endif
73
74 private:
75 #ifndef NDEBUG
76 bool enqueue_order_set_;
77 #endif
78 // Similar to sequence number, but the |enqueue_order| is set by
79 // EnqueueTasksLocked and is not initially defined for delayed tasks until
80 // they are enqueued on the |immediate_incoming_queue_|.
81 EnqueueOrder enqueue_order_;
82 };
83
84 // TaskQueue implementation.
85 void UnregisterTaskQueue() override;
86 bool RunsTasksOnCurrentThread() const override;
87 bool PostDelayedTask(const tracked_objects::Location& from_here,
88 const base::Closure& task,
89 base::TimeDelta delay) override;
90 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
91 const base::Closure& task,
92 base::TimeDelta delay) override;
93
94 void SetQueueEnabled(bool enabled) override;
95 bool IsQueueEnabled() const override;
96 bool IsEmpty() const override;
97 bool HasPendingImmediateWork() const override;
98 bool NeedsPumping() const override;
99 void SetQueuePriority(QueuePriority priority) override;
100 QueuePriority GetQueuePriority() const override;
101 void PumpQueue(LazyNow* lazy_now, bool may_post_dowork) override;
102 void SetPumpPolicy(PumpPolicy pump_policy) override;
103 PumpPolicy GetPumpPolicy() const override;
104 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
105 void RemoveTaskObserver(
106 base::MessageLoop::TaskObserver* task_observer) override;
107 void SetTimeDomain(TimeDomain* time_domain) override;
108 TimeDomain* GetTimeDomain() const override;
109 void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
110
111 void UpdateImmediateWorkQueue(bool should_trigger_wakeup,
112 const Task* previous_task);
113 void UpdateDelayedWorkQueue(LazyNow* lazy_now,
114 bool should_trigger_wakeup,
115 const Task* previous_task);
116
117 WakeupPolicy wakeup_policy() const {
118 DCHECK(main_thread_checker_.CalledOnValidThread());
119 return wakeup_policy_;
120 }
121
122 const char* GetName() const override;
123
124 void AsValueInto(base::trace_event::TracedValue* state) const;
125
126 bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; }
127 bool GetShouldNotifyObservers() const {
128 return should_notify_observers_;
129 }
130
131 void NotifyWillProcessTask(const base::PendingTask& pending_task);
132 void NotifyDidProcessTask(const base::PendingTask& pending_task);
133
134 // Can be called on any thread.
135 static const char* PumpPolicyToString(TaskQueue::PumpPolicy pump_policy);
136
137 // Can be called on any thread.
138 static const char* WakeupPolicyToString(
139 TaskQueue::WakeupPolicy wakeup_policy);
140
141 // Can be called on any thread.
142 static const char* PriorityToString(TaskQueue::QueuePriority priority);
143
144 WorkQueue* delayed_work_queue() {
145 return main_thread_only().delayed_work_queue.get();
146 }
147
148 const WorkQueue* delayed_work_queue() const {
149 return main_thread_only().delayed_work_queue.get();
150 }
151
152 WorkQueue* immediate_work_queue() {
153 return main_thread_only().immediate_work_queue.get();
154 }
155
156 const WorkQueue* immediate_work_queue() const {
157 return main_thread_only().immediate_work_queue.get();
158 }
159
160 bool should_report_when_execution_blocked() const {
161 return should_report_when_execution_blocked_;
162 }
163
164 private:
165 friend class WorkQueue;
166
167 enum class TaskType {
168 NORMAL,
169 NON_NESTABLE,
170 };
171
172 struct AnyThread {
173 AnyThread(TaskQueueManager* task_queue_manager,
174 PumpPolicy pump_policy,
175 TimeDomain* time_domain);
176 ~AnyThread();
177
178 // TaskQueueManager, PumpPolicy and TimeDomain are maintained in two copies:
179 // inside AnyThread and inside MainThreadOnly. They can be changed only from
180 // main thread, so it should be locked before accessing from other threads.
181 TaskQueueManager* task_queue_manager;
182 PumpPolicy pump_policy;
183 TimeDomain* time_domain;
184
185 std::queue<Task> immediate_incoming_queue;
186 };
187
188 struct MainThreadOnly {
189 MainThreadOnly(TaskQueueManager* task_queue_manager,
190 PumpPolicy pump_policy,
191 TaskQueueImpl* task_queue,
192 TimeDomain* time_domain);
193 ~MainThreadOnly();
194
195 // Another copy of TaskQueueManager, PumpPolicy and TimeDomain for lock-free
196 // access from the main thread. See description inside struct AnyThread for
197 // details.
198 TaskQueueManager* task_queue_manager;
199 PumpPolicy pump_policy;
200 TimeDomain* time_domain;
201
202 std::unique_ptr<WorkQueue> delayed_work_queue;
203 std::unique_ptr<WorkQueue> immediate_work_queue;
204 std::priority_queue<Task> delayed_incoming_queue;
205 base::ObserverList<base::MessageLoop::TaskObserver> task_observers;
206 size_t set_index;
207 bool is_enabled;
208 base::trace_event::BlameContext* blame_context; // Not owned.
209 };
210
211 ~TaskQueueImpl() override;
212
213 bool PostImmediateTaskImpl(const tracked_objects::Location& from_here,
214 const base::Closure& task,
215 TaskType task_type);
216 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
217 const base::Closure& task,
218 base::TimeDelta delay,
219 TaskType task_type);
220
221 // Push the task onto the |delayed_incoming_queue|. Lock-free main thread
222 // only fast path.
223 void PushOntoDelayedIncomingQueueFromMainThread(Task pending_task,
224 base::TimeTicks now);
225
226 // Push the task onto the |delayed_incoming_queue|. Slow path from other
227 // threads.
228 void PushOntoDelayedIncomingQueueLocked(Task pending_task);
229
230 void ScheduleDelayedWorkTask(Task pending_task);
231
232 // Enqueues any delayed tasks which should be run now on the
233 // |delayed_work_queue|. Must be called from the main thread.
234 void MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now);
235
236 void MoveReadyImmediateTasksToImmediateWorkQueueLocked();
237
238 // Note this does nothing if its not called from the main thread.
239 void PumpQueueLocked(LazyNow* lazy_now, bool may_post_dowork);
240
241 // Returns true if |task| is older than the oldest incoming immediate task.
242 // NOTE |any_thread_lock_| must be locked.
243 bool TaskIsOlderThanQueuedImmediateTasksLocked(const Task* task);
244
245 // Returns true if |task| is older than the oldest delayed task. Must be
246 // called from the main thread.
247 bool TaskIsOlderThanQueuedDelayedTasks(const Task* task);
248
249 // NOTE |any_thread_lock_| must be locked.
250 bool ShouldAutoPumpImmediateQueueLocked(bool should_trigger_wakeup,
251 const Task* previous_task);
252
253 // Must be called from the main thread.
254 bool ShouldAutoPumpDelayedQueue(bool should_trigger_wakeup,
255 const Task* previous_task);
256
257 // Push the task onto the |immediate_incoming_queue| and for auto pumped
258 // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was
259 // empty.
260 void PushOntoImmediateIncomingQueueLocked(Task pending_task);
261
262 void TraceQueueSize(bool is_locked) const;
263 static void QueueAsValueInto(const std::queue<Task>& queue,
264 base::trace_event::TracedValue* state);
265 static void QueueAsValueInto(const std::priority_queue<Task>& queue,
266 base::trace_event::TracedValue* state);
267 static void TaskAsValueInto(const Task& task,
268 base::trace_event::TracedValue* state);
269
270 const base::PlatformThreadId thread_id_;
271
272 mutable base::Lock any_thread_lock_;
273 AnyThread any_thread_;
274 struct AnyThread& any_thread() {
275 any_thread_lock_.AssertAcquired();
276 return any_thread_;
277 }
278 const struct AnyThread& any_thread() const {
279 any_thread_lock_.AssertAcquired();
280 return any_thread_;
281 }
282
283 const char* name_;
284 const char* disabled_by_default_tracing_category_;
285 const char* disabled_by_default_verbose_tracing_category_;
286
287 base::ThreadChecker main_thread_checker_;
288 MainThreadOnly main_thread_only_;
289 MainThreadOnly& main_thread_only() {
290 DCHECK(main_thread_checker_.CalledOnValidThread());
291 return main_thread_only_;
292 }
293 const MainThreadOnly& main_thread_only() const {
294 DCHECK(main_thread_checker_.CalledOnValidThread());
295 return main_thread_only_;
296 }
297
298 const WakeupPolicy wakeup_policy_;
299 const bool should_monitor_quiescence_;
300 const bool should_notify_observers_;
301 const bool should_report_when_execution_blocked_;
302
303 DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
304 };
305
306 } // namespace internal
307 } // namespace scheduler
308
309 #endif // CONTENT_RENDERER_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
OLDNEW
« no previous file with comments | « components/scheduler/base/task_queue.h ('k') | components/scheduler/base/task_queue_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698