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

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

Issue 2326313003: Revert of Make canceling Timers fast. (Closed)
Patch Set: Created 4 years, 3 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 EnqueueOrder sequence_number, 71 EnqueueOrder sequence_number,
72 bool nestable); 72 bool nestable);
73 73
74 Task(const tracked_objects::Location& posted_from, 74 Task(const tracked_objects::Location& posted_from,
75 const base::Closure& task, 75 const base::Closure& task,
76 base::TimeTicks desired_run_time, 76 base::TimeTicks desired_run_time,
77 EnqueueOrder sequence_number, 77 EnqueueOrder sequence_number,
78 bool nestable, 78 bool nestable,
79 EnqueueOrder enqueue_order); 79 EnqueueOrder enqueue_order);
80 80
81 // Create a fake Task based on the handle, suitable for using as a search
82 // key.
83 static Task CreateFakeTaskFromHandle(const TaskHandle& handle);
84
81 EnqueueOrder enqueue_order() const { 85 EnqueueOrder enqueue_order() const {
82 #ifndef NDEBUG 86 #ifndef NDEBUG
83 DCHECK(enqueue_order_set_); 87 DCHECK(enqueue_order_set_);
84 #endif 88 #endif
85 return enqueue_order_; 89 return enqueue_order_;
86 } 90 }
87 91
88 void set_enqueue_order(EnqueueOrder enqueue_order) { 92 void set_enqueue_order(EnqueueOrder enqueue_order) {
89 #ifndef NDEBUG 93 #ifndef NDEBUG
90 DCHECK(!enqueue_order_set_); 94 DCHECK(!enqueue_order_set_);
91 enqueue_order_set_ = true; 95 enqueue_order_set_ = true;
92 #endif 96 #endif
93 enqueue_order_ = enqueue_order; 97 enqueue_order_ = enqueue_order;
94 } 98 }
95 99
96 #ifndef NDEBUG 100 #ifndef NDEBUG
97 bool enqueue_order_set() const { return enqueue_order_set_; } 101 bool enqueue_order_set() const { return enqueue_order_set_; }
98 #endif 102 #endif
99 103
104 using ComparatorFn = bool (*)(const Task&, const Task&);
105
106 // Tasks are ordered by |delayed_run_time| smallest first then and by
107 // |sequence_num| in case of a tie.
108 class DelayedRunTimeComparator {
109 public:
110 bool operator()(const Task& a, const Task& b) const;
111 };
112
113 // Tasks are ordered by |enqueue_order_| smallest first.
114 static bool EnqueueOrderComparatorFn(const TaskQueueImpl::Task& a,
115 const TaskQueueImpl::Task& b);
116
117 // Tasks are ordered by |delayed_run_time| smallest first then and by
118 // |sequence_num| in case of a tie.
119 static bool DelayedRunTimeComparatorFn(const TaskQueueImpl::Task& a,
120 const TaskQueueImpl::Task& b);
121
100 private: 122 private:
101 #ifndef NDEBUG 123 #ifndef NDEBUG
102 bool enqueue_order_set_; 124 bool enqueue_order_set_;
103 #endif 125 #endif
104 // Similar to sequence number, but ultimately the |enqueue_order_| is what 126 // Similar to sequence number, but ultimately the |enqueue_order_| is what
105 // the scheduler uses for task ordering. For immediate tasks |enqueue_order| 127 // the scheduler uses for task ordering. For immediate tasks |enqueue_order|
106 // is set when posted, but for delayed tasks it's not defined until they are 128 // is set when posted, but for delayed tasks it's not defined until they are
107 // enqueued on the |delayed_work_queue_|. This is because otherwise delayed 129 // enqueued on the |delayed_work_queue_|. This is because otherwise delayed
108 // tasks could run before an immediate task posted after the delayed task. 130 // tasks could run before an immediate task posted after the delayed task.
109 EnqueueOrder enqueue_order_; 131 EnqueueOrder enqueue_order_;
110 }; 132 };
111 133
112 // TaskQueue implementation. 134 // TaskQueue implementation.
113 void UnregisterTaskQueue() override; 135 void UnregisterTaskQueue() override;
114 bool RunsTasksOnCurrentThread() const override; 136 bool RunsTasksOnCurrentThread() const override;
115 bool PostDelayedTask(const tracked_objects::Location& from_here, 137 bool PostDelayedTask(const tracked_objects::Location& from_here,
116 const base::Closure& task, 138 const base::Closure& task,
117 base::TimeDelta delay) override; 139 base::TimeDelta delay) override;
118 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, 140 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
119 const base::Closure& task, 141 const base::Closure& task,
120 base::TimeDelta delay) override; 142 base::TimeDelta delay) override;
143 TaskHandle PostCancellableDelayedTask(
144 const tracked_objects::Location& from_here,
145 const base::Closure& task,
146 base::TimeDelta delay) override;
147 bool CancelTask(const TaskHandle& handle) override;
121 void SetQueueEnabled(bool enabled) override; 148 void SetQueueEnabled(bool enabled) override;
122 bool IsQueueEnabled() const override; 149 bool IsQueueEnabled() const override;
123 bool IsEmpty() const override; 150 bool IsEmpty() const override;
124 bool HasPendingImmediateWork() const override; 151 bool HasPendingImmediateWork() const override;
125 void SetQueuePriority(QueuePriority priority) override; 152 void SetQueuePriority(QueuePriority priority) override;
126 QueuePriority GetQueuePriority() const override; 153 QueuePriority GetQueuePriority() const override;
127 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; 154 void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override;
128 void RemoveTaskObserver( 155 void RemoveTaskObserver(
129 base::MessageLoop::TaskObserver* task_observer) override; 156 base::MessageLoop::TaskObserver* task_observer) override;
130 void SetTimeDomain(TimeDomain* time_domain) override; 157 void SetTimeDomain(TimeDomain* time_domain) override;
131 TimeDomain* GetTimeDomain() const override; 158 TimeDomain* GetTimeDomain() const override;
132 void SetBlameContext(base::trace_event::BlameContext* blame_context) override; 159 void SetBlameContext(base::trace_event::BlameContext* blame_context) override;
133 void InsertFence() override; 160 void InsertFence() override;
134 void RemoveFence() override; 161 void RemoveFence() override;
135 bool BlockedByFence() const override; 162 bool BlockedByFence() const override;
136 163
137 // If this returns false then future updates for this queue are not needed 164 bool IsTaskPending(const TaskHandle& handle) const;
138 // unless requested. 165
139 bool MaybeUpdateImmediateWorkQueues(); 166 void UpdateImmediateWorkQueue();
167 void UpdateDelayedWorkQueue(LazyNow* lazy_now);
140 168
141 const char* GetName() const override; 169 const char* GetName() const override;
142 170
143 void AsValueInto(base::trace_event::TracedValue* state) const; 171 void AsValueInto(base::trace_event::TracedValue* state) const;
144 172
145 bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; } 173 bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; }
146 bool GetShouldNotifyObservers() const { return should_notify_observers_; } 174 bool GetShouldNotifyObservers() const { return should_notify_observers_; }
147 175
148 void NotifyWillProcessTask(const base::PendingTask& pending_task); 176 void NotifyWillProcessTask(const base::PendingTask& pending_task);
149 void NotifyDidProcessTask(const base::PendingTask& pending_task); 177 void NotifyDidProcessTask(const base::PendingTask& pending_task);
(...skipping 14 matching lines...) Expand all
164 } 192 }
165 193
166 const WorkQueue* immediate_work_queue() const { 194 const WorkQueue* immediate_work_queue() const {
167 return main_thread_only().immediate_work_queue.get(); 195 return main_thread_only().immediate_work_queue.get();
168 } 196 }
169 197
170 bool should_report_when_execution_blocked() const { 198 bool should_report_when_execution_blocked() const {
171 return should_report_when_execution_blocked_; 199 return should_report_when_execution_blocked_;
172 } 200 }
173 201
174 // Enqueues any delayed tasks which should be run now on the
175 // |delayed_work_queue|. Must be called from the main thread.
176 void MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now);
177
178 private: 202 private:
179 friend class WorkQueue; 203 friend class WorkQueue;
180 friend class WorkQueueTest; 204 friend class WorkQueueTest;
181 205
206 // Note both DelayedRunTimeQueue and ComparatorQueue are sets for fast task
207 // cancellation. Typically queue sizes are well under 200 so the overhead of
208 // std::set vs std::priority_queue and std::queue is lost in the noise of
209 // everything else.
210 using DelayedRunTimeQueue = std::set<Task, Task::DelayedRunTimeComparator>;
211 using ComparatorQueue = std::set<Task, Task::ComparatorFn>;
212
182 enum class TaskType { 213 enum class TaskType {
183 NORMAL, 214 NORMAL,
184 NON_NESTABLE, 215 NON_NESTABLE,
185 }; 216 };
186 217
187 struct AnyThread { 218 struct AnyThread {
188 AnyThread(TaskQueueManager* task_queue_manager, 219 AnyThread(TaskQueueManager* task_queue_manager,
189 TimeDomain* time_domain); 220 TimeDomain* time_domain);
190 ~AnyThread(); 221 ~AnyThread();
191 222
192 // TaskQueueManager and TimeDomain are maintained in two copies: 223 // TaskQueueManager and TimeDomain are maintained in two copies:
193 // inside AnyThread and inside MainThreadOnly. They can be changed only from 224 // inside AnyThread and inside MainThreadOnly. They can be changed only from
194 // main thread, so it should be locked before accessing from other threads. 225 // main thread, so it should be locked before accessing from other threads.
195 TaskQueueManager* task_queue_manager; 226 TaskQueueManager* task_queue_manager;
196 TimeDomain* time_domain; 227 TimeDomain* time_domain;
197 228
198 std::queue<Task> immediate_incoming_queue; 229 ComparatorQueue immediate_incoming_queue;
199 }; 230 };
200 231
201 struct MainThreadOnly { 232 struct MainThreadOnly {
202 MainThreadOnly(TaskQueueManager* task_queue_manager, 233 MainThreadOnly(TaskQueueManager* task_queue_manager,
203 TaskQueueImpl* task_queue, 234 TaskQueueImpl* task_queue,
204 TimeDomain* time_domain); 235 TimeDomain* time_domain);
205 ~MainThreadOnly(); 236 ~MainThreadOnly();
206 237
207 // Another copy of TaskQueueManager and TimeDomain for lock-free access from 238 // Another copy of TaskQueueManager and TimeDomain for lock-free access from
208 // the main thread. See description inside struct AnyThread for details. 239 // the main thread. See description inside struct AnyThread for details.
209 TaskQueueManager* task_queue_manager; 240 TaskQueueManager* task_queue_manager;
210 TimeDomain* time_domain; 241 TimeDomain* time_domain;
211 242
212 std::unique_ptr<WorkQueue> delayed_work_queue; 243 std::unique_ptr<WorkQueue> delayed_work_queue;
213 std::unique_ptr<WorkQueue> immediate_work_queue; 244 std::unique_ptr<WorkQueue> immediate_work_queue;
214 std::priority_queue<Task> delayed_incoming_queue; 245 DelayedRunTimeQueue delayed_incoming_queue;
215 base::ObserverList<base::MessageLoop::TaskObserver> task_observers; 246 base::ObserverList<base::MessageLoop::TaskObserver> task_observers;
216 size_t set_index; 247 size_t set_index;
217 bool is_enabled; 248 bool is_enabled;
218 base::trace_event::BlameContext* blame_context; // Not owned. 249 base::trace_event::BlameContext* blame_context; // Not owned.
219 EnqueueOrder current_fence; 250 EnqueueOrder current_fence;
220 }; 251 };
221 252
222 ~TaskQueueImpl() override; 253 ~TaskQueueImpl() override;
223 254
224 bool PostImmediateTaskImpl(const tracked_objects::Location& from_here, 255 bool PostImmediateTaskImpl(const tracked_objects::Location& from_here,
225 const base::Closure& task, 256 const base::Closure& task,
226 TaskType task_type); 257 TaskType task_type);
227 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here, 258 bool PostDelayedTaskImpl(const tracked_objects::Location& from_here,
228 const base::Closure& task, 259 const base::Closure& task,
229 base::TimeDelta delay, 260 base::TimeDelta delay,
230 TaskType task_type); 261 TaskType task_type);
231 262
232 // Push the task onto the |delayed_incoming_queue|. Lock-free main thread 263 // Push the task onto the |delayed_incoming_queue|. Lock-free main thread
233 // only fast path. 264 // only fast path.
234 void PushOntoDelayedIncomingQueueFromMainThread(Task pending_task, 265 void PushOntoDelayedIncomingQueueFromMainThread(Task pending_task,
235 base::TimeTicks now); 266 base::TimeTicks now);
236 267
237 // Push the task onto the |delayed_incoming_queue|. Slow path from other 268 // Push the task onto the |delayed_incoming_queue|. Slow path from other
238 // threads. 269 // threads.
239 void PushOntoDelayedIncomingQueueLocked(Task pending_task); 270 void PushOntoDelayedIncomingQueueLocked(Task pending_task);
240 271
241 void ScheduleDelayedWorkTask(Task pending_task); 272 void ScheduleDelayedWorkTask(Task pending_task);
242 273
274 // Enqueues any delayed tasks which should be run now on the
275 // |delayed_work_queue|. Must be called from the main thread.
276 void MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now);
277
243 void MoveReadyImmediateTasksToImmediateWorkQueueLocked(); 278 void MoveReadyImmediateTasksToImmediateWorkQueueLocked();
244 279
245 // Push the task onto the |immediate_incoming_queue| and for auto pumped 280 // Push the task onto the |immediate_incoming_queue| and for auto pumped
246 // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was 281 // queues it calls MaybePostDoWorkOnMainRunner if the Incoming queue was
247 // empty. 282 // empty.
248 void PushOntoImmediateIncomingQueueLocked( 283 void PushOntoImmediateIncomingQueueLocked(Task pending_task);
249 const tracked_objects::Location& posted_from,
250 const base::Closure& task,
251 base::TimeTicks desired_run_time,
252 EnqueueOrder sequence_number,
253 bool nestable);
254 284
255 // As BlockedByFence but safe to be called while locked. 285 // As BlockedByFence but safe to be called while locked.
256 bool BlockedByFenceLocked() const; 286 bool BlockedByFenceLocked() const;
257 287
258 void TraceQueueSize(bool is_locked) const; 288 void TraceQueueSize(bool is_locked) const;
259 static void QueueAsValueInto(const std::queue<Task>& queue, 289 static void QueueAsValueInto(const ComparatorQueue& queue,
260 base::trace_event::TracedValue* state); 290 base::trace_event::TracedValue* state);
261 static void QueueAsValueInto(const std::priority_queue<Task>& queue, 291 static void QueueAsValueInto(const DelayedRunTimeQueue& queue,
262 base::trace_event::TracedValue* state); 292 base::trace_event::TracedValue* state);
263 static void TaskAsValueInto(const Task& task, 293 static void TaskAsValueInto(const Task& task,
264 base::trace_event::TracedValue* state); 294 base::trace_event::TracedValue* state);
265 295
266 const base::PlatformThreadId thread_id_; 296 const base::PlatformThreadId thread_id_;
267 297
268 mutable base::Lock any_thread_lock_; 298 mutable base::Lock any_thread_lock_;
269 AnyThread any_thread_; 299 AnyThread any_thread_;
270 struct AnyThread& any_thread() { 300 struct AnyThread& any_thread() {
271 any_thread_lock_.AssertAcquired(); 301 any_thread_lock_.AssertAcquired();
(...skipping 24 matching lines...) Expand all
296 const bool should_report_when_execution_blocked_; 326 const bool should_report_when_execution_blocked_;
297 327
298 DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl); 328 DISALLOW_COPY_AND_ASSIGN(TaskQueueImpl);
299 }; 329 };
300 330
301 } // namespace internal 331 } // namespace internal
302 } // namespace scheduler 332 } // namespace scheduler
303 } // namespace blink 333 } // namespace blink
304 334
305 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_ 335 #endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/Timer.cpp ('k') | third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698