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

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

Issue 2786083005: scheduler: Maintain a constant enqueue order for every task (Closed)
Patch Set: Update VirtualTimeTest 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 #include "platform/scheduler/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 DCHECK(any_thread().task_queue_manager == nullptr) 103 DCHECK(any_thread().task_queue_manager == nullptr)
104 << "UnregisterTaskQueue must be called first!"; 104 << "UnregisterTaskQueue must be called first!";
105 #endif 105 #endif
106 } 106 }
107 107
108 TaskQueueImpl::Task::Task() 108 TaskQueueImpl::Task::Task()
109 : PendingTask(tracked_objects::Location(), 109 : PendingTask(tracked_objects::Location(),
110 base::Closure(), 110 base::Closure(),
111 base::TimeTicks(), 111 base::TimeTicks(),
112 true), 112 true),
113 #ifndef NDEBUG 113 enqueue_order_({base::TimeTicks(), 0}) {
114 enqueue_order_set_(false),
115 #endif
116 enqueue_order_(0) {
117 sequence_num = 0; 114 sequence_num = 0;
118 } 115 }
119 116
120 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from, 117 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
121 base::OnceClosure task, 118 base::OnceClosure task,
122 base::TimeTicks desired_run_time, 119 EnqueueOrder enqueue_order,
123 EnqueueOrder sequence_number,
124 bool nestable) 120 bool nestable)
125 : PendingTask(posted_from, std::move(task), desired_run_time, nestable), 121 : PendingTask(posted_from,
126 #ifndef NDEBUG 122 std::move(task),
127 enqueue_order_set_(false), 123 enqueue_order.delayed_run_time,
128 #endif 124 nestable),
129 enqueue_order_(0) {
130 sequence_num = sequence_number;
131 }
132
133 TaskQueueImpl::Task::Task(const tracked_objects::Location& posted_from,
134 base::OnceClosure task,
135 base::TimeTicks desired_run_time,
136 EnqueueOrder sequence_number,
137 bool nestable,
138 EnqueueOrder enqueue_order)
139 : PendingTask(posted_from, std::move(task), desired_run_time, nestable),
140 #ifndef NDEBUG
141 enqueue_order_set_(true),
142 #endif
143 enqueue_order_(enqueue_order) { 125 enqueue_order_(enqueue_order) {
144 sequence_num = sequence_number; 126 // Note: these properties are only used for tracing.
127 sequence_num = static_cast<int>(enqueue_order.sequence_num);
128 delayed_run_time = enqueue_order.delayed_run_time;
145 } 129 }
146 130
147 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, 131 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
148 TimeDomain* time_domain) 132 TimeDomain* time_domain)
149 : task_queue_manager(task_queue_manager), 133 : task_queue_manager(task_queue_manager),
150 time_domain(time_domain), 134 time_domain(time_domain),
151 observer(nullptr) {} 135 observer(nullptr) {}
152 136
153 TaskQueueImpl::AnyThread::~AnyThread() {} 137 TaskQueueImpl::AnyThread::~AnyThread() {}
154 138
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 205
222 bool TaskQueueImpl::PostImmediateTaskImpl( 206 bool TaskQueueImpl::PostImmediateTaskImpl(
223 const tracked_objects::Location& from_here, 207 const tracked_objects::Location& from_here,
224 base::OnceClosure task, 208 base::OnceClosure task,
225 TaskType task_type) { 209 TaskType task_type) {
226 DCHECK(task); 210 DCHECK(task);
227 base::AutoLock lock(any_thread_lock_); 211 base::AutoLock lock(any_thread_lock_);
228 if (!any_thread().task_queue_manager) 212 if (!any_thread().task_queue_manager)
229 return false; 213 return false;
230 214
231 EnqueueOrder sequence_number = 215 EnqueueOrder enqueue_order =
232 any_thread().task_queue_manager->GetNextSequenceNumber(); 216 any_thread().task_queue_manager->GetNextEnqueueOrder(base::TimeTicks());
233 217
234 PushOntoImmediateIncomingQueueLocked(from_here, std::move(task), 218 PushOntoImmediateIncomingQueueLocked(from_here, std::move(task),
235 base::TimeTicks(), sequence_number, 219 enqueue_order,
236 task_type != TaskType::NON_NESTABLE); 220 task_type != TaskType::NON_NESTABLE);
237 return true; 221 return true;
238 } 222 }
239 223
240 bool TaskQueueImpl::PostDelayedTaskImpl( 224 bool TaskQueueImpl::PostDelayedTaskImpl(
241 const tracked_objects::Location& from_here, 225 const tracked_objects::Location& from_here,
242 base::OnceClosure task, 226 base::OnceClosure task,
243 base::TimeDelta delay, 227 base::TimeDelta delay,
244 TaskType task_type) { 228 TaskType task_type) {
245 DCHECK(task); 229 DCHECK(task);
246 DCHECK_GT(delay, base::TimeDelta()); 230 DCHECK_GT(delay, base::TimeDelta());
247 if (base::PlatformThread::CurrentId() == thread_id_) { 231 if (base::PlatformThread::CurrentId() == thread_id_) {
248 // Lock-free fast path for delayed tasks posted from the main thread. 232 // Lock-free fast path for delayed tasks posted from the main thread.
249 if (!main_thread_only().task_queue_manager) 233 if (!main_thread_only().task_queue_manager)
250 return false; 234 return false;
251 235
252 EnqueueOrder sequence_number =
253 main_thread_only().task_queue_manager->GetNextSequenceNumber();
254
255 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 236 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
256 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; 237 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
238 EnqueueOrder enqueue_order =
239 main_thread_only().task_queue_manager->GetNextEnqueueOrder(
240 time_domain_delayed_run_time);
257 PushOntoDelayedIncomingQueueFromMainThread( 241 PushOntoDelayedIncomingQueueFromMainThread(
258 Task(from_here, std::move(task), time_domain_delayed_run_time, 242 Task(from_here, std::move(task), enqueue_order,
259 sequence_number, task_type != TaskType::NON_NESTABLE), 243 task_type != TaskType::NON_NESTABLE),
260 time_domain_now); 244 time_domain_now);
261 } else { 245 } else {
262 // NOTE posting a delayed task from a different thread is not expected to 246 // NOTE posting a delayed task from a different thread is not expected to
263 // be common. This pathway is less optimal than perhaps it could be 247 // be common. This pathway is less optimal than perhaps it could be
264 // because it causes two main thread tasks to be run. Should this 248 // because it causes two main thread tasks to be run. Should this
265 // assumption prove to be false in future, we may need to revisit this. 249 // assumption prove to be false in future, we may need to revisit this.
266 base::AutoLock lock(any_thread_lock_); 250 base::AutoLock lock(any_thread_lock_);
267 if (!any_thread().task_queue_manager) 251 if (!any_thread().task_queue_manager)
268 return false; 252 return false;
269 253
270 EnqueueOrder sequence_number =
271 any_thread().task_queue_manager->GetNextSequenceNumber();
272
273 base::TimeTicks time_domain_now = any_thread().time_domain->Now(); 254 base::TimeTicks time_domain_now = any_thread().time_domain->Now();
274 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; 255 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
256 EnqueueOrder enqueue_order =
257 any_thread().task_queue_manager->GetNextEnqueueOrder(
258 time_domain_delayed_run_time);
275 PushOntoDelayedIncomingQueueLocked( 259 PushOntoDelayedIncomingQueueLocked(
276 Task(from_here, std::move(task), time_domain_delayed_run_time, 260 Task(from_here, std::move(task), enqueue_order,
277 sequence_number, task_type != TaskType::NON_NESTABLE)); 261 task_type != TaskType::NON_NESTABLE));
278 } 262 }
279 return true; 263 return true;
280 } 264 }
281 265
282 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( 266 void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread(
283 Task pending_task, base::TimeTicks now) { 267 Task pending_task, base::TimeTicks now) {
284 DelayedWakeUp wake_up = pending_task.delayed_wake_up(); 268 DelayedWakeUp wake_up = pending_task.delayed_wake_up();
285 main_thread_only().task_queue_manager->DidQueueTask(pending_task); 269 main_thread_only().task_queue_manager->DidQueueTask(pending_task);
286 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 270 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
287 271
288 // If |pending_task| is at the head of the queue, then make sure a wake-up 272 // If |pending_task| is at the head of the queue, then make sure a wake-up
289 // is requested if the queue is enabled. Note we still want to schedule a 273 // is requested if the queue is enabled. Note we still want to schedule a
290 // wake-up even if blocked by a fence, because we'd break throttling logic 274 // wake-up even if blocked by a fence, because we'd break throttling logic
291 // otherwise. 275 // otherwise.
292 DelayedWakeUp new_wake_up = 276 DelayedWakeUp new_wake_up =
293 main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); 277 main_thread_only().delayed_incoming_queue.top().delayed_wake_up();
294 if (wake_up.time == new_wake_up.time && 278 if (wake_up.time == new_wake_up.time &&
295 wake_up.sequence_num == new_wake_up.sequence_num) { 279 wake_up.sequence_num == new_wake_up.sequence_num) {
296 ScheduleDelayedWorkInTimeDomain(now); 280 ScheduleDelayedWorkInTimeDomain(now);
297 } 281 }
298 282
299 TraceQueueSize(); 283 TraceQueueSize();
300 } 284 }
301 285
302 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { 286 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
303 any_thread().task_queue_manager->DidQueueTask(pending_task); 287 any_thread().task_queue_manager->DidQueueTask(pending_task);
304 288
305 int thread_hop_task_sequence_number = 289 EnqueueOrder thread_hop_task_enqueue_order =
alex clarke (OOO till 29th) 2017/04/13 07:46:00 Oh wow that's a nasty bug fixed here.
Sami 2017/04/18 10:47:49 You mean the overflow? Yeah :)
306 any_thread().task_queue_manager->GetNextSequenceNumber(); 290 any_thread().task_queue_manager->GetNextEnqueueOrder(base::TimeTicks());
307 PushOntoImmediateIncomingQueueLocked( 291 PushOntoImmediateIncomingQueueLocked(
308 FROM_HERE, 292 FROM_HERE,
309 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, 293 base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this,
310 base::Passed(&pending_task)), 294 base::Passed(&pending_task)),
311 base::TimeTicks(), 295 thread_hop_task_enqueue_order, false);
312 thread_hop_task_sequence_number,
313 false);
314 } 296 }
315 297
316 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { 298 void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) {
317 DCHECK(main_thread_checker_.CalledOnValidThread()); 299 DCHECK(main_thread_checker_.CalledOnValidThread());
318 base::TimeTicks delayed_run_time = pending_task.delayed_run_time; 300 base::TimeTicks delayed_run_time = pending_task.delayed_run_time;
319 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 301 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
320 if (delayed_run_time <= time_domain_now) { 302 if (delayed_run_time <= time_domain_now) {
321 // If |delayed_run_time| is in the past then push it onto the work queue 303 // If |delayed_run_time| is in the past then push it onto the work queue
322 // immediately. To ensure the right task ordering we need to temporarily 304 // immediately. To ensure the right task ordering we need to temporarily
323 // push it onto the |delayed_incoming_queue|. 305 // push it onto the |delayed_incoming_queue|.
324 delayed_run_time = time_domain_now; 306 delayed_run_time = time_domain_now;
325 pending_task.delayed_run_time = time_domain_now; 307 pending_task.delayed_run_time = time_domain_now;
326 main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); 308 main_thread_only().delayed_incoming_queue.push(std::move(pending_task));
327 LazyNow lazy_now(time_domain_now); 309 LazyNow lazy_now(time_domain_now);
328 WakeUpForDelayedWork(&lazy_now); 310 WakeUpForDelayedWork(&lazy_now);
329 } else { 311 } else {
330 // If |delayed_run_time| is in the future we can queue it as normal. 312 // If |delayed_run_time| is in the future we can queue it as normal.
331 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task), 313 PushOntoDelayedIncomingQueueFromMainThread(std::move(pending_task),
332 time_domain_now); 314 time_domain_now);
333 } 315 }
334 TraceQueueSize(); 316 TraceQueueSize();
335 } 317 }
336 318
337 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( 319 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
338 const tracked_objects::Location& posted_from, 320 const tracked_objects::Location& posted_from,
339 base::OnceClosure task, 321 base::OnceClosure task,
340 base::TimeTicks desired_run_time, 322 EnqueueOrder enqueue_order,
341 EnqueueOrder sequence_number,
342 bool nestable) { 323 bool nestable) {
343 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make 324 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
344 // it run. 325 // it run.
345 bool was_immediate_incoming_queue_empty; 326 bool was_immediate_incoming_queue_empty;
346 327
347 { 328 {
348 base::AutoLock lock(immediate_incoming_queue_lock_); 329 base::AutoLock lock(immediate_incoming_queue_lock_);
349 was_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); 330 was_immediate_incoming_queue_empty = immediate_incoming_queue().empty();
350 immediate_incoming_queue().emplace_back(posted_from, std::move(task), 331 immediate_incoming_queue().emplace_back(posted_from, std::move(task),
351 desired_run_time, sequence_number, 332 enqueue_order, nestable);
352 nestable, sequence_number);
353 any_thread().task_queue_manager->DidQueueTask( 333 any_thread().task_queue_manager->DidQueueTask(
354 immediate_incoming_queue().back()); 334 immediate_incoming_queue().back());
355 } 335 }
356 336
357 if (was_immediate_incoming_queue_empty) { 337 if (was_immediate_incoming_queue_empty) {
358 // However there's no point posting a DoWork for a blocked queue. NB we can 338 // However there's no point posting a DoWork for a blocked queue. NB we can
359 // only tell if it's disabled from the main thread. 339 // only tell if it's disabled from the main thread.
360 bool queue_is_blocked = 340 bool queue_is_blocked =
361 RunsTasksOnCurrentThread() && 341 RunsTasksOnCurrentThread() &&
362 (!IsQueueEnabled() || main_thread_only().current_fence); 342 (!IsQueueEnabled() || main_thread_only().current_fence);
363 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork( 343 any_thread().task_queue_manager->OnQueueHasIncomingImmediateWork(
364 this, sequence_number, queue_is_blocked); 344 this, enqueue_order, queue_is_blocked);
365 if (any_thread().observer) 345 if (any_thread().observer)
366 any_thread().observer->OnQueueNextWakeUpChanged(this, desired_run_time); 346 any_thread().observer->OnQueueNextWakeUpChanged(
347 this, enqueue_order.delayed_run_time);
367 } 348 }
368 349
369 TraceQueueSize(); 350 TraceQueueSize();
370 } 351 }
371 352
372 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { 353 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
373 if (!main_thread_only().immediate_work_queue->Empty()) 354 if (!main_thread_only().immediate_work_queue->Empty())
374 return; 355 return;
375 356
376 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue(); 357 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 // have been canceled. 420 // have been canceled.
440 while (!main_thread_only().delayed_incoming_queue.empty()) { 421 while (!main_thread_only().delayed_incoming_queue.empty()) {
441 Task& task = 422 Task& task =
442 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); 423 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top());
443 if (task.task.IsCancelled()) { 424 if (task.task.IsCancelled()) {
444 main_thread_only().delayed_incoming_queue.pop(); 425 main_thread_only().delayed_incoming_queue.pop();
445 continue; 426 continue;
446 } 427 }
447 if (task.delayed_run_time > lazy_now->Now()) 428 if (task.delayed_run_time > lazy_now->Now())
448 break; 429 break;
449 task.set_enqueue_order(
450 main_thread_only().task_queue_manager->GetNextSequenceNumber());
451 main_thread_only().delayed_work_queue->Push(std::move(task)); 430 main_thread_only().delayed_work_queue->Push(std::move(task));
alex clarke (OOO till 29th) 2017/04/13 07:46:00 Something for a future patch, but I wonder if we a
Sami 2017/04/18 10:47:49 Interesting point. We'd still need some way to rou
452 main_thread_only().delayed_incoming_queue.pop(); 431 main_thread_only().delayed_incoming_queue.pop();
453 } 432 }
454 433
455 // Make sure the next wake up is scheduled. 434 // Make sure the next wake up is scheduled.
456 if (!main_thread_only().delayed_incoming_queue.empty()) { 435 if (!main_thread_only().delayed_incoming_queue.empty()) {
457 return main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); 436 return main_thread_only().delayed_incoming_queue.top().delayed_wake_up();
458 } 437 }
459 438
460 return base::nullopt; 439 return base::nullopt;
461 } 440 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 593
615 void TaskQueueImpl::SetBlameContext( 594 void TaskQueueImpl::SetBlameContext(
616 base::trace_event::BlameContext* blame_context) { 595 base::trace_event::BlameContext* blame_context) {
617 main_thread_only().blame_context = blame_context; 596 main_thread_only().blame_context = blame_context;
618 } 597 }
619 598
620 void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { 599 void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) {
621 if (!main_thread_only().task_queue_manager) 600 if (!main_thread_only().task_queue_manager)
622 return; 601 return;
623 602
624 EnqueueOrder previous_fence = main_thread_only().current_fence; 603 uint64_t previous_fence = main_thread_only().current_fence;
625 main_thread_only().current_fence = 604 main_thread_only().current_fence =
626 position == TaskQueue::InsertFencePosition::NOW 605 position == TaskQueue::InsertFencePosition::NOW
627 ? main_thread_only().task_queue_manager->GetNextSequenceNumber() 606 ? main_thread_only()
628 : static_cast<EnqueueOrder>(EnqueueOrderValues::BLOCKING_FENCE); 607 .task_queue_manager->GetNextEnqueueOrder(base::TimeTicks())
608 .sequence_num
609 : static_cast<uint64_t>(
610 EnqueueOrderSequenceNumberValues::BLOCKING_FENCE);
629 611
630 // Tasks posted after this point will have a strictly higher enqueue order 612 // Tasks posted after this point will have a strictly higher enqueue order
631 // and will be blocked from running. 613 // and will be blocked from running.
632 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence( 614 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence(
633 main_thread_only().current_fence); 615 main_thread_only().current_fence);
634 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence( 616 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence(
635 main_thread_only().current_fence); 617 main_thread_only().current_fence);
636 618
637 if (!task_unblocked && previous_fence && 619 if (!task_unblocked && previous_fence &&
638 previous_fence < main_thread_only().current_fence) { 620 previous_fence < main_thread_only().current_fence) {
639 base::AutoLock lock(immediate_incoming_queue_lock_); 621 base::AutoLock lock(immediate_incoming_queue_lock_);
640 if (!immediate_incoming_queue().empty() && 622 if (!immediate_incoming_queue().empty() &&
641 immediate_incoming_queue().front().enqueue_order() > previous_fence && 623 immediate_incoming_queue().front().enqueue_order().sequence_num >
642 immediate_incoming_queue().front().enqueue_order() < 624 previous_fence &&
625 immediate_incoming_queue().front().enqueue_order().sequence_num <
643 main_thread_only().current_fence) { 626 main_thread_only().current_fence) {
644 task_unblocked = true; 627 task_unblocked = true;
645 } 628 }
646 } 629 }
647 630
648 if (IsQueueEnabled() && task_unblocked) { 631 if (IsQueueEnabled() && task_unblocked) {
649 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 632 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
650 FROM_HERE); 633 FROM_HERE);
651 } 634 }
652 } 635 }
653 636
654 void TaskQueueImpl::RemoveFence() { 637 void TaskQueueImpl::RemoveFence() {
655 if (!main_thread_only().task_queue_manager) 638 if (!main_thread_only().task_queue_manager)
656 return; 639 return;
657 640
658 EnqueueOrder previous_fence = main_thread_only().current_fence; 641 uint64_t previous_fence = main_thread_only().current_fence;
659 main_thread_only().current_fence = 0; 642 main_thread_only().current_fence = 0;
660 643
661 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); 644 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence();
662 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); 645 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
663 646
664 if (!task_unblocked && previous_fence) { 647 if (!task_unblocked && previous_fence) {
665 base::AutoLock lock(immediate_incoming_queue_lock_); 648 base::AutoLock lock(immediate_incoming_queue_lock_);
666 if (!immediate_incoming_queue().empty() && 649 if (!immediate_incoming_queue().empty() &&
667 immediate_incoming_queue().front().enqueue_order() > previous_fence) { 650 immediate_incoming_queue().front().enqueue_order().sequence_num >
651 previous_fence) {
668 task_unblocked = true; 652 task_unblocked = true;
669 } 653 }
670 } 654 }
671 655
672 if (IsQueueEnabled() && task_unblocked) { 656 if (IsQueueEnabled() && task_unblocked) {
673 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork( 657 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
674 FROM_HERE); 658 FROM_HERE);
675 } 659 }
676 } 660 }
677 661
678 bool TaskQueueImpl::BlockedByFence() const { 662 bool TaskQueueImpl::BlockedByFence() const {
679 if (!main_thread_only().current_fence) 663 if (!main_thread_only().current_fence)
680 return false; 664 return false;
681 665
682 if (!main_thread_only().immediate_work_queue->BlockedByFence() || 666 if (!main_thread_only().immediate_work_queue->BlockedByFence() ||
683 !main_thread_only().delayed_work_queue->BlockedByFence()) { 667 !main_thread_only().delayed_work_queue->BlockedByFence()) {
684 return false; 668 return false;
685 } 669 }
686 670
687 base::AutoLock lock(immediate_incoming_queue_lock_); 671 base::AutoLock lock(immediate_incoming_queue_lock_);
688 if (immediate_incoming_queue().empty()) 672 if (immediate_incoming_queue().empty())
689 return true; 673 return true;
690 674
691 return immediate_incoming_queue().front().enqueue_order() > 675 return immediate_incoming_queue().front().enqueue_order().sequence_num >
692 main_thread_only().current_fence; 676 main_thread_only().current_fence;
693 } 677 }
694 678
695 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const { 679 bool TaskQueueImpl::CouldTaskRun(EnqueueOrder enqueue_order) const {
696 if (!IsQueueEnabled()) 680 if (!IsQueueEnabled())
697 return false; 681 return false;
698 682
699 if (!main_thread_only().current_fence) 683 if (!main_thread_only().current_fence)
700 return true; 684 return true;
701 685
702 return enqueue_order < main_thread_only().current_fence; 686 return enqueue_order.sequence_num < main_thread_only().current_fence;
703 } 687 }
704 688
705 EnqueueOrder TaskQueueImpl::GetFenceForTest() const { 689 uint64_t TaskQueueImpl::GetFenceForTest() const {
706 return main_thread_only().current_fence; 690 return main_thread_only().current_fence;
707 } 691 }
708 692
709 // static 693 // static
710 void TaskQueueImpl::QueueAsValueInto(const WTF::Deque<Task>& queue, 694 void TaskQueueImpl::QueueAsValueInto(const WTF::Deque<Task>& queue,
711 base::trace_event::TracedValue* state) { 695 base::trace_event::TracedValue* state) {
712 for (const Task& task : queue) { 696 for (const Task& task : queue) {
713 TaskAsValueInto(task, state); 697 TaskAsValueInto(task, state);
714 } 698 }
715 } 699 }
(...skipping 12 matching lines...) Expand all
728 mutable_queue->pop(); 712 mutable_queue->pop();
729 } 713 }
730 *mutable_queue = std::move(visited); 714 *mutable_queue = std::move(visited);
731 } 715 }
732 716
733 // static 717 // static
734 void TaskQueueImpl::TaskAsValueInto(const Task& task, 718 void TaskQueueImpl::TaskAsValueInto(const Task& task,
735 base::trace_event::TracedValue* state) { 719 base::trace_event::TracedValue* state) {
736 state->BeginDictionary(); 720 state->BeginDictionary();
737 state->SetString("posted_from", task.posted_from.ToString()); 721 state->SetString("posted_from", task.posted_from.ToString());
738 #ifndef NDEBUG 722 state->SetInteger("enqueue_order.delayed_run_time",
739 if (task.enqueue_order_set()) 723 task.enqueue_order().delayed_run_time.ToInternalValue());
740 state->SetInteger("enqueue_order", task.enqueue_order()); 724 state->SetInteger("enqueue_order.sequence_num",
741 #else 725 task.enqueue_order().sequence_num);
742 state->SetInteger("enqueue_order", task.enqueue_order());
743 #endif
744 state->SetInteger("sequence_num", task.sequence_num); 726 state->SetInteger("sequence_num", task.sequence_num);
745 state->SetBoolean("nestable", task.nestable); 727 state->SetBoolean("nestable", task.nestable);
746 state->SetBoolean("is_high_res", task.is_high_res); 728 state->SetBoolean("is_high_res", task.is_high_res);
747 state->SetBoolean("is_cancelled", task.task.IsCancelled()); 729 state->SetBoolean("is_cancelled", task.task.IsCancelled());
748 state->SetDouble( 730 state->SetDouble(
749 "delayed_run_time", 731 "delayed_run_time",
750 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); 732 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
751 state->EndDictionary(); 733 state->EndDictionary();
752 } 734 }
753 735
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 } 881 }
900 882
901 void TaskQueueImpl::NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up) { 883 void TaskQueueImpl::NotifyWakeUpChangedOnMainThread(base::TimeTicks wake_up) {
902 if (main_thread_only().observer) 884 if (main_thread_only().observer)
903 main_thread_only().observer->OnQueueNextWakeUpChanged(this, wake_up); 885 main_thread_only().observer->OnQueueNextWakeUpChanged(this, wake_up);
904 } 886 }
905 887
906 } // namespace internal 888 } // namespace internal
907 } // namespace scheduler 889 } // namespace scheduler
908 } // namespace blink 890 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698