• 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(Task task)17 bool 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()32 Optional<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()44 bool 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() const52 SequenceSortKey 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