| 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 // TODO(scheduler-dev): Should we also clear the other queues here too? | 162 // TODO(scheduler-dev): Should we also clear the other queues here too? |
| 158 delayed_task_queue_ = base::DelayedTaskQueue(); | 163 delayed_task_queue_ = base::DelayedTaskQueue(); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 314 |
| 310 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { | 315 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { |
| 311 base::PendingTask pending_task = work_queue_.front(); | 316 base::PendingTask pending_task = work_queue_.front(); |
| 312 work_queue_.pop(); | 317 work_queue_.pop(); |
| 313 TraceQueueSize(false); | 318 TraceQueueSize(false); |
| 314 return pending_task; | 319 return pending_task; |
| 315 } | 320 } |
| 316 | 321 |
| 317 void TaskQueue::TraceQueueSize(bool is_locked) const { | 322 void TaskQueue::TraceQueueSize(bool is_locked) const { |
| 318 bool is_tracing; | 323 bool is_tracing; |
| 319 TRACE_EVENT_CATEGORY_GROUP_ENABLED( | 324 TRACE_EVENT_CATEGORY_GROUP_ENABLED(disabled_by_default_tracing_category_, |
| 320 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); | 325 &is_tracing); |
| 321 if (!is_tracing || !name_) | 326 if (!is_tracing || !name_) |
| 322 return; | 327 return; |
| 323 if (!is_locked) | 328 if (!is_locked) |
| 324 lock_.Acquire(); | 329 lock_.Acquire(); |
| 325 else | 330 else |
| 326 lock_.AssertAcquired(); | 331 lock_.AssertAcquired(); |
| 327 TRACE_COUNTER1( | 332 TRACE_COUNTER1( |
| 328 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), name_, | 333 disabled_by_default_tracing_category_, name_, |
| 329 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); | 334 incoming_queue_.size() + work_queue_.size() + delayed_task_queue_.size()); |
| 330 if (!is_locked) | 335 if (!is_locked) |
| 331 lock_.Release(); | 336 lock_.Release(); |
| 332 } | 337 } |
| 333 | 338 |
| 334 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { | 339 void TaskQueue::EnqueueTaskLocked(const base::PendingTask& pending_task) { |
| 335 lock_.AssertAcquired(); | 340 lock_.AssertAcquired(); |
| 336 if (!task_queue_manager_) | 341 if (!task_queue_manager_) |
| 337 return; | 342 return; |
| 338 if (pump_policy_ == TaskQueueManager::PumpPolicy::AUTO && | 343 if (pump_policy_ == TaskQueueManager::PumpPolicy::AUTO && |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 "delayed_run_time", | 447 "delayed_run_time", |
| 443 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); | 448 (task.delayed_run_time - base::TimeTicks()).InMicroseconds() / 1000.0L); |
| 444 state->EndDictionary(); | 449 state->EndDictionary(); |
| 445 } | 450 } |
| 446 | 451 |
| 447 } // namespace internal | 452 } // namespace internal |
| 448 | 453 |
| 449 TaskQueueManager::TaskQueueManager( | 454 TaskQueueManager::TaskQueueManager( |
| 450 size_t task_queue_count, | 455 size_t task_queue_count, |
| 451 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, | 456 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner, |
| 452 TaskQueueSelector* selector) | 457 TaskQueueSelector* selector, |
| 458 const char* disabled_by_default_tracing_category) |
| 453 : main_task_runner_(main_task_runner), | 459 : main_task_runner_(main_task_runner), |
| 454 selector_(selector), | 460 selector_(selector), |
| 455 pending_dowork_count_(0), | 461 pending_dowork_count_(0), |
| 456 work_batch_size_(1), | 462 work_batch_size_(1), |
| 457 time_source_(nullptr), | 463 time_source_(nullptr), |
| 464 disabled_by_default_tracing_category_( |
| 465 disabled_by_default_tracing_category), |
| 458 weak_factory_(this) { | 466 weak_factory_(this) { |
| 459 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); | 467 DCHECK(main_task_runner->RunsTasksOnCurrentThread()); |
| 460 TRACE_EVENT_OBJECT_CREATED_WITH_ID( | 468 TRACE_EVENT_OBJECT_CREATED_WITH_ID(disabled_by_default_tracing_category, |
| 461 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", | 469 "TaskQueueManager", this); |
| 462 this); | |
| 463 | 470 |
| 464 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); | 471 task_queue_manager_weak_ptr_ = weak_factory_.GetWeakPtr(); |
| 465 for (size_t i = 0; i < task_queue_count; i++) { | 472 for (size_t i = 0; i < task_queue_count; i++) { |
| 466 scoped_refptr<internal::TaskQueue> queue( | 473 scoped_refptr<internal::TaskQueue> queue(make_scoped_refptr( |
| 467 make_scoped_refptr(new internal::TaskQueue(this))); | 474 new internal::TaskQueue(this, disabled_by_default_tracing_category))); |
| 468 queues_.push_back(queue); | 475 queues_.push_back(queue); |
| 469 } | 476 } |
| 470 | 477 |
| 471 std::vector<const base::TaskQueue*> work_queues; | 478 std::vector<const base::TaskQueue*> work_queues; |
| 472 for (const auto& queue: queues_) | 479 for (const auto& queue : queues_) |
| 473 work_queues.push_back(&queue->work_queue()); | 480 work_queues.push_back(&queue->work_queue()); |
| 474 selector_->RegisterWorkQueues(work_queues); | 481 selector_->RegisterWorkQueues(work_queues); |
| 475 } | 482 } |
| 476 | 483 |
| 477 TaskQueueManager::~TaskQueueManager() { | 484 TaskQueueManager::~TaskQueueManager() { |
| 478 TRACE_EVENT_OBJECT_DELETED_WITH_ID( | 485 TRACE_EVENT_OBJECT_DELETED_WITH_ID(disabled_by_default_tracing_category_, |
| 479 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", | 486 "TaskQueueManager", this); |
| 480 this); | |
| 481 for (auto& queue : queues_) | 487 for (auto& queue : queues_) |
| 482 queue->WillDeleteTaskQueueManager(); | 488 queue->WillDeleteTaskQueueManager(); |
| 483 } | 489 } |
| 484 | 490 |
| 485 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { | 491 internal::TaskQueue* TaskQueueManager::Queue(size_t queue_index) const { |
| 486 DCHECK_LT(queue_index, queues_.size()); | 492 DCHECK_LT(queue_index, queues_.size()); |
| 487 return queues_[queue_index].get(); | 493 return queues_[queue_index].get(); |
| 488 } | 494 } |
| 489 | 495 |
| 490 scoped_refptr<base::SingleThreadTaskRunner> | 496 scoped_refptr<base::SingleThreadTaskRunner> |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); | 598 ProcessTaskFromWorkQueue(queue_index, i > 0, &previous_task); |
| 593 | 599 |
| 594 if (!UpdateWorkQueues(&previous_task)) | 600 if (!UpdateWorkQueues(&previous_task)) |
| 595 return; | 601 return; |
| 596 } | 602 } |
| 597 } | 603 } |
| 598 | 604 |
| 599 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { | 605 bool TaskQueueManager::SelectWorkQueueToService(size_t* out_queue_index) { |
| 600 bool should_run = selector_->SelectWorkQueueToService(out_queue_index); | 606 bool should_run = selector_->SelectWorkQueueToService(out_queue_index); |
| 601 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | 607 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( |
| 602 TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", this, | 608 disabled_by_default_tracing_category_, "TaskQueueManager", this, |
| 603 AsValueWithSelectorResult(should_run, *out_queue_index)); | 609 AsValueWithSelectorResult(should_run, *out_queue_index)); |
| 604 return should_run; | 610 return should_run; |
| 605 } | 611 } |
| 606 | 612 |
| 607 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { | 613 void TaskQueueManager::DidQueueTask(base::PendingTask* pending_task) { |
| 608 pending_task->sequence_num = task_sequence_num_.GetNext(); | 614 pending_task->sequence_num = task_sequence_num_.GetNext(); |
| 609 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); | 615 task_annotator_.DidQueueTask("TaskQueueManager::PostTask", *pending_task); |
| 610 } | 616 } |
| 611 | 617 |
| 612 void TaskQueueManager::ProcessTaskFromWorkQueue( | 618 void TaskQueueManager::ProcessTaskFromWorkQueue( |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 698 state->EndArray(); | 704 state->EndArray(); |
| 699 state->BeginDictionary("selector"); | 705 state->BeginDictionary("selector"); |
| 700 selector_->AsValueInto(state.get()); | 706 selector_->AsValueInto(state.get()); |
| 701 state->EndDictionary(); | 707 state->EndDictionary(); |
| 702 if (should_run) | 708 if (should_run) |
| 703 state->SetInteger("selected_queue", selected_queue); | 709 state->SetInteger("selected_queue", selected_queue); |
| 704 return state; | 710 return state; |
| 705 } | 711 } |
| 706 | 712 |
| 707 } // namespace content | 713 } // namespace content |
| OLD | NEW |