Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: content/renderer/scheduler/renderer_task_queue_selector.cc

Issue 657953004: content: Add RendererTaskQueueSelector. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use NON_EXPORTED_BASE Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "content/renderer/scheduler/renderer_task_queue_selector.h"
6
7 #include "base/logging.h"
8 #include "base/pending_task.h"
9
10 namespace content {
11
12 RendererTaskQueueSelector::RendererTaskQueueSelector() : starvation_count_(0) {
13 }
14
15 RendererTaskQueueSelector::~RendererTaskQueueSelector() {
16 }
17
18 void RendererTaskQueueSelector::RegisterWorkQueues(
19 const std::vector<const base::TaskQueue*>& work_queues) {
20 main_thread_checker_.CalledOnValidThread();
21 work_queues_ = work_queues;
22 for (QueuePriority priority = FIRST_QUEUE_PRIORITY;
23 priority < QUEUE_PRIORITY_COUNT;
24 priority = NextPriority(priority)) {
25 queue_priorities_[priority].clear();
26 }
27 // By default, all work queues are set to normal priority.
28 for (size_t i = 0; i < work_queues.size(); i++) {
29 queue_priorities_[NORMAL_PRIORITY].insert(i);
30 }
31 }
32
33 void RendererTaskQueueSelector::SetQueuePriority(size_t queue_index,
34 QueuePriority priority) {
35 main_thread_checker_.CalledOnValidThread();
36 DCHECK_LT(queue_index, work_queues_.size());
37 DCHECK_LT(priority, QUEUE_PRIORITY_COUNT);
38 DisableQueue(queue_index);
39 queue_priorities_[priority].insert(queue_index);
40 }
41
42 void RendererTaskQueueSelector::EnableQueue(size_t queue_index,
43 QueuePriority priority) {
44 SetQueuePriority(queue_index, priority);
45 }
46
47 void RendererTaskQueueSelector::DisableQueue(size_t queue_index) {
48 main_thread_checker_.CalledOnValidThread();
49 DCHECK_LT(queue_index, work_queues_.size());
50 for (QueuePriority priority = FIRST_QUEUE_PRIORITY;
51 priority < QUEUE_PRIORITY_COUNT;
52 priority = NextPriority(priority)) {
53 queue_priorities_[priority].erase(queue_index);
54 }
55 }
56
57 bool RendererTaskQueueSelector::IsOlder(const base::TaskQueue* queueA,
58 const base::TaskQueue* queueB) {
59 // Note: the comparison is correct due to the fact that the PendingTask
60 // operator inverts its comparison operation in order to work well in a heap
61 // based priority queue.
62 return queueB->front() < queueA->front();
63 }
64
65 RendererTaskQueueSelector::QueuePriority
66 RendererTaskQueueSelector::NextPriority(QueuePriority priority) {
67 DCHECK(priority < QUEUE_PRIORITY_COUNT);
68 return static_cast<QueuePriority>(static_cast<int>(priority) + 1);
69 }
70
71 bool RendererTaskQueueSelector::ChooseOldestWithPriority(
72 QueuePriority priority,
73 size_t* out_queue_index) const {
74 bool found_non_empty_queue = false;
75 size_t chosen_queue = 0;
76 for (int queue_index : queue_priorities_[priority]) {
77 if (work_queues_[queue_index]->empty()) {
78 continue;
79 }
80 if (!found_non_empty_queue ||
81 IsOlder(work_queues_[queue_index], work_queues_[chosen_queue])) {
82 found_non_empty_queue = true;
83 chosen_queue = queue_index;
84 }
85 }
86
87 if (found_non_empty_queue) {
88 *out_queue_index = chosen_queue;
89 }
90 return found_non_empty_queue;
91 }
92
93 bool RendererTaskQueueSelector::SelectWorkQueueToService(
94 size_t* out_queue_index) {
95 main_thread_checker_.CalledOnValidThread();
96 DCHECK(work_queues_.size());
97 // Always service the control queue if it has any work.
98 if (ChooseOldestWithPriority(CONTROL_PRIORITY, out_queue_index)) {
99 return true;
100 }
101 // Select from the normal priority queue if we are starving it.
102 if (starvation_count_ >= kMaxStarvationTasks &&
103 ChooseOldestWithPriority(NORMAL_PRIORITY, out_queue_index)) {
104 starvation_count_ = 0;
105 return true;
106 }
107 // Otherwise choose in priority order.
108 for (QueuePriority priority = HIGH_PRIORITY; priority < QUEUE_PRIORITY_COUNT;
109 priority = NextPriority(priority)) {
110 if (ChooseOldestWithPriority(priority, out_queue_index)) {
111 if (priority == HIGH_PRIORITY) {
112 starvation_count_++;
113 } else {
114 starvation_count_ = 0;
115 }
116 return true;
117 }
118 }
119 return false;
120 }
121
122 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698