1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/task_scheduler/sequence.h" 6 7 #include <utility> 8 9 #include "base/logging.h" 10 #include "base/time/time.h" 11 12 namespace base { 13 namespace internal { 14 15 Sequence::Sequence() = default; 16 PushTask(Task task)17bool Sequence::PushTask(Task task) { 18 // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 19 // for details. 20 CHECK(task.task); 21 DCHECK(task.sequenced_time.is_null()); 22 task.sequenced_time = base::TimeTicks::Now(); 23 24 AutoSchedulerLock auto_lock(lock_); 25 ++num_tasks_per_priority_[static_cast<int>(task.traits.priority())]; 26 queue_.push(std::move(task)); 27 28 // Return true if the sequence was empty before the push. 29 return queue_.size() == 1; 30 } 31 TakeTask()32Optional<Task> Sequence::TakeTask() { 33 AutoSchedulerLock auto_lock(lock_); 34 DCHECK(!queue_.empty()); 35 DCHECK(queue_.front().task); 36 37 const int priority_index = static_cast<int>(queue_.front().traits.priority()); 38 DCHECK_GT(num_tasks_per_priority_[priority_index], 0U); 39 --num_tasks_per_priority_[priority_index]; 40 41 return std::move(queue_.front()); 42 } 43 Pop()44bool Sequence::Pop() { 45 AutoSchedulerLock auto_lock(lock_); 46 DCHECK(!queue_.empty()); 47 DCHECK(!queue_.front().task); 48 queue_.pop(); 49 return queue_.empty(); 50 } 51 GetSortKey() const52SequenceSortKey Sequence::GetSortKey() const { 53 TaskPriority priority = TaskPriority::LOWEST; 54 base::TimeTicks next_task_sequenced_time; 55 56 { 57 AutoSchedulerLock auto_lock(lock_); 58 DCHECK(!queue_.empty()); 59 60 // Find the highest task priority in the sequence. 61 const int highest_priority_index = static_cast<int>(TaskPriority::HIGHEST); 62 const int lowest_priority_index = static_cast<int>(TaskPriority::LOWEST); 63 for (int i = highest_priority_index; i > lowest_priority_index; --i) { 64 if (num_tasks_per_priority_[i] > 0) { 65 priority = static_cast<TaskPriority>(i); 66 break; 67 } 68 } 69 70 // Save the sequenced time of the next task in the sequence. 71 next_task_sequenced_time = queue_.front().sequenced_time; 72 } 73 74 return SequenceSortKey(priority, next_task_sequenced_time); 75 } 76 77 Sequence::~Sequence() = default; 78 79 } // namespace internal 80 } // namespace base 81