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