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

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

Issue 2640763003: Optimize away updatable_queue_set_ (Closed)
Patch Set: Fix lock issue plus rename OnPushQueue Created 3 years, 11 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/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/trace_event/blame_context.h" 10 #include "base/trace_event/blame_context.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 : task_queue_manager(task_queue_manager), time_domain(time_domain) {} 147 : task_queue_manager(task_queue_manager), time_domain(time_domain) {}
148 148
149 TaskQueueImpl::AnyThread::~AnyThread() {} 149 TaskQueueImpl::AnyThread::~AnyThread() {}
150 150
151 TaskQueueImpl::MainThreadOnly::MainThreadOnly( 151 TaskQueueImpl::MainThreadOnly::MainThreadOnly(
152 TaskQueueManager* task_queue_manager, 152 TaskQueueManager* task_queue_manager,
153 TaskQueueImpl* task_queue, 153 TaskQueueImpl* task_queue,
154 TimeDomain* time_domain) 154 TimeDomain* time_domain)
155 : task_queue_manager(task_queue_manager), 155 : task_queue_manager(task_queue_manager),
156 time_domain(time_domain), 156 time_domain(time_domain),
157 delayed_work_queue(new WorkQueue(task_queue, "delayed")), 157 delayed_work_queue(
158 immediate_work_queue(new WorkQueue(task_queue, "immediate")), 158 new WorkQueue(task_queue, "delayed", WorkQueue::QueueType::DELAYED)),
159 immediate_work_queue(new WorkQueue(task_queue,
160 "immediate",
161 WorkQueue::QueueType::IMMEDIATE)),
159 set_index(0), 162 set_index(0),
160 is_enabled_refcount(0), 163 is_enabled_refcount(0),
161 voter_refcount(0), 164 voter_refcount(0),
162 blame_context(nullptr), 165 blame_context(nullptr),
163 current_fence(0) {} 166 current_fence(0) {}
164 167
165 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {} 168 TaskQueueImpl::MainThreadOnly::~MainThreadOnly() {}
166 169
167 void TaskQueueImpl::UnregisterTaskQueue() { 170 void TaskQueueImpl::UnregisterTaskQueue() {
168 base::AutoLock lock(any_thread_lock_); 171 base::AutoLock lock(any_thread_lock_);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 TraceQueueSize(false); 322 TraceQueueSize(false);
320 } 323 }
321 324
322 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked( 325 void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(
323 const tracked_objects::Location& posted_from, 326 const tracked_objects::Location& posted_from,
324 const base::Closure& task, 327 const base::Closure& task,
325 base::TimeTicks desired_run_time, 328 base::TimeTicks desired_run_time,
326 EnqueueOrder sequence_number, 329 EnqueueOrder sequence_number,
327 bool nestable) { 330 bool nestable) {
328 if (any_thread().immediate_incoming_queue.empty()) 331 if (any_thread().immediate_incoming_queue.empty())
329 any_thread().time_domain->RegisterAsUpdatableTaskQueue(this); 332 any_thread().time_domain->OnQueueHasIncomingImmediateWork(this);
330 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make 333 // If the |immediate_incoming_queue| is empty we need a DoWork posted to make
331 // it run. 334 // it run.
332 if (any_thread().immediate_incoming_queue.empty()) { 335 if (any_thread().immediate_incoming_queue.empty()) {
333 // There's no point posting a DoWork for a disabled queue, however we can 336 // There's no point posting a DoWork for a disabled queue, however we can
334 // only tell if it's disabled from the main thread. 337 // only tell if it's disabled from the main thread.
335 if (base::PlatformThread::CurrentId() == thread_id_) { 338 if (base::PlatformThread::CurrentId() == thread_id_) {
336 if (IsQueueEnabled() && !BlockedByFenceLocked()) 339 if (IsQueueEnabled() && !BlockedByFenceLocked())
337 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 340 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
338 } else { 341 } else {
339 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE); 342 any_thread().task_queue_manager->MaybeScheduleImmediateWork(FROM_HERE);
340 } 343 }
341 } 344 }
342 any_thread().immediate_incoming_queue.emplace_back( 345 any_thread().immediate_incoming_queue.emplace_back(
343 posted_from, task, desired_run_time, sequence_number, nestable, 346 posted_from, task, desired_run_time, sequence_number, nestable,
344 sequence_number); 347 sequence_number);
345 any_thread().task_queue_manager->DidQueueTask( 348 any_thread().task_queue_manager->DidQueueTask(
346 any_thread().immediate_incoming_queue.back()); 349 any_thread().immediate_incoming_queue.back());
347 TraceQueueSize(true); 350 TraceQueueSize(true);
348 } 351 }
349 352
353 void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() {
354 if (!main_thread_only().immediate_work_queue->Empty())
355 return;
356
357 main_thread_only().immediate_work_queue->ReloadEmptyImmediateQueue();
358 }
359
360 WTF::Deque<TaskQueueImpl::Task> TaskQueueImpl::TakeImmediateIncomingQueue() {
361 base::AutoLock lock(any_thread_lock_);
362 WTF::Deque<TaskQueueImpl::Task> queue;
363 queue.swap(any_thread().immediate_incoming_queue);
364 return queue;
365 }
366
350 bool TaskQueueImpl::IsEmpty() const { 367 bool TaskQueueImpl::IsEmpty() const {
351 if (!main_thread_only().delayed_work_queue->Empty() || 368 if (!main_thread_only().delayed_work_queue->Empty() ||
352 !main_thread_only().delayed_incoming_queue.empty() || 369 !main_thread_only().delayed_incoming_queue.empty() ||
353 !main_thread_only().immediate_work_queue->Empty()) { 370 !main_thread_only().immediate_work_queue->Empty()) {
354 return false; 371 return false;
355 } 372 }
356 373
357 base::AutoLock lock(any_thread_lock_); 374 base::AutoLock lock(any_thread_lock_);
358 return any_thread().immediate_incoming_queue.empty(); 375 return any_thread().immediate_incoming_queue.empty();
359 } 376 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 } 432 }
416 433
417 // Make sure the next wake up is scheduled. 434 // Make sure the next wake up is scheduled.
418 if (!main_thread_only().delayed_incoming_queue.empty()) { 435 if (!main_thread_only().delayed_incoming_queue.empty()) {
419 main_thread_only().time_domain->ScheduleDelayedWork( 436 main_thread_only().time_domain->ScheduleDelayedWork(
420 this, main_thread_only().delayed_incoming_queue.top().delayed_run_time, 437 this, main_thread_only().delayed_incoming_queue.top().delayed_run_time,
421 lazy_now->Now()); 438 lazy_now->Now());
422 } 439 }
423 } 440 }
424 441
425 bool TaskQueueImpl::MaybeUpdateImmediateWorkQueues() {
426 if (!main_thread_only().task_queue_manager)
427 return false;
428
429 if (!main_thread_only().immediate_work_queue->Empty())
430 return true;
431
432 base::AutoLock lock(any_thread_lock_);
433 main_thread_only().immediate_work_queue->SwapLocked(
434 any_thread().immediate_incoming_queue);
435 // |immediate_work_queue| is now empty so updates are no longer required.
436 return false;
437 }
438
439 void TaskQueueImpl::TraceQueueSize(bool is_locked) const { 442 void TaskQueueImpl::TraceQueueSize(bool is_locked) const {
440 bool is_tracing; 443 bool is_tracing;
441 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, 444 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_,
442 &is_tracing); 445 &is_tracing);
443 if (!is_tracing) 446 if (!is_tracing)
444 return; 447 return;
445 448
446 // It's only safe to access the work queues from the main thread. 449 // It's only safe to access the work queues from the main thread.
447 // TODO(alexclarke): We should find another way of tracing this 450 // TODO(alexclarke): We should find another way of tracing this
448 if (base::PlatformThread::CurrentId() != thread_id_) 451 if (base::PlatformThread::CurrentId() != thread_id_)
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 DCHECK(any_thread().time_domain); 573 DCHECK(any_thread().time_domain);
571 if (!any_thread().time_domain) 574 if (!any_thread().time_domain)
572 return; 575 return;
573 DCHECK(main_thread_checker_.CalledOnValidThread()); 576 DCHECK(main_thread_checker_.CalledOnValidThread());
574 if (time_domain == main_thread_only().time_domain) 577 if (time_domain == main_thread_only().time_domain)
575 return; 578 return;
576 579
577 any_thread().time_domain = time_domain; 580 any_thread().time_domain = time_domain;
578 } 581 }
579 // We rely here on TimeDomain::MigrateQueue being thread-safe to use with 582 // We rely here on TimeDomain::MigrateQueue being thread-safe to use with
580 // TimeDomain::Register/UnregisterAsUpdatableTaskQueue. 583 // TimeDomain::Register.
581 main_thread_only().time_domain->MigrateQueue(this, time_domain); 584 main_thread_only().time_domain->MigrateQueue(this, time_domain);
582 main_thread_only().time_domain = time_domain; 585 main_thread_only().time_domain = time_domain;
583 } 586 }
584 587
585 TimeDomain* TaskQueueImpl::GetTimeDomain() const { 588 TimeDomain* TaskQueueImpl::GetTimeDomain() const {
586 if (base::PlatformThread::CurrentId() == thread_id_) 589 if (base::PlatformThread::CurrentId() == thread_id_)
587 return main_thread_only().time_domain; 590 return main_thread_only().time_domain;
588 591
589 base::AutoLock lock(any_thread_lock_); 592 base::AutoLock lock(any_thread_lock_);
590 return any_thread().time_domain; 593 return any_thread().time_domain;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 bool is_enabled = IsQueueEnabled(); 795 bool is_enabled = IsQueueEnabled();
793 if (was_enabled != is_enabled) 796 if (was_enabled != is_enabled)
794 EnableOrDisableWithSelector(is_enabled); 797 EnableOrDisableWithSelector(is_enabled);
795 } 798 }
796 799
797 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) { 800 void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) {
798 if (!main_thread_only().task_queue_manager) 801 if (!main_thread_only().task_queue_manager)
799 return; 802 return;
800 803
801 if (enable) { 804 if (enable) {
802 // Note it's the job of the selector to tell the TaskQueueManager if 805 // Note the selector calls TaskQueueManager::OnTaskQueueEnabled which posts
803 // a DoWork needs posting. 806 // a DoWork if needed.
804 main_thread_only().task_queue_manager->selector_.EnableQueue(this); 807 main_thread_only().task_queue_manager->selector_.EnableQueue(this);
805 } else { 808 } else {
806 main_thread_only().task_queue_manager->selector_.DisableQueue(this); 809 main_thread_only().task_queue_manager->selector_.DisableQueue(this);
807 } 810 }
808 } 811 }
809 812
810 std::unique_ptr<TaskQueueImpl::QueueEnabledVoter> 813 std::unique_ptr<TaskQueueImpl::QueueEnabledVoter>
811 TaskQueueImpl::CreateQueueEnabledVoter() { 814 TaskQueueImpl::CreateQueueEnabledVoter() {
812 main_thread_only().voter_refcount++; 815 main_thread_only().voter_refcount++;
813 main_thread_only().is_enabled_refcount++; 816 main_thread_only().is_enabled_refcount++;
(...skipping 15 matching lines...) Expand all
829 main_thread_only().delayed_incoming_queue.top().delayed_run_time == 832 main_thread_only().delayed_incoming_queue.top().delayed_run_time ==
830 first_task_runtime) { 833 first_task_runtime) {
831 remaining_tasks.push(std::move( 834 remaining_tasks.push(std::move(
832 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()))); 835 const_cast<Task&>(main_thread_only().delayed_incoming_queue.top())));
833 } 836 }
834 main_thread_only().delayed_incoming_queue.pop(); 837 main_thread_only().delayed_incoming_queue.pop();
835 } 838 }
836 main_thread_only().delayed_incoming_queue = std::move(remaining_tasks); 839 main_thread_only().delayed_incoming_queue = std::move(remaining_tasks);
837 } 840 }
838 841
842 void TaskQueueImpl::PushImmediateIncomingTaskForTest(
843 TaskQueueImpl::Task&& task) {
844 base::AutoLock lock(any_thread_lock_);
845 any_thread().immediate_incoming_queue.push_back(std::move(task));
846 }
847
839 } // namespace internal 848 } // namespace internal
840 } // namespace scheduler 849 } // namespace scheduler
841 } // namespace blink 850 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698