Allow only one bookmark to be added for multiple fast starring
[chromium-blink-merge.git] / components / scheduler / child / task_queue_selector.cc
bloba8faf98fdadbb3e4d02fcf7ba22f4b3fccbbd32a
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
3 // found in the LICENSE file.
5 #include "components/scheduler/child/task_queue_selector.h"
7 #include "base/logging.h"
8 #include "base/trace_event/trace_event_argument.h"
9 #include "components/scheduler/child/task_queue_impl.h"
11 namespace scheduler {
12 namespace internal {
14 TaskQueueSelector::TaskQueueSelector()
15 : task_queue_sets_(TaskQueue::QUEUE_PRIORITY_COUNT),
16 starvation_count_(0),
17 task_queue_selector_observer_(nullptr) {}
19 TaskQueueSelector::~TaskQueueSelector() {}
21 void TaskQueueSelector::AddQueue(internal::TaskQueueImpl* queue) {
22 DCHECK(main_thread_checker_.CalledOnValidThread());
23 task_queue_sets_.AssignQueueToSet(queue, TaskQueue::NORMAL_PRIORITY);
26 void TaskQueueSelector::RemoveQueue(internal::TaskQueueImpl* queue) {
27 DCHECK(main_thread_checker_.CalledOnValidThread());
28 task_queue_sets_.RemoveQueue(queue);
31 void TaskQueueSelector::SetQueuePriority(internal::TaskQueueImpl* queue,
32 TaskQueue::QueuePriority priority) {
33 DCHECK(main_thread_checker_.CalledOnValidThread());
34 DCHECK_LT(priority, TaskQueue::QUEUE_PRIORITY_COUNT);
35 TaskQueue::QueuePriority old_priority =
36 static_cast<TaskQueue::QueuePriority>(queue->get_task_queue_set_index());
37 task_queue_sets_.AssignQueueToSet(queue, priority);
38 if (task_queue_selector_observer_ &&
39 old_priority == TaskQueue::DISABLED_PRIORITY)
40 task_queue_selector_observer_->OnTaskQueueEnabled();
43 bool TaskQueueSelector::IsQueueEnabled(
44 const internal::TaskQueueImpl* queue) const {
45 DCHECK(main_thread_checker_.CalledOnValidThread());
46 return static_cast<TaskQueue::QueuePriority>(
47 queue->get_task_queue_set_index()) != TaskQueue::DISABLED_PRIORITY;
50 TaskQueue::QueuePriority TaskQueueSelector::NextPriority(
51 TaskQueue::QueuePriority priority) {
52 DCHECK(priority < TaskQueue::QUEUE_PRIORITY_COUNT);
53 return static_cast<TaskQueue::QueuePriority>(static_cast<int>(priority) + 1);
56 bool TaskQueueSelector::ChooseOldestWithPriority(
57 TaskQueue::QueuePriority priority,
58 internal::TaskQueueImpl** out_queue) const {
59 return task_queue_sets_.GetOldestQueueInSet(priority, out_queue);
62 bool TaskQueueSelector::SelectQueueToService(
63 internal::TaskQueueImpl** out_queue) {
64 DCHECK(main_thread_checker_.CalledOnValidThread());
65 // Always service the control queue if it has any work.
66 if (ChooseOldestWithPriority(TaskQueue::CONTROL_PRIORITY, out_queue)) {
67 DidSelectQueueWithPriority(TaskQueue::CONTROL_PRIORITY);
68 return true;
70 // Select from the normal priority queue if we are starving it.
71 if (starvation_count_ >= kMaxStarvationTasks &&
72 ChooseOldestWithPriority(TaskQueue::NORMAL_PRIORITY, out_queue)) {
73 DidSelectQueueWithPriority(TaskQueue::NORMAL_PRIORITY);
74 return true;
76 // Otherwise choose in priority order.
77 for (TaskQueue::QueuePriority priority = TaskQueue::HIGH_PRIORITY;
78 priority < TaskQueue::DISABLED_PRIORITY;
79 priority = NextPriority(priority)) {
80 if (ChooseOldestWithPriority(priority, out_queue)) {
81 DidSelectQueueWithPriority(priority);
82 return true;
85 return false;
88 void TaskQueueSelector::DidSelectQueueWithPriority(
89 TaskQueue::QueuePriority priority) {
90 switch (priority) {
91 case TaskQueue::CONTROL_PRIORITY:
92 break;
93 case TaskQueue::HIGH_PRIORITY:
94 starvation_count_++;
95 break;
96 case TaskQueue::NORMAL_PRIORITY:
97 case TaskQueue::BEST_EFFORT_PRIORITY:
98 starvation_count_ = 0;
99 break;
100 default:
101 NOTREACHED();
105 void TaskQueueSelector::AsValueInto(
106 base::trace_event::TracedValue* state) const {
107 DCHECK(main_thread_checker_.CalledOnValidThread());
108 state->SetInteger("starvation_count", starvation_count_);
111 void TaskQueueSelector::SetTaskQueueSelectorObserver(Observer* observer) {
112 task_queue_selector_observer_ = observer;
115 } // namespace internal
116 } // namespace scheduler