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

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

Powered by Google App Engine
This is Rietveld 408576698