| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 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 "components/scheduler/base/work_queue_sets.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "components/scheduler/base/work_queue.h" | |
| 9 | |
| 10 namespace scheduler { | |
| 11 namespace internal { | |
| 12 | |
| 13 WorkQueueSets::WorkQueueSets(size_t num_sets, const char* name) | |
| 14 : enqueue_order_to_work_queue_maps_(num_sets), name_(name) {} | |
| 15 | |
| 16 WorkQueueSets::~WorkQueueSets() {} | |
| 17 | |
| 18 void WorkQueueSets::AddQueue(WorkQueue* work_queue, size_t set_index) { | |
| 19 DCHECK(!work_queue->work_queue_sets()); | |
| 20 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); | |
| 21 EnqueueOrder enqueue_order; | |
| 22 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 23 work_queue->AssignToWorkQueueSets(this); | |
| 24 work_queue->AssignSetIndex(set_index); | |
| 25 if (!has_enqueue_order) | |
| 26 return; | |
| 27 enqueue_order_to_work_queue_maps_[set_index].insert( | |
| 28 std::make_pair(enqueue_order, work_queue)); | |
| 29 } | |
| 30 | |
| 31 void WorkQueueSets::RemoveQueue(WorkQueue* work_queue) { | |
| 32 DCHECK_EQ(this, work_queue->work_queue_sets()); | |
| 33 EnqueueOrder enqueue_order; | |
| 34 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 35 work_queue->AssignToWorkQueueSets(nullptr); | |
| 36 if (!has_enqueue_order) | |
| 37 return; | |
| 38 size_t set_index = work_queue->work_queue_set_index(); | |
| 39 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); | |
| 40 DCHECK_EQ( | |
| 41 work_queue, | |
| 42 enqueue_order_to_work_queue_maps_[set_index].find(enqueue_order)->second); | |
| 43 enqueue_order_to_work_queue_maps_[set_index].erase(enqueue_order); | |
| 44 } | |
| 45 | |
| 46 void WorkQueueSets::ChangeSetIndex(WorkQueue* work_queue, size_t set_index) { | |
| 47 DCHECK_EQ(this, work_queue->work_queue_sets()); | |
| 48 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); | |
| 49 EnqueueOrder enqueue_order; | |
| 50 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 51 size_t old_set = work_queue->work_queue_set_index(); | |
| 52 DCHECK_LT(old_set, enqueue_order_to_work_queue_maps_.size()); | |
| 53 DCHECK_NE(old_set, set_index); | |
| 54 work_queue->AssignSetIndex(set_index); | |
| 55 if (!has_enqueue_order) | |
| 56 return; | |
| 57 enqueue_order_to_work_queue_maps_[old_set].erase(enqueue_order); | |
| 58 enqueue_order_to_work_queue_maps_[set_index].insert( | |
| 59 std::make_pair(enqueue_order, work_queue)); | |
| 60 } | |
| 61 | |
| 62 void WorkQueueSets::OnPushQueue(WorkQueue* work_queue) { | |
| 63 // NOTE if this funciton changes, we need to keep |WorkQueueSets::AddQueue| in | |
| 64 // sync. | |
| 65 DCHECK_EQ(this, work_queue->work_queue_sets()); | |
| 66 EnqueueOrder enqueue_order; | |
| 67 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 68 DCHECK(has_enqueue_order); | |
| 69 size_t set_index = work_queue->work_queue_set_index(); | |
| 70 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()) | |
| 71 << " set_index = " << set_index; | |
| 72 enqueue_order_to_work_queue_maps_[set_index].insert( | |
| 73 std::make_pair(enqueue_order, work_queue)); | |
| 74 } | |
| 75 | |
| 76 void WorkQueueSets::OnPopQueue(WorkQueue* work_queue) { | |
| 77 size_t set_index = work_queue->work_queue_set_index(); | |
| 78 DCHECK_EQ(this, work_queue->work_queue_sets()); | |
| 79 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); | |
| 80 DCHECK(!enqueue_order_to_work_queue_maps_[set_index].empty()) | |
| 81 << " set_index = " << set_index; | |
| 82 DCHECK_EQ(enqueue_order_to_work_queue_maps_[set_index].begin()->second, | |
| 83 work_queue) | |
| 84 << " set_index = " << set_index; | |
| 85 // O(1) amortised. | |
| 86 enqueue_order_to_work_queue_maps_[set_index].erase( | |
| 87 enqueue_order_to_work_queue_maps_[set_index].begin()); | |
| 88 EnqueueOrder enqueue_order; | |
| 89 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 90 if (!has_enqueue_order) | |
| 91 return; | |
| 92 enqueue_order_to_work_queue_maps_[set_index].insert( | |
| 93 std::make_pair(enqueue_order, work_queue)); | |
| 94 } | |
| 95 | |
| 96 bool WorkQueueSets::GetOldestQueueInSet(size_t set_index, | |
| 97 WorkQueue** out_work_queue) const { | |
| 98 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()); | |
| 99 if (enqueue_order_to_work_queue_maps_[set_index].empty()) | |
| 100 return false; | |
| 101 *out_work_queue = | |
| 102 enqueue_order_to_work_queue_maps_[set_index].begin()->second; | |
| 103 #ifndef NDEBUG | |
| 104 EnqueueOrder enqueue_order; | |
| 105 DCHECK((*out_work_queue)->GetFrontTaskEnqueueOrder(&enqueue_order)); | |
| 106 DCHECK_EQ(enqueue_order, | |
| 107 enqueue_order_to_work_queue_maps_[set_index].begin()->first); | |
| 108 #endif | |
| 109 return true; | |
| 110 } | |
| 111 | |
| 112 bool WorkQueueSets::IsSetEmpty(size_t set_index) const { | |
| 113 DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size()) | |
| 114 << " set_index = " << set_index; | |
| 115 return enqueue_order_to_work_queue_maps_[set_index].empty(); | |
| 116 } | |
| 117 | |
| 118 #if DCHECK_IS_ON() || !defined(NDEBUG) | |
| 119 bool WorkQueueSets::ContainsWorkQueueForTest( | |
| 120 const WorkQueue* work_queue) const { | |
| 121 EnqueueOrder enqueue_order; | |
| 122 bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order); | |
| 123 | |
| 124 for (const EnqueueOrderToWorkQueueMap& map : | |
| 125 enqueue_order_to_work_queue_maps_) { | |
| 126 for (const EnqueueOrderToWorkQueueMap::value_type& key_value_pair : map) { | |
| 127 if (key_value_pair.second == work_queue) { | |
| 128 DCHECK(has_enqueue_order); | |
| 129 DCHECK_EQ(key_value_pair.first, enqueue_order); | |
| 130 DCHECK_EQ(this, work_queue->work_queue_sets()); | |
| 131 return true; | |
| 132 } | |
| 133 } | |
| 134 } | |
| 135 | |
| 136 if (work_queue->work_queue_sets() == this) { | |
| 137 DCHECK(!has_enqueue_order); | |
| 138 return true; | |
| 139 } | |
| 140 | |
| 141 return false; | |
| 142 } | |
| 143 #endif | |
| 144 | |
| 145 } // namespace internal | |
| 146 } // namespace scheduler | |
| OLD | NEW |