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

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: Slight simplification 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),
201 is_enabled(true), 193 is_enabled(true),
202 blame_context(nullptr) {} 194 blame_context(nullptr),
195 current_fence(0) {}
203 196
204 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} 197 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
205 198
206 void TaskQueueImpl::UnregisterTaskQueue() { 199 void TaskQueueImpl::UnregisterTaskQueue() {
207 base::AutoLock lock(any_thread_lock_); 200 base::AutoLock lock(any_thread_lock_);
208 if (main_thread_only().time_domain) 201 if (main_thread_only().time_domain)
209 main_thread_only().time_domain->UnregisterQueue(this); 202 main_thread_only().time_domain->UnregisterQueue(this);
210 if (!any_thread().task_queue_manager) 203 if (!any_thread().task_queue_manager)
211 return; 204 return;
212 any_thread().time_domain = nullptr; 205 any_thread().time_domain = nullptr;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 PushOntoImmediateIncomingQueueLocked( 435 PushOntoImmediateIncomingQueueLocked(
443 Task(FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this, 436 Task(FROM_HERE, base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, this,
444 base::Passed(&pending_task)), 437 base::Passed(&pending_task)),
445 base::TimeTicks(), thread_hop_task_sequence_number, false, 438 base::TimeTicks(), thread_hop_task_sequence_number, false,
446 thread_hop_task_sequence_number)); 439 thread_hop_task_sequence_number));
447 } 440 }
448 441
449 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task pending_task) { 442 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task pending_task) {
450 if (any_thread().immediate_incoming_queue.empty()) 443 if (any_thread().immediate_incoming_queue.empty())
451 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); 444 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this);
452 if (any_thread().pump_policy == PumpPolicy::AUTO && 445 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
453 any_thread().immediate_incoming_queue.empty()) { 446 // it run.
454 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 447 if (any_thread().immediate_incoming_queue.empty()) {
448 // There's no point posting a DoWork for a disabled queue, however we can
449 // only tell if it's disabled from the main thread.
450 if (base::PlatformThread::CurrentId() == thread_id_) {
451 if (main_thread_only().is_enabled && !BlockedByFenceLocked())
452 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
453 } else {
454 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
455 }
455 } 456 }
456 any_thread().task_queue_manager->DidQueueTask(pending_task); 457 any_thread().task_queue_manager->DidQueueTask(pending_task);
457 // We expect |pending_task| to be inserted at the end. Amoritized O(1). 458 // We expect |pending_task| to be inserted at the end. Amoritized O(1).
458 any_thread().immediate_incoming_queue.insert( 459 any_thread().immediate_incoming_queue.insert(
459 any_thread().immediate_incoming_queue.end(), 460 any_thread().immediate_incoming_queue.end(),
460 std::move(pending_task)); 461 std::move(pending_task));
461 DCHECK_EQ(pending_task.enqueue_order(), 462 DCHECK_EQ(pending_task.enqueue_order(),
462 any_thread().immediate_incoming_queue.rbegin()->enqueue_order()); 463 any_thread().immediate_incoming_queue.rbegin()->enqueue_order());
463 TraceQueueSize(true); 464 TraceQueueSize(true);
464 } 465 }
(...skipping 17 matching lines...) Expand all
482 TraceQueueSize(false); 483 TraceQueueSize(false);
483 } 484 }
484 485
485 void TaskQueueImpl::SetQueueEnabled(bool enabled) { 486 void TaskQueueImpl::SetQueueEnabled(bool enabled) {
486 if (main_thread_only().is_enabled == enabled) 487 if (main_thread_only().is_enabled == enabled)
487 return; 488 return;
488 main_thread_only().is_enabled = enabled; 489 main_thread_only().is_enabled = enabled;
489 if (!main_thread_only().task_queue_manager) 490 if (!main_thread_only().task_queue_manager)
490 return; 491 return;
491 if (enabled) { 492 if (enabled) {
493 // Note it's the job of the selector to tell the TaskQueueManager if
494 // a DoWork needs posting.
492 main_thread_only().task_queue_manager->selector_.EnableQueue(this); 495 main_thread_only().task_queue_manager->selector_.EnableQueue(this);
493 } else { 496 } else {
494 main_thread_only().task_queue_manager->selector_.DisableQueue(this); 497 main_thread_only().task_queue_manager->selector_.DisableQueue(this);
495 } 498 }
496 } 499 }
497 500
498 bool TaskQueueImpl::IsQueueEnabled() const { 501 bool TaskQueueImpl::IsQueueEnabled() const {
499 return main_thread_only().is_enabled; 502 return main_thread_only().is_enabled;
500 } 503 }
501 504
502 bool TaskQueueImpl::IsEmpty() const { 505 bool TaskQueueImpl::IsEmpty() const {
503 if (!main_thread_only().delayed_work_queue->Empty() || 506 if (!main_thread_only().delayed_work_queue->Empty() ||
504 !main_thread_only().immediate_work_queue->Empty()) { 507 !main_thread_only().immediate_work_queue->Empty()) {
505 return false; 508 return false;
506 } 509 }
507 510
508 base::AutoLock lock(any_thread_lock_); 511 base::AutoLock lock(any_thread_lock_);
509 return any_thread().immediate_incoming_queue.empty() && 512 return any_thread().immediate_incoming_queue.empty() &&
510 main_thread_only().delayed_incoming_queue.empty(); 513 main_thread_only().delayed_incoming_queue.empty();
511 } 514 }
512 515
513 bool TaskQueueImpl::HasPendingImmediateWork() const { 516 bool TaskQueueImpl::HasPendingImmediateWork() const {
517 // Any work queue tasks count as immediate work.
514 if (!main_thread_only().delayed_work_queue->Empty() || 518 if (!main_thread_only().delayed_work_queue->Empty() ||
515 !main_thread_only().immediate_work_queue->Empty()) { 519 !main_thread_only().immediate_work_queue->Empty()) {
516 return true; 520 return true;
517 } 521 }
518 522
519 return NeedsPumping(); 523 // Tasks on |delayed_incoming_queue| that could run now, count as
520 } 524 // immediate work.
521 525 if (!main_thread_only().delayed_incoming_queue.empty() &&
522 bool TaskQueueImpl::NeedsPumping() const { 526 main_thread_only().delayed_incoming_queue.begin()->delayed_run_time <=
523 if (!main_thread_only().immediate_work_queue->Empty()) 527 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; 528 return true;
568 } 529 }
569 530
570 return task->enqueue_order() < enqueue_order; 531 // Finally tasks on |immediate_incoming_queue| count as immediate work.
571 } 532 base::AutoLock lock(any_thread_lock_);
572 533 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 } 534 }
595 535
596 void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) { 536 void TaskQueueImpl::MoveReadyDelayedTasksToDelayedWorkQueue(LazyNow* lazy_now) {
597 // Enqueue all delayed tasks that should be running now. 537 // Enqueue all delayed tasks that should be running now.
598 while (!main_thread_only().delayed_incoming_queue.empty()) { 538 while (!main_thread_only().delayed_incoming_queue.empty()) {
599 DelayedRunTimeQueue::iterator next_task = 539 DelayedRunTimeQueue::iterator next_task =
600 main_thread_only().delayed_incoming_queue.begin(); 540 main_thread_only().delayed_incoming_queue.begin();
601 if (next_task->delayed_run_time > lazy_now->Now()) 541 if (next_task->delayed_run_time > lazy_now->Now())
602 break; 542 break;
603 // TODO(alexclarke): Use extract() when C++17 is allowed. 543 // TODO(alexclarke): Use extract() when C++17 is allowed.
604 Task& task = const_cast<Task&>(*next_task); 544 Task& task = const_cast<Task&>(*next_task);
605 task.set_enqueue_order( 545 task.set_enqueue_order(
606 main_thread_only().task_queue_manager->GetNextSequenceNumber()); 546 main_thread_only().task_queue_manager->GetNextSequenceNumber());
607 main_thread_only().delayed_work_queue->Push(std::move(task)); 547 main_thread_only().delayed_work_queue->Push(std::move(task));
608 main_thread_only().delayed_incoming_queue.erase(next_task); 548 main_thread_only().delayed_incoming_queue.erase(next_task);
609 } 549 }
610 } 550 }
611 551
612 void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now, 552 void TaskQueueImpl::UpdateDelayedWorkQueue(LazyNow* lazy_now) {
613 bool should_trigger_wakeup,
614 const Task* previous_task) {
615 if (!main_thread_only().task_queue_manager) 553 if (!main_thread_only().task_queue_manager)
616 return; 554 return;
617 if (!ShouldAutoPumpDelayedQueue(should_trigger_wakeup, previous_task))
618 return;
619 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now); 555 MoveReadyDelayedTasksToDelayedWorkQueue(lazy_now);
620 TraceQueueSize(false); 556 TraceQueueSize(false);
621 } 557 }
622 558
623 void TaskQueueImpl::UpdateImmediateWorkQueue(bool should_trigger_wakeup, 559 void TaskQueueImpl::UpdateImmediateWorkQueue() {
624 const Task* previous_task) {
625 DCHECK(main_thread_only().immediate_work_queue->Empty()); 560 DCHECK(main_thread_only().immediate_work_queue->Empty());
626 base::AutoLock lock(any_thread_lock_); 561 base::AutoLock lock(any_thread_lock_);
627 if (!main_thread_only().task_queue_manager) 562 if (!main_thread_only().task_queue_manager)
628 return; 563 return;
629 if (!ShouldAutoPumpImmediateQueueLocked(should_trigger_wakeup, previous_task))
630 return;
631 564
632 main_thread_only().immediate_work_queue->SwapLocked( 565 main_thread_only().immediate_work_queue->SwapLocked(
633 any_thread().immediate_incoming_queue); 566 any_thread().immediate_incoming_queue);
634 567
635 // |any_thread().immediate_incoming_queue| is now empty so 568 // |any_thread().immediate_incoming_queue| is now empty so
636 // TimeDomain::UpdateQueues no longer needs to consider this queue for 569 // TimeDomain::UpdateQueues no longer needs to consider this queue for
637 // reloading. 570 // reloading.
638 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this); 571 main_thread_only().time_domain->UnregisterAsUpdatableTaskQueue(this);
639 } 572 }
640 573
(...skipping 15 matching lines...) Expand all
656 any_thread_lock_.AssertAcquired(); 589 any_thread_lock_.AssertAcquired();
657 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(), 590 TRACE_COUNTER1(disabled_by_default_tracing_category_, GetName(),
658 any_thread().immediate_incoming_queue.size() + 591 any_thread().immediate_incoming_queue.size() +
659 main_thread_only().immediate_work_queue->Size() + 592 main_thread_only().immediate_work_queue->Size() +
660 main_thread_only().delayed_work_queue->Size() + 593 main_thread_only().delayed_work_queue->Size() +
661 main_thread_only().delayed_incoming_queue.size()); 594 main_thread_only().delayed_incoming_queue.size());
662 if (!is_locked) 595 if (!is_locked)
663 any_thread_lock_.Release(); 596 any_thread_lock_.Release();
664 } 597 }
665 598
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 { 599 const char* TaskQueueImpl::GetName() const {
717 return name_; 600 return name_;
718 } 601 }
719 602
720 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) { 603 void TaskQueueImpl::SetQueuePriority(QueuePriority priority) {
721 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority()) 604 if (!main_thread_only().task_queue_manager || priority == GetQueuePriority())
722 return; 605 return;
723 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this, 606 main_thread_only().task_queue_manager->selector_.SetQueuePriority(this,
724 priority); 607 priority);
725 } 608 }
726 609
727 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const { 610 TaskQueueImpl::QueuePriority TaskQueueImpl::GetQueuePriority() const {
728 size_t set_index = immediate_work_queue()->work_queue_set_index(); 611 size_t set_index = immediate_work_queue()->work_queue_set_index();
729 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index()); 612 DCHECK_EQ(set_index, delayed_work_queue()->work_queue_set_index());
730 return static_cast<TaskQueue::QueuePriority>(set_index); 613 return static_cast<TaskQueue::QueuePriority>(set_index);
731 } 614 }
732 615
733 // static 616 // 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) { 617 const char* TaskQueueImpl::PriorityToString(QueuePriority priority) {
765 switch (priority) { 618 switch (priority) {
766 case CONTROL_PRIORITY: 619 case CONTROL_PRIORITY:
767 return "control"; 620 return "control";
768 case HIGH_PRIORITY: 621 case HIGH_PRIORITY:
769 return "high"; 622 return "high";
770 case NORMAL_PRIORITY: 623 case NORMAL_PRIORITY:
771 return "normal"; 624 return "normal";
772 case BEST_EFFORT_PRIORITY: 625 case BEST_EFFORT_PRIORITY:
773 return "best_effort"; 626 return "best_effort";
774 default: 627 default:
775 NOTREACHED(); 628 NOTREACHED();
776 return nullptr; 629 return nullptr;
777 } 630 }
778 } 631 }
779 632
780 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const { 633 void TaskQueueImpl::AsValueInto(base::trace_event::TracedValue* state) const {
781 base::AutoLock lock(any_thread_lock_); 634 base::AutoLock lock(any_thread_lock_);
782 state->BeginDictionary(); 635 state->BeginDictionary();
783 state->SetString("name", GetName()); 636 state->SetString("name", GetName());
784 state->SetBoolean("enabled", main_thread_only().is_enabled); 637 state->SetBoolean("enabled", main_thread_only().is_enabled);
785 state->SetString("time_domain_name", 638 state->SetString("time_domain_name",
786 main_thread_only().time_domain->GetName()); 639 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; 640 bool verbose_tracing_enabled = false;
790 TRACE_EVENT_CATEGORY_GROUP_ENABLED( 641 TRACE_EVENT_CATEGORY_GROUP_ENABLED(
791 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled); 642 disabled_by_default_verbose_tracing_category_, &verbose_tracing_enabled);
792 state->SetInteger("immediate_incoming_queue_size", 643 state->SetInteger("immediate_incoming_queue_size",
793 any_thread().immediate_incoming_queue.size()); 644 any_thread().immediate_incoming_queue.size());
794 state->SetInteger("delayed_incoming_queue_size", 645 state->SetInteger("delayed_incoming_queue_size",
795 main_thread_only().delayed_incoming_queue.size()); 646 main_thread_only().delayed_incoming_queue.size());
796 state->SetInteger("immediate_work_queue_size", 647 state->SetInteger("immediate_work_queue_size",
797 main_thread_only().immediate_work_queue->Size()); 648 main_thread_only().immediate_work_queue->Size());
798 state->SetInteger("delayed_work_queue_size", 649 state->SetInteger("delayed_work_queue_size",
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 728
878 base::AutoLock lock(any_thread_lock_); 729 base::AutoLock lock(any_thread_lock_);
879 return any_thread().time_domain; 730 return any_thread().time_domain;
880 } 731 }
881 732
882 void TaskQueueImpl::SetBlameContext( 733 void TaskQueueImpl::SetBlameContext(
883 base::trace_event::BlameContext* blame_context) { 734 base::trace_event::BlameContext* blame_context) {
884 main_thread_only().blame_context = blame_context; 735 main_thread_only().blame_context = blame_context;
885 } 736 }
886 737
738 void TaskQueueImpl::InsertFence() {
739 if (!main_thread_only().task_queue_manager)
740 return;
741
742 EnqueueOrder previous_fence = main_thread_only().current_fence;
743 main_thread_only().current_fence =
744 main_thread_only().task_queue_manager->GetNextSequenceNumber();
745
746 // Tasks posted after this point will have a strictly higher enqueue order
747 // and will be blocked from running.
748 bool task_unblocked = main_thread_only().immediate_work_queue->InsertFence(
749 main_thread_only().current_fence);
750 task_unblocked |= main_thread_only().delayed_work_queue->InsertFence(
751 main_thread_only().current_fence);
752
753 if (!task_unblocked && previous_fence) {
754 base::AutoLock lock(any_thread_lock_);
755 if (!any_thread().immediate_incoming_queue.empty() &&
756 any_thread().immediate_incoming_queue.begin()->enqueue_order() >
757 previous_fence &&
758 any_thread().immediate_incoming_queue.begin()->enqueue_order() <
759 main_thread_only().current_fence) {
760 task_unblocked = true;
761 }
762 }
763
764 if (main_thread_only().is_enabled && task_unblocked) {
765 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
766 FROM_HERE);
767 }
768 }
769
770 void TaskQueueImpl::RemoveFence() {
771 if (!main_thread_only().task_queue_manager)
772 return;
773
774 EnqueueOrder previous_fence = main_thread_only().current_fence;
775 main_thread_only().current_fence = 0;
776
777 bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence();
778 task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence();
779
780 if (!task_unblocked && previous_fence) {
781 base::AutoLock lock(any_thread_lock_);
782 if (!any_thread().immediate_incoming_queue.empty() &&
783 any_thread().immediate_incoming_queue.begin()->enqueue_order() >
784 previous_fence) {
785 task_unblocked = true;
786 }
787 }
788
789 if (main_thread_only().is_enabled && task_unblocked) {
790 main_thread_only().task_queue_manager->MaybeScheduleImmediateWork(
791 FROM_HERE);
792 }
793 }
794
795 bool TaskQueueImpl::BlockedByFence() const {
796 if (!main_thread_only().current_fence)
797 return false;
798
799 if (!main_thread_only().immediate_work_queue->BlockedByFence() ||
800 !main_thread_only().delayed_work_queue->BlockedByFence()) {
801 return false;
802 }
803
804 base::AutoLock lock(any_thread_lock_);
805 if (any_thread().immediate_incoming_queue.empty())
806 return true;
807
808 return any_thread().immediate_incoming_queue.begin()->enqueue_order() >
809 main_thread_only().current_fence;
810 }
811
812 bool TaskQueueImpl::BlockedByFenceLocked() const {
813 if (!main_thread_only().current_fence)
814 return false;
815
816 if (!main_thread_only().immediate_work_queue->BlockedByFence() ||
817 !main_thread_only().delayed_work_queue->BlockedByFence()) {
818 return false;
819 }
820
821 if (any_thread().immediate_incoming_queue.empty())
822 return true;
823
824 return any_thread().immediate_incoming_queue.begin()->enqueue_order() >
825 main_thread_only().current_fence;
826 }
827
887 // static 828 // static
888 void TaskQueueImpl::QueueAsValueInto(const ComparatorQueue& queue, 829 void TaskQueueImpl::QueueAsValueInto(const ComparatorQueue& queue,
889 base::trace_event::TracedValue* state) { 830 base::trace_event::TracedValue* state) {
890 for (const Task& task : queue) { 831 for (const Task& task : queue) {
891 TaskAsValueInto(task, state); 832 TaskAsValueInto(task, state);
892 } 833 }
893 } 834 }
894 835
895 // static 836 // static
896 void TaskQueueImpl::QueueAsValueInto(const DelayedRunTimeQueue& queue, 837 void TaskQueueImpl::QueueAsValueInto(const DelayedRunTimeQueue& queue,
(...skipping 19 matching lines...) Expand all
916 state->SetBoolean("is_high_res", task.is_high_res); 857 state->SetBoolean("is_high_res", task.is_high_res);
917 state->SetDouble( 858 state->SetDouble(
918 "delayed_run_time", 859 "delayed_run_time",
919 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); 860 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L);
920 state->EndDictionary(); 861 state->EndDictionary();
921 } 862 }
922 863
923 } // namespace internal 864 } // namespace internal
924 } // namespace scheduler 865 } // namespace scheduler
925 } // namespace blink 866 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698