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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h

Issue 2812703002: Revert of [scheduler] Add TaskQueue::Observer (Closed)
Patch Set: Manual Revert Created 3 years, 8 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 THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_ 5 #ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_ 6 #define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 28 matching lines...) Expand all
39 // 39 //
40 // Delayed tasks 40 // Delayed tasks
41 // delayed_incoming_queue - PostDelayedTask enqueues tasks here 41 // delayed_incoming_queue - PostDelayedTask enqueues tasks here
42 // delayed_work_queue 42 // delayed_work_queue
43 // 43 //
44 // The immediate_incoming_queue can be accessed from any thread, the other 44 // The immediate_incoming_queue can be accessed from any thread, the other
45 // queues are main-thread only. To reduce the overhead of locking, 45 // queues are main-thread only. To reduce the overhead of locking,
46 // immediate_work_queue is swapped with immediate_incoming_queue when 46 // immediate_work_queue is swapped with immediate_incoming_queue when
47 // immediate_work_queue becomes empty. 47 // immediate_work_queue becomes empty.
48 // 48 //
49 // Delayed tasks are initially posted to delayed_incoming_queue and a wake-up 49 // Delayed tasks are initially posted to delayed_incoming_queue and a wakeup
50 // is scheduled with the TimeDomain. When the delay has elapsed, the TimeDomain 50 // is scheduled with the TimeDomain. When the delay has elapsed, the TimeDomain
51 // calls UpdateDelayedWorkQueue and ready delayed tasks are moved into the 51 // calls UpdateDelayedWorkQueue and ready delayed tasks are moved into the
52 // delayed_work_queue. Note the EnqueueOrder (used for ordering) for a delayed 52 // delayed_work_queue. Note the EnqueueOrder (used for ordering) for a delayed
53 // task is not set until it's moved into the delayed_work_queue. 53 // task is not set until it's moved into the delayed_work_queue.
54 // 54 //
55 // TaskQueueImpl uses the WorkQueueSets and the TaskQueueSelector to implement 55 // TaskQueueImpl uses the WorkQueueSets and the TaskQueueSelector to implement
56 // prioritization. Task selection is done by the TaskQueueSelector and when a 56 // prioritization. Task selection is done by the TaskQueueSelector and when a
57 // queue is selected, it round-robins between the immediate_work_queue and 57 // queue is selected, it round-robins between the immediate_work_queue and
58 // delayed_work_queue. The reason for this is we want to make sure delayed 58 // delayed_work_queue. The reason for this is we want to make sure delayed
59 // tasks (normally the most common type) don't starve out immediate work. 59 // tasks (normally the most common type) don't starve out immediate work.
60 class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue { 60 class BLINK_PLATFORM_EXPORT TaskQueueImpl final : public TaskQueue {
61 public: 61 public:
62 TaskQueueImpl(TaskQueueManager* task_queue_manager, 62 TaskQueueImpl(TaskQueueManager* task_queue_manager,
63 TimeDomain* time_domain, 63 TimeDomain* time_domain,
64 const Spec& spec, 64 const Spec& spec,
65 const char* disabled_by_default_tracing_category, 65 const char* disabled_by_default_tracing_category,
66 const char* disabled_by_default_verbose_tracing_category); 66 const char* disabled_by_default_verbose_tracing_category);
67 67
68 // Represents a time at which a task wants to run. Tasks scheduled for the
69 // same point in time will be ordered by their sequence numbers.
70 struct DelayedWakeUp {
71 base::TimeTicks time;
72 int sequence_num;
73
74 bool operator<=(const DelayedWakeUp& other) const {
75 if (time == other.time) {
76 DCHECK_NE(sequence_num, other.sequence_num);
77 return (sequence_num - other.sequence_num) < 0;
78 }
79 return time < other.time;
80 }
81 };
82
83 class BLINK_PLATFORM_EXPORT Task : public base::PendingTask { 68 class BLINK_PLATFORM_EXPORT Task : public base::PendingTask {
84 public: 69 public:
85 Task(); 70 Task();
86 Task(const tracked_objects::Location& posted_from, 71 Task(const tracked_objects::Location& posted_from,
87 base::OnceClosure task, 72 base::OnceClosure task,
88 base::TimeTicks desired_run_time, 73 base::TimeTicks desired_run_time,
89 EnqueueOrder sequence_number, 74 EnqueueOrder sequence_number,
90 bool nestable); 75 bool nestable);
91 76
92 Task(const tracked_objects::Location& posted_from, 77 Task(const tracked_objects::Location& posted_from,
93 base::OnceClosure task, 78 base::OnceClosure task,
94 base::TimeTicks desired_run_time, 79 base::TimeTicks desired_run_time,
95 EnqueueOrder sequence_number, 80 EnqueueOrder sequence_number,
96 bool nestable, 81 bool nestable,
97 EnqueueOrder enqueue_order); 82 EnqueueOrder enqueue_order);
98 83
99 DelayedWakeUp delayed_wake_up() const {
100 return DelayedWakeUp{delayed_run_time, sequence_num};
101 }
102
103 EnqueueOrder enqueue_order() const { 84 EnqueueOrder enqueue_order() const {
104 #ifndef NDEBUG 85 #ifndef NDEBUG
105 DCHECK(enqueue_order_set_); 86 DCHECK(enqueue_order_set_);
106 #endif 87 #endif
107 return enqueue_order_; 88 return enqueue_order_;
108 } 89 }
109 90
110 void set_enqueue_order(EnqueueOrder enqueue_order) { 91 void set_enqueue_order(EnqueueOrder enqueue_order) {
111 #ifndef NDEBUG 92 #ifndef NDEBUG
112 DCHECK(!enqueue_order_set_); 93 DCHECK(!enqueue_order_set_);
(...skipping 11 matching lines...) Expand all
124 bool enqueue_order_set_; 105 bool enqueue_order_set_;
125 #endif 106 #endif
126 // Similar to sequence number, but ultimately the |enqueue_order_| is what 107 // Similar to sequence number, but ultimately the |enqueue_order_| is what
127 // the scheduler uses for task ordering. For immediate tasks |enqueue_order| 108 // the scheduler uses for task ordering. For immediate tasks |enqueue_order|
128 // is set when posted, but for delayed tasks it's not defined until they are 109 // is set when posted, but for delayed tasks it's not defined until they are
129 // enqueued on the |delayed_work_queue_|. This is because otherwise delayed 110 // enqueued on the |delayed_work_queue_|. This is because otherwise delayed
130 // tasks could run before an immediate task posted after the delayed task. 111 // tasks could run before an immediate task posted after the delayed task.
131 EnqueueOrder enqueue_order_; 112 EnqueueOrder enqueue_order_;
132 }; 113 };
133 114
115 // Represents a time at which a task wants to run. Tasks scheduled for the
116 // same point in time will be ordered by their sequence numbers.
117 struct DelayedWakeUp {
118 base::TimeTicks time;
119 int sequence_num;
120
121 bool operator<=(const DelayedWakeUp& other) const {
122 if (time == other.time) {
123 DCHECK_NE(sequence_num, other.sequence_num);
124 return (sequence_num - other.sequence_num) < 0;
125 }
126 return time < other.time;
127 }
128 };
129
134 // TaskQueue implementation. 130 // TaskQueue implementation.
135 void UnregisterTaskQueue() override; 131 void UnregisterTaskQueue() override;
136 bool RunsTasksOnCurrentThread() const override; 132 bool RunsTasksOnCurrentThread() const override;
137 bool PostDelayedTask(const tracked_objects::Location& from_here, 133 bool PostDelayedTask(const tracked_objects::Location& from_here,
138 base::OnceClosure task, 134 base::OnceClosure task,
139 base::TimeDelta delay) override; 135 base::TimeDelta delay) override;
140 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, 136 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
141 base::OnceClosure task, 137 base::OnceClosure task,
142 base::TimeDelta delay) override; 138 base::TimeDelta delay) override;
143 std::unique_ptr<QueueEnabledVoter> CreateQueueEnabledVoter() override; 139 std::unique_ptr<QueueEnabledVoter> CreateQueueEnabledVoter() override;
144 bool IsQueueEnabled() const override; 140 bool IsQueueEnabled() const override;
145 bool IsEmpty() const override; 141 bool IsEmpty() const override;
146 size_t GetNumberOfPendingTasks() const override; 142 size_t GetNumberOfPendingTasks() const override;
147 bool HasPendingImmediateWork() const override; 143 bool HasPendingImmediateWork() const override;
148 base::Optional<base::TimeTicks> GetNextScheduledWakeUp() override; 144 base::Optional<base::TimeTicks> GetNextScheduledWakeUp() override;
149 void SetQueuePriority(QueuePriority priority) override; 145 void SetQueuePriority(QueuePriority priority) override;
150 QueuePriority GetQueuePriority() const override; 146 QueuePriority GetQueuePriority() const override;
151 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; 147 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
152 void RemoveTaskObserver( 148 void RemoveTaskObserver(
153 base::MessageLoop::TaskObserver* task_observer) override; 149 base::MessageLoop::TaskObserver* task_observer) override;
154 void SetTimeDomain(TimeDomain* time_domain) override; 150 void SetTimeDomain(TimeDomain* time_domain) override;
155 TimeDomain* GetTimeDomain() const override; 151 TimeDomain* GetTimeDomain() const override;
156 void SetBlameContext(base::trace_event::BlameContext* blame_context) override; 152 void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
157 void InsertFence(InsertFencePosition position) override; 153 void InsertFence(InsertFencePosition position) override;
158 void RemoveFence() override; 154 void RemoveFence() override;
159 bool BlockedByFence() const override; 155 bool BlockedByFence() const override;
160 const char* GetName() const override; 156 const char* GetName() const override;
161 QueueType GetQueueType() const override; 157 QueueType GetQueueType() const override;
162 void SetObserver(Observer* observer) override;
163 158
164 // Returns true if a (potentially hypothetical) task with the specified 159 // Returns true if a (potentially hypothetical) task with the specified
165 // |enqueue_order| could run on the queue. Must be called from the main 160 // |enqueue_order| could run on the queue. Must be called from the main
166 // thread. 161 // thread.
167 bool CouldTaskRun(EnqueueOrder enqueue_order) const; 162 bool CouldTaskRun(EnqueueOrder enqueue_order) const;
168 163
169 // Must only be called from the thread this task queue was created on. 164 // Must only be called from the thread this task queue was created on.
170 void ReloadImmediateWorkQueueIfEmpty(); 165 void ReloadImmediateWorkQueueIfEmpty();
171 166
172 void AsValueInto(base::trace_event::TracedValue* state) const; 167 void AsValueInto(base::trace_event::TracedValue* state) const;
(...skipping 18 matching lines...) Expand all
191 186
192 const WorkQueue* immediate_work_queue() const { 187 const WorkQueue* immediate_work_queue() const {
193 return main_thread_only().immediate_work_queue.get(); 188 return main_thread_only().immediate_work_queue.get();
194 } 189 }
195 190
196 bool should_report_when_execution_blocked() const { 191 bool should_report_when_execution_blocked() const {
197 return should_report_when_execution_blocked_; 192 return should_report_when_execution_blocked_;
198 } 193 }
199 194
200 // Enqueues any delayed tasks which should be run now on the 195 // Enqueues any delayed tasks which should be run now on the
201 // |delayed_work_queue|. Returns the subsequent wake-up that is required, if 196 // |delayed_work_queue|. Returns the subsequent wakeup that is required, if
202 // any. Must be called from the main thread. 197 // any. Must be called from the main thread.
203 base::Optional<DelayedWakeUp> WakeUpForDelayedWork(LazyNow* lazy_now); 198 base::Optional<DelayedWakeUp> WakeUpForDelayedWork(LazyNow* lazy_now);
204 199
205 base::TimeTicks scheduled_time_domain_wake_up() const { 200 base::TimeTicks scheduled_time_domain_wakeup() const {
206 return main_thread_only().scheduled_time_domain_wake_up; 201 return main_thread_only().scheduled_time_domain_wakeup;
207 } 202 }
208 203
209 void set_scheduled_time_domain_wake_up( 204 void set_scheduled_time_domain_wakeup(
210 base::TimeTicks scheduled_time_domain_wake_up) { 205 base::TimeTicks scheduled_time_domain_wakeup) {
211 main_thread_only().scheduled_time_domain_wake_up = 206 main_thread_only().scheduled_time_domain_wakeup =
212 scheduled_time_domain_wake_up; 207 scheduled_time_domain_wakeup;
213 } 208 }
214 209
215 HeapHandle heap_handle() const { return main_thread_only().heap_handle; } 210 HeapHandle heap_handle() const { return main_thread_only().heap_handle; }
216 211
217 void set_heap_handle(HeapHandle heap_handle) { 212 void set_heap_handle(HeapHandle heap_handle) {
218 main_thread_only().heap_handle = heap_handle; 213 main_thread_only().heap_handle = heap_handle;
219 } 214 }
220 215
221 void PushImmediateIncomingTaskForTest(TaskQueueImpl::Task&& task); 216 void PushImmediateIncomingTaskForTest(TaskQueueImpl::Task&& task);
222 EnqueueOrder GetFenceForTest() const; 217 EnqueueOrder GetFenceForTest() const;
(...skipping 24 matching lines...) Expand all
247 242
248 enum class TaskType { 243 enum class TaskType {
249 NORMAL, 244 NORMAL,
250 NON_NESTABLE, 245 NON_NESTABLE,
251 }; 246 };
252 247
253 struct AnyThread { 248 struct AnyThread {
254 AnyThread(TaskQueueManager* task_queue_manager, TimeDomain* time_domain); 249 AnyThread(TaskQueueManager* task_queue_manager, TimeDomain* time_domain);
255 ~AnyThread(); 250 ~AnyThread();
256 251
257 // TaskQueueManager, TimeDomain and Observer are maintained in two copies: 252 // TaskQueueManager and TimeDomain are maintained in two copies:
258 // inside AnyThread and inside MainThreadOnly. They can be changed only from 253 // inside AnyThread and inside MainThreadOnly. They can be changed only from
259 // main thread, so it should be locked before accessing from other threads. 254 // main thread, so it should be locked before accessing from other threads.
260 TaskQueueManager* task_queue_manager; 255 TaskQueueManager* task_queue_manager;
261 TimeDomain* time_domain; 256 TimeDomain* time_domain;
262 Observer* observer;
263 }; 257 };
264 258
265 struct MainThreadOnly { 259 struct MainThreadOnly {
266 MainThreadOnly(TaskQueueManager* task_queue_manager, 260 MainThreadOnly(TaskQueueManager* task_queue_manager,
267 TaskQueueImpl* task_queue, 261 TaskQueueImpl* task_queue,
268 TimeDomain* time_domain); 262 TimeDomain* time_domain);
269 ~MainThreadOnly(); 263 ~MainThreadOnly();
270 264
271 // Another copy of TaskQueueManager, TimeDomain and Observer 265 // Another copy of TaskQueueManager and TimeDomain for lock-free access from
272 // for lock-free access from the main thread. 266 // the main thread. See description inside struct AnyThread for details.
273 // See description inside struct AnyThread for details.
274 TaskQueueManager* task_queue_manager; 267 TaskQueueManager* task_queue_manager;
275 TimeDomain* time_domain; 268 TimeDomain* time_domain;
276 Observer* observer;
277 269
278 std::unique_ptr<WorkQueue> delayed_work_queue; 270 std::unique_ptr<WorkQueue> delayed_work_queue;
279 std::unique_ptr<WorkQueue> immediate_work_queue; 271 std::unique_ptr<WorkQueue> immediate_work_queue;
280 std::priority_queue<Task> delayed_incoming_queue; 272 std::priority_queue<Task> delayed_incoming_queue;
281 base::ObserverList<base::MessageLoop::TaskObserver> task_observers; 273 base::ObserverList<base::MessageLoop::TaskObserver> task_observers;
282 size_t set_index; 274 size_t set_index;
283 HeapHandle heap_handle; 275 HeapHandle heap_handle;
284 int is_enabled_refcount; 276 int is_enabled_refcount;
285 int voter_refcount; 277 int voter_refcount;
286 base::trace_event::BlameContext* blame_context; // Not owned. 278 base::trace_event::BlameContext* blame_context; // Not owned.
287 EnqueueOrder current_fence; 279 EnqueueOrder current_fence;
288 base::TimeTicks scheduled_time_domain_wake_up; 280 base::TimeTicks scheduled_time_domain_wakeup;
289 }; 281 };
290 282
291 ~TaskQueueImpl() override; 283 ~TaskQueueImpl() override;
292 284
293 bool PostImmediateTaskImpl(const tracked_objects::Location& from_here, 285 bool PostImmediateTaskImpl(const tracked_objects::Location& from_here,
294 base::OnceClosure task, 286 base::OnceClosure task,
295 TaskType task_type); 287 TaskType task_type);
296 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here, 288 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
297 base::OnceClosure task, 289 base::OnceClosure task,
298 base::TimeDelta delay, 290 base::TimeDelta delay,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 base::trace_event::TracedValue* state); 322 base::trace_event::TracedValue* state);
331 static void QueueAsValueInto(const std::priority_queue<Task>& queue, 323 static void QueueAsValueInto(const std::priority_queue<Task>& queue,
332 base::trace_event::TracedValue* state); 324 base::trace_event::TracedValue* state);
333 static void TaskAsValueInto(const Task& task, 325 static void TaskAsValueInto(const Task& task,
334 base::trace_event::TracedValue* state); 326 base::trace_event::TracedValue* state);
335 327
336 void RemoveQueueEnabledVoter(const QueueEnabledVoterImpl* voter); 328 void RemoveQueueEnabledVoter(const QueueEnabledVoterImpl* voter);
337 void OnQueueEnabledVoteChanged(bool enabled); 329 void OnQueueEnabledVoteChanged(bool enabled);
338 void EnableOrDisableWithSelector(bool enable); 330 void EnableOrDisableWithSelector(bool enable);
339 331
340 // Schedules delayed work on time domain and calls the observer.
341 void ScheduleDelayedWorkInTimeDomain(base::TimeTicks now);
342
343 void NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up);
344
345 const base::PlatformThreadId thread_id_; 332 const base::PlatformThreadId thread_id_;
346 333
347 mutable base::Lock any_thread_lock_; 334 mutable base::Lock any_thread_lock_;
348 AnyThread any_thread_; 335 AnyThread any_thread_;
349 struct AnyThread& any_thread() { 336 struct AnyThread& any_thread() {
350 any_thread_lock_.AssertAcquired(); 337 any_thread_lock_.AssertAcquired();
351 return any_thread_; 338 return any_thread_;
352 } 339 }
353 const struct AnyThread& any_thread() const { 340 const struct AnyThread& any_thread() const {
354 any_thread_lock_.AssertAcquired(); 341 any_thread_lock_.AssertAcquired();
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 const bool should_report_when_execution_blocked_; 374 const bool should_report_when_execution_blocked_;
388 375
389 DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl); 376 DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
390 }; 377 };
391 378
392 } // namespace internal 379 } // namespace internal
393 } // namespace scheduler 380 } // namespace scheduler
394 } // namespace blink 381 } // namespace blink
395 382
396 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_ 383 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698