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

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

Issue 2276353002: Remove after wakeup logic and replace PumpTask with Fences (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased 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 #include "platform/scheduler/base/task_queue_impl.h" 5 #include "platform/scheduler/base/task_queue_impl.h"
6 6
7 #include "base/trace_event/blame_context.h" 7 #include "base/trace_event/blame_context.h"
8 #include "platform/scheduler/base/task_queue_manager.h" 8 #include "platform/scheduler/base/task_queue_manager.h"
9 #include "platform/scheduler/base/task_queue_manager_delegate.h" 9 #include "platform/scheduler/base/task_queue_manager_delegate.h"
10 #include "platform/scheduler/base/time_domain.h" 10 #include "platform/scheduler/base/time_domain.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 43
44 namespace internal { 44 namespace internal {
45 45
46 TaskQueueImpl::TaskQueueImpl( 46 TaskQueueImpl::TaskQueueImpl(
47 TaskQueueManager* task_queue_manager, 47 TaskQueueManager* task_queue_manager,
48 TimeDomain* time_domain, 48 TimeDomain* time_domain,
49 const Spec& spec, 49 const Spec& spec,
50 const char* disabled_by_default_tracing_category, 50 const char* disabled_by_default_tracing_category,
51 const char* disabled_by_default_verbose_tracing_category) 51 const char* disabled_by_default_verbose_tracing_category)
52 : thread_id_(base::PlatformThread::CurrentId()), 52 : thread_id_(base::PlatformThread::CurrentId()),
53 any_thread_(task_queue_manager, spec.pump_policy, time_domain), 53 any_thread_(task_queue_manager, time_domain),
54 name_(spec.name), 54 name_(spec.name),
55 disabled_by_default_tracing_category_( 55 disabled_by_default_tracing_category_(
56 disabled_by_default_tracing_category), 56 disabled_by_default_tracing_category),
57 disabled_by_default_verbose_tracing_category_( 57 disabled_by_default_verbose_tracing_category_(
58 disabled_by_default_verbose_tracing_category), 58 disabled_by_default_verbose_tracing_category),
59 main_thread_only_(task_queue_manager, 59 main_thread_only_(task_queue_manager, this, time_domain),
60 spec.pump_policy,
61 this,
62 time_domain),
63 wakeup_policy_(spec.wakeup_policy),
64 should_monitor_quiescence_(spec.should_monitor_quiescence), 60 should_monitor_quiescence_(spec.should_monitor_quiescence),
65 should_notify_observers_(spec.should_notify_observers), 61 should_notify_observers_(spec.should_notify_observers),
66 should_report_when_execution_blocked_( 62 should_report_when_execution_blocked_(
67 spec.should_report_when_execution_blocked) { 63 spec.should_report_when_execution_blocked) {
68 DCHECK(time_domain); 64 DCHECK(time_domain);
69 time_domain->RegisterQueue(this); 65 time_domain->RegisterQueue(this);
70 } 66 }
71 67
72 TaskQueueImpl::~TaskQueueImpl() { 68 TaskQueueImpl::~TaskQueueImpl() {
73 #if DCHECK_IS_ON() 69 #if DCHECK_IS_ON()
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 160
165 if (a.delayed_run_time > b.delayed_run_time) 161 if (a.delayed_run_time > b.delayed_run_time)
166 return false; 162 return false;
167 163
168 // If the times happen to match, then we use the sequence number to decide. 164 // If the times happen to match, then we use the sequence number to decide.
169 // Compare the difference to support integer roll-over. 165 // Compare the difference to support integer roll-over.
170 return (a.sequence_num - b.sequence_num) < 0; 166 return (a.sequence_num - b.sequence_num) < 0;
171 } 167 }
172 168
173 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager, 169 TaskQueueImpl::AnyThread::AnyThread(TaskQueueManager* task_queue_manager,
174 PumpPolicy pump_policy,
175 TimeDomain* time_domain) 170 TimeDomain* time_domain)
176 : task_queue_manager(task_queue_manager), 171 : task_queue_manager(task_queue_manager),
177 pump_policy(pump_policy),
178 time_domain(time_domain), 172 time_domain(time_domain),
179 immediate_incoming_queue(&TaskQueueImpl::Task::EnqueueOrderComparatorFn) { 173 immediate_incoming_queue(&TaskQueueImpl::Task::EnqueueOrderComparatorFn) {
180 } 174 }
181 175
182 TaskQueueImpl::AnyThread::~AnyThread() {} 176 TaskQueueImpl::AnyThread::~AnyThread() {}
183 177
184 TaskQueueImpl::MainThreadOnly::MainThreadOnly( 178 TaskQueueImpl::MainThreadOnly::MainThreadOnly(
185 TaskQueueManager* task_queue_manager, 179 TaskQueueManager* task_queue_manager,
186 PumpPolicy pump_policy,
187 TaskQueueImpl* task_queue, 180 TaskQueueImpl* task_queue,
188 TimeDomain* time_domain) 181 TimeDomain* time_domain)
189 : task_queue_manager(task_queue_manager), 182 : task_queue_manager(task_queue_manager),
190 pump_policy(pump_policy),
191 time_domain(time_domain), 183 time_domain(time_domain),
192 delayed_work_queue( 184 delayed_work_queue(
193 new WorkQueue(task_queue, 185 new WorkQueue(task_queue,
194 "delayed", 186 "delayed",
195 &TaskQueueImpl::Task::DelayedRunTimeComparatorFn)), 187 &TaskQueueImpl::Task::DelayedRunTimeComparatorFn)),
196 immediate_work_queue( 188 immediate_work_queue(
197 new WorkQueue(task_queue, 189 new WorkQueue(task_queue,
198 "immediate", 190 "immediate",
199 &TaskQueueImpl::Task::EnqueueOrderComparatorFn)), 191 &TaskQueueImpl::Task::EnqueueOrderComparatorFn)),
200 set_index(0), 192 set_index(0),
(...skipping 30 matching lines...) Expand all
231 const base::Closure& task, 223 const base::Closure& task,
232 base::TimeDelta delay) { 224 base::TimeDelta delay) {
233 if (!main_thread_only().task_queue_manager) 225 if (!main_thread_only().task_queue_manager)
234 return TaskHandle(); 226 return TaskHandle();
235 227
236 EnqueueOrder sequence_number = 228 EnqueueOrder sequence_number =
237 main_thread_only().task_queue_manager->GetNextSequenceNumber(); 229 main_thread_only().task_queue_manager->GetNextSequenceNumber();
238 230
239 if (delay.is_zero()) { 231 if (delay.is_zero()) {
240 base::AutoLock lock(any_thread_lock_); 232 base::AutoLock lock(any_thread_lock_);
233 // If the |immediate_incoming_queue| is empty and the queue is enabled then
234 // we need a DoWork posted to make it run.
235 if (any_thread().immediate_incoming_queue.empty() &&
236 main_thread_only().is_enabled && !BlockedByFence()) {
237 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
238 }
241 PushOntoImmediateIncomingQueueLocked( 239 PushOntoImmediateIncomingQueueLocked(
242 Task(from_here, task, base::TimeTicks(), sequence_number, true, 240 Task(from_here, task, base::TimeTicks(), sequence_number, true,
243 sequence_number)); 241 sequence_number));
244 242
245 return TaskHandle(this, sequence_number); 243 return TaskHandle(this, sequence_number);
246 } else { 244 } else {
247 DCHECK_GT(delay, base::TimeDelta()); 245 DCHECK_GT(delay, base::TimeDelta());
248 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); 246 base::TimeTicks time_domain_now = main_thread_only().time_domain->Now();
249 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay; 247 base::TimeTicks time_domain_delayed_run_time = time_domain_now + delay;
250 PushOntoDelayedIncomingQueueFromMainThread( 248 PushOntoDelayedIncomingQueueFromMainThread(
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 const tracked_objects::Location& from_here, 365 const tracked_objects::Location& from_here,
368 const base::Closure& task, 366 const base::Closure& task,
369 TaskType task_type) { 367 TaskType task_type) {
370 base::AutoLock lock(any_thread_lock_); 368 base::AutoLock lock(any_thread_lock_);
371 if (!any_thread().task_queue_manager) 369 if (!any_thread().task_queue_manager)
372 return false; 370 return false;
373 371
374 EnqueueOrder sequence_number = 372 EnqueueOrder sequence_number =
375 any_thread().task_queue_manager->GetNextSequenceNumber(); 373 any_thread().task_queue_manager->GetNextSequenceNumber();
376 374
375 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
376 // it run.
377 if (any_thread().immediate_incoming_queue.empty()) {
378 // There's no point posting a DoWork for a disabled queue, however we can
379 // only tell if it's disabled from the main thread.
380 if (base::PlatformThread::CurrentId() == thread_id_) {
381 if (main_thread_only().is_enabled && !BlockedByFence())
382 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
383 } else {
384 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
385 }
386 }
387
377 PushOntoImmediateIncomingQueueLocked( 388 PushOntoImmediateIncomingQueueLocked(
378 Task(from_here, task, base::TimeTicks(), sequence_number, 389 Task(from_here, task, base::TimeTicks(), sequence_number,
379 task_type != TaskType::NON_NESTABLE, sequence_number)); 390 task_type != TaskType::NON_NESTABLE, sequence_number));
380 return true; 391 return true;
381 } 392 }
382 393
383 bool TaskQueueImpl::PostDelayedTaskImpl( 394 bool TaskQueueImpl::PostDelayedTaskImpl(
384 const tracked_objects::Location& from_here, 395 const tracked_objects::Location& from_here,
385 const base::Closure& task, 396 const base::Closure& task,
386 base::TimeDelta delay, 397 base::TimeDelta delay,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time, 443 main_thread_only().time_domain->ScheduleDelayedWork(this, delayed_run_time,
433 now); 444 now);
434 TraceQueueSize(false); 445 TraceQueueSize(false);
435 } 446 }
436 447
437 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { 448 void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) {
438 any_thread().task_queue_manager->DidQueueTask(pending_task); 449 any_thread().task_queue_manager->DidQueueTask(pending_task);
439 450
440 int thread_hop_task_sequence_number = 451 int thread_hop_task_sequence_number =
441 any_thread().task_queue_manager->GetNextSequenceNumber(); 452 any_thread().task_queue_manager->GetNextSequenceNumber();
453
454 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
455 // it run.
456 if (any_thread().immediate_incoming_queue.empty())
457 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
458
442 PushOntoImmediateIncomingQueueLocked( 459 PushOntoImmediateIncomingQueueLocked(
443 Task(FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, 460 Task(FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this,
444 base::Passed(&pending_task)), 461 base::Passed(&pending_task)),
445 base::TimeTicks(), thread_hop_task_sequence_number, false, 462 base::TimeTicks(), thread_hop_task_sequence_number, false,
446 thread_hop_task_sequence_number)); 463 thread_hop_task_sequence_number));
447 } 464 }
448 465
449 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task pending_task) { 466 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task pending_task) {
450 if (any_thread().immediate_incoming_queue.empty()) 467 if (any_thread().immediate_incoming_queue.empty())
451 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); 468 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this);
452 if (any_thread().pump_policy == PumpPolicy::AUTO &&
453 any_thread().immediate_incoming_queue.empty()) {
454 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
455 }
456 any_thread().task_queue_manager->DidQueueTask(pending_task); 469 any_thread().task_queue_manager->DidQueueTask(pending_task);
457 // We expect |pending_task| to be inserted at the end. Amoritized O(1). 470 // We expect |pending_task| to be inserted at the end. Amoritized O(1).
458 any_thread().immediate_incoming_queue.insert( 471 any_thread().immediate_incoming_queue.insert(
459 any_thread().immediate_incoming_queue.end(), 472 any_thread().immediate_incoming_queue.end(),
460 std::move(pending_task)); 473 std::move(pending_task));
461 DCHECK_EQ(pending_task.enqueue_order(), 474 DCHECK_EQ(pending_task.enqueue_order(),
462 any_thread().immediate_incoming_queue.rbegin()->enqueue_order()); 475 any_thread().immediate_incoming_queue.rbegin()->enqueue_order());
463 TraceQueueSize(true); 476 TraceQueueSize(true);
464 } 477 }
465 478
(...skipping 16 matching lines...) Expand all
482 TraceQueueSize(false); 495 TraceQueueSize(false);
483 } 496 }
484 497
485 void TaskQueueImpl::SetQueueEnabled(bool enabled) { 498 void TaskQueueImpl::SetQueueEnabled(bool enabled) {
486 if (main_thread_only().is_enabled == enabled) 499 if (main_thread_only().is_enabled == enabled)
487 return; 500 return;
488 main_thread_only().is_enabled = enabled; 501 main_thread_only().is_enabled = enabled;
489 if (!main_thread_only().task_queue_manager) 502 if (!main_thread_only().task_queue_manager)
490 return; 503 return;
491 if (enabled) { 504 if (enabled) {
505 // Note it's the job of the selector to tell the TaskQueueManager if
506 // a DoWork needs posting.
492 main_thread_only().task_queue_manager->selector_.EnableQueue(this); 507 main_thread_only().task_queue_manager->selector_.EnableQueue(this);
493 } else { 508 } else {
494 main_thread_only().task_queue_manager->selector_.DisableQueue(this); 509 main_thread_only().task_queue_manager->selector_.DisableQueue(this);
495 } 510 }
496 } 511 }
497 512
498 bool TaskQueueImpl::IsQueueEnabled() const { 513 bool TaskQueueImpl::IsQueueEnabled() const {
499 return main_thread_only().is_enabled; 514 return main_thread_only().is_enabled;
500 } 515 }
501 516
502 bool TaskQueueImpl::IsEmpty() const { 517 bool TaskQueueImpl::IsEmpty() const {
503 if (!main_thread_only().delayed_work_queue->Empty() || 518 if (!main_thread_only().delayed_work_queue->Empty() ||
504 !main_thread_only().immediate_work_queue->Empty()) { 519 !main_thread_only().immediate_work_queue->Empty()) {
505 return false; 520 return false;
506 } 521 }
507 522
508 base::AutoLock lock(any_thread_lock_); 523 base::AutoLock lock(any_thread_lock_);
509 return any_thread().immediate_incoming_queue.empty() && 524 return any_thread().immediate_incoming_queue.empty() &&
510 main_thread_only().delayed_incoming_queue.empty(); 525 main_thread_only().delayed_incoming_queue.empty();
511 } 526 }
512 527
513 bool TaskQueueImpl::HasPendingImmediateWork() const { 528 bool TaskQueueImpl::HasPendingImmediateWork() const {
529 // Any work queue tasks count as immediate work.
514 if (!main_thread_only().delayed_work_queue->Empty() || 530 if (!main_thread_only().delayed_work_queue->Empty() ||
515 !main_thread_only().immediate_work_queue->Empty()) { 531 !main_thread_only().immediate_work_queue->Empty()) {
516 return true; 532 return true;
517 } 533 }
518 534
519 return NeedsPumping(); 535 // Tasks on |delayed_incoming_queue| that could run now, count as
520 } 536 // immediate work.
521 537 if (!main_thread_only().delayed_incoming_queue.empty() &&
522 bool TaskQueueImpl::NeedsPumping() const { 538 main_thread_only().delayed_incoming_queue.begin()->delayed_run_time <=
523 if (!main_thread_only().immediate_work_queue->Empty()) 539 main_thread_only().time_domain->CreateLazyNow().Now()) {
524 return false;
525
526 base::AutoLock lock(any_thread_lock_);
527 if (!any_thread().immediate_incoming_queue.empty())
528 return true;
529
530 // If there's no immediate Incoming work then we only need pumping if there
531 // is a delayed task that should be running now.
532 if (main_thread_only().delayed_incoming_queue.empty())
533 return false;
534
535 return main_thread_only().delayed_incoming_queue.begin()->delayed_run_time <=
536 main_thread_only().time_domain->CreateLazyNow().Now();
537 }
538
539 bool TaskQueueImpl::TaskIsOlderThanQueuedImmediateTasksLocked(
540 const Task* task) {
541 // A null task is passed when UpdateQueue is called before any task is run.
542 // In this case we don't want to pump an after_wakeup queue, so return true
543 // here.
544 if (!task)
545 return true;
546
547 // Return false if task is newer than the oldest immediate task.
548 if (!any_thread().immediate_incoming_queue.empty() &&
549 task->enqueue_order() >
550 any_thread().immediate_incoming_queue.begin()->enqueue_order()) {
551 return false;
552 }
553 return true;
554 }
555
556 bool TaskQueueImpl::TaskIsOlderThanQueuedDelayedTasks(const Task* task) {
557 DCHECK(main_thread_checker_.CalledOnValidThread());
558 // A null task is passed when UpdateQueue is called before any task is run.
559 // In this case we don't want to pump an after_wakeup queue, so return true
560 // here.
561 if (!task)
562 return true;
563
564 EnqueueOrder enqueue_order;
565 if (!main_thread_only().delayed_work_queue->GetFrontTaskEnqueueOrder(
566 &enqueue_order)) {
567 return true; 540 return true;
568 } 541 }
569 542
570 return task->enqueue_order() < enqueue_order; 543 // Finally tasks on |immediate_incoming_queue| count as immediate work.
571 } 544 base::AutoLock lock(any_thread_lock_);
572 545 return !any_thread().immediate_incoming_queue.empty();
573 bool TaskQueueImpl::ShouldAutoPumpImmediateQueueLocked(
574 bool should_trigger_wakeup,
575 const Task* previous_task) {
576 if (main_thread_only().pump_policy == PumpPolicy::MANUAL)
577 return false;
578 if (main_thread_only().pump_policy == PumpPolicy::AFTER_WAKEUP &&
579 (!should_trigger_wakeup ||
580 TaskIsOlderThanQueuedImmediateTasksLocked(previous_task)))
581 return false;
582 return true;
583 }
584
585 bool TaskQueueImpl::ShouldAutoPumpDelayedQueue(bool should_trigger_wakeup,
586 const Task* previous_task) {
587 if (main_thread_only().pump_policy == PumpPolicy::MANUAL)
588 return false;
589 if (main_thread_only().pump_policy == PumpPolicy::AFTER_WAKEUP &&
590 (!should_trigger_wakeup ||
591 TaskIsOlderThanQueuedDelayedTasks(previous_task)))
592 return false;
593 return true;
594 } 546 }
595 547
596 void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) { 548 void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) {
597 // Enqueue all delayed tasks that should be running now. 549 // Enqueue all delayed tasks that should be running now.
598 while (!main_thread_only().delayed_incoming_queue.empty()) { 550 while (!main_thread_only().delayed_incoming_queue.empty()) {
599 DelayedRunTimeQueue::iterator next_task = 551 DelayedRunTimeQueue::iterator next_task =
600 main_thread_only().delayed_incoming_queue.begin(); 552 main_thread_only().delayed_incoming_queue.begin();
601 if (next_task->delayed_run_time > lazy_now->Now()) 553 if (next_task->delayed_run_time > lazy_now->Now())
602 break; 554 break;
603 // TODO(alexclarke): Use extract() when C++17 is allowed. 555 // TODO(alexclarke): Use extract() when C++17 is allowed.
604 Task& task = const_cast<Task&>(*next_task); 556 Task& task = const_cast<Task&>(*next_task);
605 task.set_enqueue_order( 557 task.set_enqueue_order(
606 main_thread_only().task_queue_manager->GetNextSequenceNumber()); 558 main_thread_only().task_queue_manager->GetNextSequenceNumber());
607 main_thread_only().delayed_work_queue->Push(std::move(task)); 559 main_thread_only().delayed_work_queue->Push(std::move(task));
608 main_thread_only().delayed_incoming_queue.erase(next_task); 560 main_thread_only().delayed_incoming_queue.erase(next_task);
609 } 561 }
610 } 562 }
611 563
612 void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now, 564 void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now) {
613 bool should_trigger_wakeup,
614 const Task* previous_task) {
615 if (!main_thread_only().task_queue_manager) 565 if (!main_thread_only().task_queue_manager)
616 return; 566 return;
617 if (!ShouldAutoPumpDelayedQueue(should_trigger_wakeup, previous_task))
618 return;
619 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now); 567 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
620 TraceQueueSize(false); 568 TraceQueueSize(false);
621 } 569 }
622 570
623 void TaskQueueImpl::UpdateImmediateWorkQueue(bool should_trigger_wakeup, 571 void TaskQueueImpl::UpdateImmediateWorkQueue() {
624 const Task* previous_task) {
625 DCHECK(main_thread_only().immediate_work_queue->Empty()); 572 DCHECK(main_thread_only().immediate_work_queue->Empty());
626 base::AutoLock lock(any_thread_lock_); 573 base::AutoLock lock(any_thread_lock_);
627 if (!main_thread_only().task_queue_manager) 574 if (!main_thread_only().task_queue_manager)
628 return; 575 return;
629 if (!ShouldAutoPumpImmediateQueueLocked(should_trigger_wakeup, previous_task))
630 return;
631 576
632 main_thread_only().immediate_work_queue->SwapLocked( 577 main_thread_only().immediate_work_queue->SwapLocked(
633 any_thread().immediate_incoming_queue); 578 any_thread().immediate_incoming_queue);
634 579
635 // |any_thread().immediate_incoming_queue| is now empty so 580 // |any_thread().immediate_incoming_queue| is now empty so
636 // TimeDomain::UpdateQueues no longer needs to consider this queue for 581 // TimeDomain::UpdateQueues no longer needs to consider this queue for
637 // reloading. 582 // reloading.
638 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this); 583 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
639 } 584 }
640 585
(...skipping 15 matching lines...) Expand all
656 any_thread_lock_.AssertAcquired(); 601 any_thread_lock_.AssertAcquired();
657 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(), 602 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
658 any_thread().immediate_incoming_queue.size() + 603 any_thread().immediate_incoming_queue.size() +
659 main_thread_only().immediate_work_queue->Size() + 604 main_thread_only().immediate_work_queue->Size() +
660 main_thread_only().delayed_work_queue->Size() + 605 main_thread_only().delayed_work_queue->Size() +
661 main_thread_only().delayed_incoming_queue.size()); 606 main_thread_only().delayed_incoming_queue.size());
662 if (!is_locked) 607 if (!is_locked)
663 any_thread_lock_.Release(); 608 any_thread_lock_.Release();
664 } 609 }
665 610
666 void TaskQueueImpl::SetPumpPolicy(PumpPolicy pump_policy) {
667 base::AutoLock lock(any_thread_lock_);
668 if (pump_policy == PumpPolicy::AUTO &&
669 any_thread().pump_policy != PumpPolicy::AUTO) {
670 LazyNow lazy_now(main_thread_only().time_domain->CreateLazyNow());
671 PumpQueueLocked(&lazy_now, true);
672 }
673 any_thread().pump_policy = pump_policy;
674 main_thread_only().pump_policy = pump_policy;
675 }
676
677 TaskQueue::PumpPolicy TaskQueueImpl::GetPumpPolicy() const {
678 return main_thread_only().pump_policy;
679 }
680
681 void TaskQueueImpl::PumpQueueLocked(LazyNow* lazy_now, bool may_post_dowork) {
682 TRACE_EVENT1(disabled_by_default_tracing_category_,
683 "TaskQueueImpl::PumpQueueLocked", "queue", name_);
684 TaskQueueManager* task_queue_manager = any_thread().task_queue_manager;
685 if (!task_queue_manager)
686 return;
687
688 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
689
690 while (!any_thread().immediate_incoming_queue.empty()) {
691 ComparatorQueue::iterator it =
692 any_thread().immediate_incoming_queue.begin();
693 main_thread_only().immediate_work_queue->Push(
694 std::move(const_cast<Task&>(*it)));
695 any_thread().immediate_incoming_queue.erase(it);
696 }
697
698 // |immediate_incoming_queue| is now empty so TimeDomain::UpdateQueues no
699 // longer needs to consider this queue for reloading.
700 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
701
702 if (main_thread_only().immediate_work_queue->Empty() &&
703 main_thread_only().delayed_work_queue->Empty()) {
704 return;
705 }
706
707 if (may_post_dowork)
708 task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
709 }
710
711 void TaskQueueImpl::PumpQueue(LazyNow* lazy_now, bool may_post_dowork) {
712 base::AutoLock lock(any_thread_lock_);
713 PumpQueueLocked(lazy_now, may_post_dowork);
714 }
715
716 const char* TaskQueueImpl::GetName() const { 611 const char* TaskQueueImpl::GetName() const {
717 return name_; 612 return name_;
718 } 613 }
719 614
720 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { 615 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
721 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority()) 616 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
722 return; 617 return;
723 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this, 618 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
724 priority); 619 priority);
725 } 620 }
726 621
727 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const { 622 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
728 size_t set_index = immediate_work_queue()->work_queue_set_index(); 623 size_t set_index = immediate_work_queue()->work_queue_set_index();
729 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index()); 624 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index());
730 return static_cast<TaskQueue::QueuePriority>(set_index); 625 return static_cast<TaskQueue::QueuePriority>(set_index);
731 } 626 }
732 627
733 // static 628 // static
734 const char* TaskQueueImpl::PumpPolicyToString(
735 TaskQueue::PumpPolicy pump_policy) {
736 switch (pump_policy) {
737 case TaskQueue::PumpPolicy::AUTO:
738 return "auto";
739 case TaskQueue::PumpPolicy::AFTER_WAKEUP:
740 return "after_wakeup";
741 case TaskQueue::PumpPolicy::MANUAL:
742 return "manual";
743 default:
744 NOTREACHED();
745 return nullptr;
746 }
747 }
748
749 // static
750 const char* TaskQueueImpl::WakeupPolicyToString(
751 TaskQueue::WakeupPolicy wakeup_policy) {
752 switch (wakeup_policy) {
753 case TaskQueue::WakeupPolicy::CAN_WAKE_OTHER_QUEUES:
754 return "can_wake_other_queues";
755 case TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES:
756 return "dont_wake_other_queues";
757 default:
758 NOTREACHED();
759 return nullptr;
760 }
761 }
762
763 // static
764 const char* TaskQueueImpl::PriorityToString(QueuePriority priority) { 629 const char* TaskQueueImpl::PriorityToString(QueuePriority priority) {
765 switch (priority) { 630 switch (priority) {
766 case CONTROL_PRIORITY: 631 case CONTROL_PRIORITY:
767 return "control"; 632 return "control";
768 case HIGH_PRIORITY: 633 case HIGH_PRIORITY:
769 return "high"; 634 return "high";
770 case NORMAL_PRIORITY: 635 case NORMAL_PRIORITY:
771 return "normal"; 636 return "normal";
772 case BEST_EFFORT_PRIORITY: 637 case BEST_EFFORT_PRIORITY:
773 return "best_effort"; 638 return "best_effort";
774 default: 639 default:
775 NOTREACHED(); 640 NOTREACHED();
776 return nullptr; 641 return nullptr;
777 } 642 }
778 } 643 }
779 644
780 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { 645 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
781 base::AutoLock lock(any_thread_lock_); 646 base::AutoLock lock(any_thread_lock_);
782 state->BeginDictionary(); 647 state->BeginDictionary();
783 state->SetString("name", GetName()); 648 state->SetString("name", GetName());
784 state->SetBoolean("enabled", main_thread_only().is_enabled); 649 state->SetBoolean("enabled", main_thread_only().is_enabled);
785 state->SetString("time_domain_name", 650 state->SetString("time_domain_name",
786 main_thread_only().time_domain->GetName()); 651 main_thread_only().time_domain->GetName());
787 state->SetString("pump_policy", PumpPolicyToString(any_thread().pump_policy));
788 state->SetString("wakeup_policy", WakeupPolicyToString(wakeup_policy_));
789 bool verbose_tracing_enabled = false; 652 bool verbose_tracing_enabled = false;
790 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 653 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
791 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); 654 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
792 state->SetInteger("immediate_incoming_queue_size", 655 state->SetInteger("immediate_incoming_queue_size",
793 any_thread().immediate_incoming_queue.size()); 656 any_thread().immediate_incoming_queue.size());
794 state->SetInteger("delayed_incoming_queue_size", 657 state->SetInteger("delayed_incoming_queue_size",
795 main_thread_only().delayed_incoming_queue.size()); 658 main_thread_only().delayed_incoming_queue.size());
796 state->SetInteger("immediate_work_queue_size", 659 state->SetInteger("immediate_work_queue_size",
797 main_thread_only().immediate_work_queue->Size()); 660 main_thread_only().immediate_work_queue->Size());
798 state->SetInteger("delayed_work_queue_size", 661 state->SetInteger("delayed_work_queue_size",
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 740
878 base::AutoLock lock(any_thread_lock_); 741 base::AutoLock lock(any_thread_lock_);
879 return any_thread().time_domain; 742 return any_thread().time_domain;
880 } 743 }
881 744
882 void TaskQueueImpl::SetBlameContext( 745 void TaskQueueImpl::SetBlameContext(
883 base::trace_event::BlameContext* blame_context) { 746 base::trace_event::BlameContext* blame_context) {
884 main_thread_only().blame_context = blame_context; 747 main_thread_only().blame_context = blame_context;
885 } 748 }
886 749
750 EnqueueOrder TaskQueueImpl::GetNewestImmediateTaskEnqueueOrder() const {
751 base::AutoLock lock(any_thread_lock_);
752 if (!any_thread().immediate_incoming_queue.empty())
753 return any_thread().immediate_incoming_queue.rbegin()->enqueue_order();
754 const Task* task = main_thread_only().immediate_work_queue->GetBackTask();
755 if (task)
756 return task->enqueue_order();
757 return 0;
758 }
759
760 EnqueueOrder TaskQueueImpl::GetNewestReadyDelayedTaskEnqueueOrder() {
761 LazyNow lazy_now = main_thread_only().time_domain->CreateLazyNow();
762 MoveReadyDelayedTasksToDelayedWorkQueue(&lazy_now);
763 const Task* task = main_thread_only().delayed_work_queue->GetBackTask();
764 if (task)
765 return task->enqueue_order();
766 return 0;
767 }
768
769 void TaskQueueImpl::InsertFence() {
770 if (!main_thread_only().task_queue_manager)
771 return;
772
773 EnqueueOrder next_immediate = GetNewestImmediateTaskEnqueueOrder();
774 EnqueueOrder next_delayed = GetNewestReadyDelayedTaskEnqueueOrder();
775
776 bool task_unblocked =
777 main_thread_only().immediate_work_queue->InsertFence(next_immediate);
778 task_unblocked |=
779 main_thread_only().delayed_work_queue->InsertFence(next_delayed);
780
781 if (!task_unblocked)
782 task_unblocked |= HasPendingImmediateWork();
783
784 if (main_thread_only().is_enabled && task_unblocked) {
785 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
786 FROM_HERE);
787 }
788 }
789
790 void TaskQueueImpl::RemoveFence() {
791 if (!main_thread_only().task_queue_manager)
792 return;
793 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence();
794 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
795
796 if (!task_unblocked)
797 task_unblocked |= HasPendingImmediateWork();
798
799 if (main_thread_only().is_enabled && task_unblocked) {
800 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
801 FROM_HERE);
802 }
803 }
804
805 bool TaskQueueImpl::BlockedByFence() const {
806 return main_thread_only().immediate_work_queue->fence_hit() &&
807 main_thread_only().delayed_work_queue->fence_hit();
808 }
809
887 // static 810 // static
888 void TaskQueueImpl::QueueAsValueInto(const ComparatorQueue& queue, 811 void TaskQueueImpl::QueueAsValueInto(const ComparatorQueue& queue,
889 base::trace_event::TracedValue* state) { 812 base::trace_event::TracedValue* state) {
890 for (const Task& task : queue) { 813 for (const Task& task : queue) {
891 TaskAsValueInto(task, state); 814 TaskAsValueInto(task, state);
892 } 815 }
893 } 816 }
894 817
895 // static 818 // static
896 void TaskQueueImpl::QueueAsValueInto(const DelayedRunTimeQueue& queue, 819 void TaskQueueImpl::QueueAsValueInto(const DelayedRunTimeQueue& queue,
(...skipping 19 matching lines...) Expand all
916 state->SetBoolean("is_high_res", task.is_high_res); 839 state->SetBoolean("is_high_res", task.is_high_res);
917 state->SetDouble( 840 state->SetDouble(
918 "delayed_run_time", 841 "delayed_run_time",
919 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); 842 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
920 state->EndDictionary(); 843 state->EndDictionary();
921 } 844 }
922 845
923 } // namespace internal 846 } // namespace internal
924 } // namespace scheduler 847 } // namespace scheduler
925 } // namespace blink 848 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698