• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(std::unique_ptr<Task> task)17 bool Sequence::PushTask(std::unique_ptr<Task> task) {
18   DCHECK(task->sequenced_time.is_null());
19   task->sequenced_time = base::TimeTicks::Now();
20 
21   AutoSchedulerLock auto_lock(lock_);
22   ++num_tasks_per_priority_[static_cast<int>(task->traits.priority())];
23   queue_.push(std::move(task));
24 
25   // Return true if the sequence was empty before the push.
26   return queue_.size() == 1;
27 }
28 
PeekTask() const29 const Task* Sequence::PeekTask() const {
30   AutoSchedulerLock auto_lock(lock_);
31 
32   if (queue_.empty())
33     return nullptr;
34 
35   return queue_.front().get();
36 }
37 
PopTask()38 bool Sequence::PopTask() {
39   AutoSchedulerLock auto_lock(lock_);
40   DCHECK(!queue_.empty());
41 
42   const int priority_index =
43       static_cast<int>(queue_.front()->traits.priority());
44   DCHECK_GT(num_tasks_per_priority_[priority_index], 0U);
45   --num_tasks_per_priority_[priority_index];
46 
47   queue_.pop();
48   return queue_.empty();
49 }
50 
GetSortKey() const51 SequenceSortKey Sequence::GetSortKey() const {
52   TaskPriority priority = TaskPriority::LOWEST;
53   base::TimeTicks next_task_sequenced_time;
54 
55   {
56     AutoSchedulerLock auto_lock(lock_);
57     DCHECK(!queue_.empty());
58 
59     // Find the highest task priority in the sequence.
60     const int highest_priority_index = static_cast<int>(TaskPriority::HIGHEST);
61     const int lowest_priority_index = static_cast<int>(TaskPriority::LOWEST);
62     for (int i = highest_priority_index; i > lowest_priority_index; --i) {
63       if (num_tasks_per_priority_[i] > 0) {
64         priority = static_cast<TaskPriority>(i);
65         break;
66       }
67     }
68 
69     // Save the sequenced time of the next task in the sequence.
70     next_task_sequenced_time = queue_.front()->sequenced_time;
71   }
72 
73   return SequenceSortKey(priority, next_task_sequenced_time);
74 }
75 
76 Sequence::~Sequence() = default;
77 
78 }  // namespace internal
79 }  // namespace base
80