| 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/renderer/scheduler/task_queue_manager.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 const base::Closure& task, | 36 const base::Closure& task, |
| 37 base::TimeDelta delay) override { | 37 base::TimeDelta delay) override { |
| 38 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); | 38 return PostDelayedTaskImpl(from_here, task, delay, TaskType::NON_NESTABLE); |
| 39 } | 39 } |
| 40 | 40 |
| 41 bool IsQueueEmpty() const; | 41 bool IsQueueEmpty() const; |
| 42 | 42 |
| 43 void SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy); | 43 void SetPumpPolicy(TaskQueueManager::PumpPolicy pump_policy); |
| 44 void PumpQueue(); | 44 void PumpQueue(); |
| 45 | 45 |
| 46 bool NextPendingDelayedTaskRunTime( |
| 47 base::TimeTicks* next_pending_delayed_task); |
| 48 |
| 46 bool UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task, | 49 bool UpdateWorkQueue(base::TimeTicks* next_pending_delayed_task, |
| 47 const base::PendingTask* previous_task); | 50 const base::PendingTask* previous_task); |
| 48 base::PendingTask TakeTaskFromWorkQueue(); | 51 base::PendingTask TakeTaskFromWorkQueue(); |
| 49 | 52 |
| 50 void WillDeleteTaskQueueManager(); | 53 void WillDeleteTaskQueueManager(); |
| 51 | 54 |
| 52 base::TaskQueue& work_queue() { return work_queue_; } | 55 base::TaskQueue& work_queue() { return work_queue_; } |
| 53 | 56 |
| 54 void set_name(const char* name) { name_ = name; } | 57 void set_name(const char* name) { name_ = name; } |
| 55 | 58 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 70 | 73 |
| 71 // Adds a task at the end of the incoming task queue and schedules a call to | 74 // Adds a task at the end of the incoming task queue and schedules a call to |
| 72 // TaskQueueManager::DoWork() if the incoming queue was empty and automatic | 75 // TaskQueueManager::DoWork() if the incoming queue was empty and automatic |
| 73 // pumping is enabled. Can be called on an arbitrary thread. | 76 // pumping is enabled. Can be called on an arbitrary thread. |
| 74 void EnqueueTask(const base::PendingTask& pending_task); | 77 void EnqueueTask(const base::PendingTask& pending_task); |
| 75 | 78 |
| 76 void PumpQueueLocked(); | 79 void PumpQueueLocked(); |
| 77 bool TaskIsOlderThanQueuedTasks(const base::PendingTask* task); | 80 bool TaskIsOlderThanQueuedTasks(const base::PendingTask* task); |
| 78 bool ShouldAutoPumpQueueLocked(const base::PendingTask* previous_task); | 81 bool ShouldAutoPumpQueueLocked(const base::PendingTask* previous_task); |
| 79 void EnqueueTaskLocked(const base::PendingTask& pending_task); | 82 void EnqueueTaskLocked(const base::PendingTask& pending_task); |
| 83 bool NextPendingDelayedTaskRunTimeLocked( |
| 84 base::TimeTicks* next_pending_delayed_task); |
| 80 | 85 |
| 81 void TraceQueueSize(bool is_locked) const; | 86 void TraceQueueSize(bool is_locked) const; |
| 82 static const char* PumpPolicyToString( | 87 static const char* PumpPolicyToString( |
| 83 TaskQueueManager::PumpPolicy pump_policy); | 88 TaskQueueManager::PumpPolicy pump_policy); |
| 84 static void QueueAsValueInto(const base::TaskQueue& queue, | 89 static void QueueAsValueInto(const base::TaskQueue& queue, |
| 85 base::trace_event::TracedValue* state); | 90 base::trace_event::TracedValue* state); |
| 86 static void TaskAsValueInto(const base::PendingTask& task, | 91 static void TaskAsValueInto(const base::PendingTask& task, |
| 87 base::trace_event::TracedValue* state); | 92 base::trace_event::TracedValue* state); |
| 88 | 93 |
| 89 // This lock protects all members except the work queue. | 94 // This lock protects all members except the work queue. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 if (pump_policy_ == TaskQueueManager::PumpPolicy::MANUAL) | 187 if (pump_policy_ == TaskQueueManager::PumpPolicy::MANUAL) |
| 183 return false; | 188 return false; |
| 184 if (pump_policy_ == TaskQueueManager::PumpPolicy::AFTER_WAKEUP && | 189 if (pump_policy_ == TaskQueueManager::PumpPolicy::AFTER_WAKEUP && |
| 185 TaskIsOlderThanQueuedTasks(previous_task)) | 190 TaskIsOlderThanQueuedTasks(previous_task)) |
| 186 return false; | 191 return false; |
| 187 if (incoming_queue_.empty()) | 192 if (incoming_queue_.empty()) |
| 188 return false; | 193 return false; |
| 189 return true; | 194 return true; |
| 190 } | 195 } |
| 191 | 196 |
| 197 bool TaskQueue::NextPendingDelayedTaskRunTime( |
| 198 base::TimeTicks* next_pending_delayed_task) { |
| 199 base::AutoLock lock(lock_); |
| 200 return NextPendingDelayedTaskRunTimeLocked(next_pending_delayed_task); |
| 201 } |
| 202 |
| 203 bool TaskQueue::NextPendingDelayedTaskRunTimeLocked( |
| 204 base::TimeTicks* next_pending_delayed_task) { |
| 205 lock_.AssertAcquired(); |
| 206 if (!delayed_task_run_times_.empty()) { |
| 207 *next_pending_delayed_task = |
| 208 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); |
| 209 return true; |
| 210 } |
| 211 return false; |
| 212 } |
| 213 |
| 192 bool TaskQueue::UpdateWorkQueue( | 214 bool TaskQueue::UpdateWorkQueue( |
| 193 base::TimeTicks* next_pending_delayed_task, | 215 base::TimeTicks* next_pending_delayed_task, |
| 194 const base::PendingTask* previous_task) { | 216 const base::PendingTask* previous_task) { |
| 195 if (!work_queue_.empty()) | 217 if (!work_queue_.empty()) |
| 196 return true; | 218 return true; |
| 197 | 219 |
| 198 { | 220 { |
| 199 base::AutoLock lock(lock_); | 221 base::AutoLock lock(lock_); |
| 200 if (!delayed_task_run_times_.empty()) { | 222 NextPendingDelayedTaskRunTimeLocked(next_pending_delayed_task); |
| 201 *next_pending_delayed_task = | |
| 202 std::min(*next_pending_delayed_task, delayed_task_run_times_.top()); | |
| 203 } | |
| 204 if (!ShouldAutoPumpQueueLocked(previous_task)) | 223 if (!ShouldAutoPumpQueueLocked(previous_task)) |
| 205 return false; | 224 return false; |
| 206 work_queue_.Swap(&incoming_queue_); | 225 work_queue_.Swap(&incoming_queue_); |
| 207 TraceQueueSize(true); | 226 TraceQueueSize(true); |
| 208 return true; | 227 return true; |
| 209 } | 228 } |
| 210 } | 229 } |
| 211 | 230 |
| 212 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { | 231 base::PendingTask TaskQueue::TakeTaskFromWorkQueue() { |
| 213 base::PendingTask pending_task = work_queue_.front(); | 232 base::PendingTask pending_task = work_queue_.front(); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 scoped_refptr<base::SingleThreadTaskRunner> | 403 scoped_refptr<base::SingleThreadTaskRunner> |
| 385 TaskQueueManager::TaskRunnerForQueue(size_t queue_index) const { | 404 TaskQueueManager::TaskRunnerForQueue(size_t queue_index) const { |
| 386 return Queue(queue_index); | 405 return Queue(queue_index); |
| 387 } | 406 } |
| 388 | 407 |
| 389 bool TaskQueueManager::IsQueueEmpty(size_t queue_index) const { | 408 bool TaskQueueManager::IsQueueEmpty(size_t queue_index) const { |
| 390 internal::TaskQueue* queue = Queue(queue_index); | 409 internal::TaskQueue* queue = Queue(queue_index); |
| 391 return queue->IsQueueEmpty(); | 410 return queue->IsQueueEmpty(); |
| 392 } | 411 } |
| 393 | 412 |
| 413 base::TimeTicks TaskQueueManager::NextPendingDelayedTaskRunTime() { |
| 414 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 415 bool found_pending_task = false; |
| 416 base::TimeTicks next_pending_delayed_task( |
| 417 base::TimeTicks::FromInternalValue(kMaxTimeTicks)); |
| 418 for (auto& queue : queues_) { |
| 419 found_pending_task |= |
| 420 queue->NextPendingDelayedTaskRunTime(&next_pending_delayed_task); |
| 421 } |
| 422 |
| 423 if (!found_pending_task) |
| 424 return base::TimeTicks(); |
| 425 |
| 426 DCHECK_NE(next_pending_delayed_task, |
| 427 base::TimeTicks::FromInternalValue(kMaxTimeTicks)); |
| 428 return next_pending_delayed_task; |
| 429 } |
| 430 |
| 394 void TaskQueueManager::SetPumpPolicy(size_t queue_index, | 431 void TaskQueueManager::SetPumpPolicy(size_t queue_index, |
| 395 PumpPolicy pump_policy) { | 432 PumpPolicy pump_policy) { |
| 396 DCHECK(main_thread_checker_.CalledOnValidThread()); | 433 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 397 internal::TaskQueue* queue = Queue(queue_index); | 434 internal::TaskQueue* queue = Queue(queue_index); |
| 398 queue->SetPumpPolicy(pump_policy); | 435 queue->SetPumpPolicy(pump_policy); |
| 399 } | 436 } |
| 400 | 437 |
| 401 void TaskQueueManager::PumpQueue(size_t queue_index) { | 438 void TaskQueueManager::PumpQueue(size_t queue_index) { |
| 402 DCHECK(main_thread_checker_.CalledOnValidThread()); | 439 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 403 internal::TaskQueue* queue = Queue(queue_index); | 440 internal::TaskQueue* queue = Queue(queue_index); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 state->EndArray(); | 615 state->EndArray(); |
| 579 state->BeginDictionary("selector"); | 616 state->BeginDictionary("selector"); |
| 580 selector_->AsValueInto(state.get()); | 617 selector_->AsValueInto(state.get()); |
| 581 state->EndDictionary(); | 618 state->EndDictionary(); |
| 582 if (should_run) | 619 if (should_run) |
| 583 state->SetInteger("selected_queue", selected_queue); | 620 state->SetInteger("selected_queue", selected_queue); |
| 584 return state; | 621 return state; |
| 585 } | 622 } |
| 586 | 623 |
| 587 } // namespace content | 624 } // namespace content |
| OLD | NEW |