| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/renderer/scheduler/task_queue_manager.h" | 5 #include "content/child/scheduler/task_queue_manager.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 12 #include "base/trace_event/trace_event_argument.h" | 12 #include "base/trace_event/trace_event_argument.h" |
| 13 #include "cc/test/test_now_source.h" | 13 #include "cc/test/test_now_source.h" |
| 14 #include "content/renderer/scheduler/nestable_single_thread_task_runner.h" | 14 #include "content/child/scheduler/nestable_single_thread_task_runner.h" |
| 15 #include "content/renderer/scheduler/task_queue_selector.h" | 15 #include "content/child/scheduler/task_queue_selector.h" |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max(); | 18 const int64_t kMaxTimeTicks = std::numeric_limits<int64>::max(); |
| 19 } | 19 } |
| 20 | 20 |
| 21 namespace content { | 21 namespace content { |
| 22 namespace internal { | 22 namespace internal { |
| 23 | 23 |
| 24 // Now() is somewhat expensive so it makes sense not to call Now() unless we | 24 // Now() is somewhat expensive so it makes sense not to call Now() unless we |
| 25 // really need to. | 25 // really need to. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 39 return now_; | 39 return now_; |
| 40 } | 40 } |
| 41 | 41 |
| 42 private: | 42 private: |
| 43 TaskQueueManager* task_queue_manager_; // NOT OWNED | 43 TaskQueueManager* task_queue_manager_; // NOT OWNED |
| 44 base::TimeTicks now_; | 44 base::TimeTicks now_; |
| 45 }; | 45 }; |
| 46 | 46 |
| 47 class TaskQueue : public base::SingleThreadTaskRunner { | 47 class TaskQueue : public base::SingleThreadTaskRunner { |
| 48 public: | 48 public: |
| 49 TaskQueue(TaskQueueManager* task_queue_manager); | 49 TaskQueue(TaskQueueManager* task_queue_manager, |
| 50 const char* disabled_by_default_tracing_category); |
| 50 | 51 |
| 51 // base::SingleThreadTaskRunner implementation. | 52 // base::SingleThreadTaskRunner implementation. |
| 52 bool RunsTasksOnCurrentThread() const override; | 53 bool RunsTasksOnCurrentThread() const override; |
| 53 bool PostDelayedTask(const tracked_objects::Location& from_here, | 54 bool PostDelayedTask(const tracked_objects::Location& from_here, |
| 54 const base::Closure& task, | 55 const base::Closure& task, |
| 55 base::TimeDelta delay) override { | 56 base::TimeDelta delay) override { |
| 56 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); | 57 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NORMAL); |
| 57 } | 58 } |
| 58 | 59 |
| 59 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | 60 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 base::trace_event::TracedValue* state); | 126 base::trace_event::TracedValue* state); |
| 126 | 127 |
| 127 // This lock protects all members except the work queue and the | 128 // This lock protects all members except the work queue and the |
| 128 // main_thread_checker_. | 129 // main_thread_checker_. |
| 129 mutable base::Lock lock_; | 130 mutable base::Lock lock_; |
| 130 base::PlatformThreadId thread_id_; | 131 base::PlatformThreadId thread_id_; |
| 131 TaskQueueManager* task_queue_manager_; | 132 TaskQueueManager* task_queue_manager_; |
| 132 base::TaskQueue incoming_queue_; | 133 base::TaskQueue incoming_queue_; |
| 133 TaskQueueManager::PumpPolicy pump_policy_; | 134 TaskQueueManager::PumpPolicy pump_policy_; |
| 134 const char* name_; | 135 const char* name_; |
| 136 const char* disabled_by_default_tracing_category_; |
| 135 base::DelayedTaskQueue delayed_task_queue_; | 137 base::DelayedTaskQueue delayed_task_queue_; |
| 136 std::set<base::TimeTicks> in_flight_kick_delayed_tasks_; | 138 std::set<base::TimeTicks> in_flight_kick_delayed_tasks_; |
| 137 | 139 |
| 138 base::ThreadChecker main_thread_checker_; | 140 base::ThreadChecker main_thread_checker_; |
| 139 base::TaskQueue work_queue_; | 141 base::TaskQueue work_queue_; |
| 140 | 142 |
| 141 DISALLOW_COPY_AND_ASSIGN(TaskQueue); | 143 DISALLOW_COPY_AND_ASSIGN(TaskQueue); |
| 142 }; | 144 }; |
| 143 | 145 |
| 144 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager) | 146 TaskQueue::TaskQueue(TaskQueueManager* task_queue_manager, |
| 147 const char* disabled_by_default_tracing_category) |
| 145 : thread_id_(base::PlatformThread::CurrentId()), | 148 : thread_id_(base::PlatformThread::CurrentId()), |
| 146 task_queue_manager_(task_queue_manager), | 149 task_queue_manager_(task_queue_manager), |
| 147 pump_policy_(TaskQueueManager::PumpPolicy::AUTO), | 150 pump_policy_(TaskQueueManager::PumpPolicy::AUTO), |
| 148 name_(nullptr) { | 151 name_(nullptr), |
| 152 disabled_by_default_tracing_category_( |
| 153 disabled_by_default_tracing_category) { |
| 149 } | 154 } |
| 150 | 155 |
| 151 TaskQueue::~TaskQueue() { | 156 TaskQueue::~TaskQueue() { |
| 152 } | 157 } |
| 153 | 158 |
| 154 void TaskQueue::WillDeleteTaskQueueManager() { | 159 void TaskQueue::WillDeleteTaskQueueManager() { |
| 155 base::AutoLock lock(lock_); | 160 base::AutoLock lock(lock_); |
| 156 task_queue_manager_ = nullptr; | 161 task_queue_manager_ = nullptr; |
| 157 delayed_task_queue_ = base::DelayedTaskQueue(); | 162 delayed_task_queue_ = base::DelayedTaskQueue(); |
| 158 incoming_queue_ = base::TaskQueue(); | 163 incoming_queue_ = base::TaskQueue(); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 | 315 |
| 311 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { | 316 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { |
| 312 base::PendingTask pending_task = work_queue_.front(); | 317 base::PendingTask pending_task = work_queue_.front(); |
| 313 work_queue_.pop(); | 318 work_queue_.pop(); |
| 314 TraceQueueSize(false); | 319 TraceQueueSize(false); |
| 315 return pending_task; | 320 return pending_task; |
| 316 } | 321 } |
| 317 | 322 |
| 318 void TaskQueue::TraceQueueSize(bool is_locked) const { | 323 void TaskQueue::TraceQueueSize(bool is_locked) const { |
| 319 bool is_tracing; | 324 bool is_tracing; |
| 320 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 325 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, |
| 321 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); | 326 &is_tracing); |
| 322 if (!is_tracing || !name_) | 327 if (!is_tracing || !name_) |
| 323 return; | 328 return; |
| 324 if (!is_locked) | 329 if (!is_locked) |
| 325 lock_.Acquire(); | 330 lock_.Acquire(); |
| 326 else | 331 else |
| 327 lock_.AssertAcquired(); | 332 lock_.AssertAcquired(); |
| 328 TRACE_COUNTER1( | 333 TRACE_COUNTER1( |
| 329 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, | 334 disabled_by_default_tracing_category_, name_, |
| 330 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); | 335 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); |
| 331 if (!is_locked) | 336 if (!is_locked) |
| 332 lock_.Release(); | 337 lock_.Release(); |
| 333 } | 338 } |
| 334 | 339 |
| 335 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { | 340 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { |
| 336 lock_.AssertAcquired(); | 341 lock_.AssertAcquired(); |
| 337 if (!task_queue_manager_) | 342 if (!task_queue_manager_) |
| 338 return; | 343 return; |
| 339 if (pump_policy_ == TaskQueueManager::PumpPolicy::AUTO && | 344 if (pump_policy_ == TaskQueueManager::PumpPolicy::AUTO && |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 "delayed_run_time", | 448 "delayed_run_time", |
| 444 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 449 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
| 445 state->EndDictionary(); | 450 state->EndDictionary(); |
| 446 } | 451 } |
| 447 | 452 |
| 448 } // namespace internal | 453 } // namespace internal |
| 449 | 454 |
| 450 TaskQueueManager::TaskQueueManager( | 455 TaskQueueManager::TaskQueueManager( |
| 451 size_t task_queue_count, | 456 size_t task_queue_count, |
| 452 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, | 457 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, |
| 453 TaskQueueSelector* selector) | 458 TaskQueueSelector* selector, |
| 459 const char* disabled_by_default_tracing_category) |
| 454 : main_task_runner_(main_task_runner), | 460 : main_task_runner_(main_task_runner), |
| 455 selector_(selector), | 461 selector_(selector), |
| 456 pending_dowork_count_(0), | 462 pending_dowork_count_(0), |
| 457 work_batch_size_(1), | 463 work_batch_size_(1), |
| 458 time_source_(nullptr), | 464 time_source_(nullptr), |
| 465 disabled_by_default_tracing_category_( |
| 466 disabled_by_default_tracing_category), |
| 459 weak_factory_(this) { | 467 weak_factory_(this) { |
| 460 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); | 468 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); |
| 461 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | 469 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, |
| 462 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", | 470 "TaskQueueManager", this); |
| 463 this); | |
| 464 | 471 |
| 465 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); | 472 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); |
| 466 for (size_t i = 0; i < task_queue_count; i++) { | 473 for (size_t i = 0; i < task_queue_count; i++) { |
| 467 scoped_refptr<internal::TaskQueue> queue( | 474 scoped_refptr<internal::TaskQueue> queue(make_scoped_refptr( |
| 468 make_scoped_refptr(new internal::TaskQueue(this))); | 475 new internal::TaskQueue(this, disabled_by_default_tracing_category))); |
| 469 queues_.push_back(queue); | 476 queues_.push_back(queue); |
| 470 } | 477 } |
| 471 | 478 |
| 472 std::vector<const base::TaskQueue*> work_queues; | 479 std::vector<const base::TaskQueue*> work_queues; |
| 473 for (const auto& queue: queues_) | 480 for (const auto& queue : queues_) |
| 474 work_queues.push_back(&queue->work_queue()); | 481 work_queues.push_back(&queue->work_queue()); |
| 475 selector_->RegisterWorkQueues(work_queues); | 482 selector_->RegisterWorkQueues(work_queues); |
| 476 } | 483 } |
| 477 | 484 |
| 478 TaskQueueManager::~TaskQueueManager() { | 485 TaskQueueManager::~TaskQueueManager() { |
| 479 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 486 TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_, |
| 480 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", | 487 "TaskQueueManager", this); |
| 481 this); | |
| 482 for (auto& queue : queues_) | 488 for (auto& queue : queues_) |
| 483 queue->WillDeleteTaskQueueManager(); | 489 queue->WillDeleteTaskQueueManager(); |
| 484 } | 490 } |
| 485 | 491 |
| 486 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { | 492 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { |
| 487 DCHECK_LT(queue_index, queues_.size()); | 493 DCHECK_LT(queue_index, queues_.size()); |
| 488 return queues_[queue_index].get(); | 494 return queues_[queue_index].get(); |
| 489 } | 495 } |
| 490 | 496 |
| 491 scoped_refptr<base::SingleThreadTaskRunner> | 497 scoped_refptr<base::SingleThreadTaskRunner> |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); | 599 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); |
| 594 | 600 |
| 595 if (!UpdateWorkQueues(&previous_task)) | 601 if (!UpdateWorkQueues(&previous_task)) |
| 596 return; | 602 return; |
| 597 } | 603 } |
| 598 } | 604 } |
| 599 | 605 |
| 600 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { | 606 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { |
| 601 bool should_run = selector_->SelectWorkQueueToService(out_queue_index); | 607 bool should_run = selector_->SelectWorkQueueToService(out_queue_index); |
| 602 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 608 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
| 603 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", this, | 609 disabled_by_default_tracing_category_, "TaskQueueManager", this, |
| 604 AsValueWithSelectorResult(should_run, *out_queue_index)); | 610 AsValueWithSelectorResult(should_run, *out_queue_index)); |
| 605 return should_run; | 611 return should_run; |
| 606 } | 612 } |
| 607 | 613 |
| 608 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { | 614 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { |
| 609 pending_task->sequence_num = task_sequence_num_.GetNext(); | 615 pending_task->sequence_num = task_sequence_num_.GetNext(); |
| 610 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); | 616 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); |
| 611 } | 617 } |
| 612 | 618 |
| 613 void TaskQueueManager::ProcessTaskFromWorkQueue( | 619 void TaskQueueManager::ProcessTaskFromWorkQueue( |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 state->EndArray(); | 705 state->EndArray(); |
| 700 state->BeginDictionary("selector"); | 706 state->BeginDictionary("selector"); |
| 701 selector_->AsValueInto(state.get()); | 707 selector_->AsValueInto(state.get()); |
| 702 state->EndDictionary(); | 708 state->EndDictionary(); |
| 703 if (should_run) | 709 if (should_run) |
| 704 state->SetInteger("selected_queue", selected_queue); | 710 state->SetInteger("selected_queue", selected_queue); |
| 705 return state; | 711 return state; |
| 706 } | 712 } |
| 707 | 713 |
| 708 } // namespace content | 714 } // namespace content |
| OLD | NEW |