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

Unified Diff: third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc

Issue 2419793002: [Reland] Optimize blink scheduler with an intrusive heap (Closed)
Patch Set: Fix bug in MoveHoleDown Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc b/third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc
index 194524f1740f557c25154ab3aeed6097d013fef3..bc37b8846896a0edbe5864afa7796a3e59d642a2 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/work_queue_sets.cc
@@ -11,53 +11,61 @@ namespace blink {
namespace scheduler {
namespace internal {
+struct WorkQueueSets::HeapElement {
+ EnqueueOrder key;
+ WorkQueue* value;
+
+ bool operator<=(const HeapElement& other) const { return key <= other.key; }
+
+ void SetHeapIndex(size_t i) { value->set_heap_index(i); }
+};
+
WorkQueueSets::WorkQueueSets(size_t num_sets, const char* name)
- : enqueue_order_to_work_queue_maps_(num_sets), name_(name) {}
+ : work_queue_heaps_(num_sets), name_(name) {}
WorkQueueSets::~WorkQueueSets() {}
void WorkQueueSets::AddQueue(WorkQueue* work_queue, size_t set_index) {
DCHECK(!work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
+ DCHECK_LT(set_index, work_queue_heaps_.size());
EnqueueOrder enqueue_order;
bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
work_queue->AssignToWorkQueueSets(this);
work_queue->AssignSetIndex(set_index);
if (!has_enqueue_order)
return;
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
+ work_queue_heaps_[set_index].insert({enqueue_order, work_queue});
}
void WorkQueueSets::RemoveQueue(WorkQueue* work_queue) {
DCHECK_EQ(this, work_queue->work_queue_sets());
- EnqueueOrder enqueue_order;
- bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
work_queue->AssignToWorkQueueSets(nullptr);
- if (!has_enqueue_order)
+ size_t heap_index = work_queue->heap_index();
+ if (heap_index == 0u)
Sami 2016/10/14 07:26:16 Ditto about using a constant.
alex clarke (OOO till 29th) 2016/10/14 13:55:36 Done.
return;
size_t set_index = work_queue->work_queue_set_index();
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
+ DCHECK_LT(set_index, work_queue_heaps_.size());
DCHECK_EQ(
work_queue,
- enqueue_order_to_work_queue_maps_[set_index].find(enqueue_order)->second);
- enqueue_order_to_work_queue_maps_[set_index].erase(enqueue_order);
+ work_queue_heaps_[set_index].GetNodesForTesting()[heap_index].value);
+ work_queue_heaps_[set_index].eraseHeapIndex(heap_index);
+ work_queue->set_heap_index(0);
}
void WorkQueueSets::ChangeSetIndex(WorkQueue* work_queue, size_t set_index) {
DCHECK_EQ(this, work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
+ DCHECK_LT(set_index, work_queue_heaps_.size());
EnqueueOrder enqueue_order;
bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
size_t old_set = work_queue->work_queue_set_index();
- DCHECK_LT(old_set, enqueue_order_to_work_queue_maps_.size());
+ DCHECK_LT(old_set, work_queue_heaps_.size());
DCHECK_NE(old_set, set_index);
work_queue->AssignSetIndex(set_index);
if (!has_enqueue_order)
return;
- enqueue_order_to_work_queue_maps_[old_set].erase(enqueue_order);
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
+ DCHECK_NE(0u, work_queue->heap_index());
+ work_queue_heaps_[old_set].eraseHeapIndex(work_queue->heap_index());
+ work_queue_heaps_[set_index].insert({enqueue_order, work_queue});
}
void WorkQueueSets::OnPushQueue(WorkQueue* work_queue) {
@@ -68,55 +76,41 @@ void WorkQueueSets::OnPushQueue(WorkQueue* work_queue) {
bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
DCHECK(has_enqueue_order);
size_t set_index = work_queue->work_queue_set_index();
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size())
- << " set_index = " << set_index;
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
+ DCHECK_LT(set_index, work_queue_heaps_.size()) << " set_index = "
+ << set_index;
+ work_queue_heaps_[set_index].insert({enqueue_order, work_queue});
}
void WorkQueueSets::OnPopQueue(WorkQueue* work_queue) {
// Assume that |work_queue| contains the lowest enqueue_order.
size_t set_index = work_queue->work_queue_set_index();
DCHECK_EQ(this, work_queue->work_queue_sets());
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- DCHECK(!enqueue_order_to_work_queue_maps_[set_index].empty())
- << " set_index = " << set_index;
- DCHECK_EQ(enqueue_order_to_work_queue_maps_[set_index].begin()->second,
- work_queue)
+ DCHECK_LT(set_index, work_queue_heaps_.size());
+ DCHECK(!work_queue_heaps_[set_index].empty()) << " set_index = " << set_index;
+ DCHECK_EQ(work_queue_heaps_[set_index].min().value, work_queue)
<< " set_index = " << set_index;
- EnqueueOrderToWorkQueueMap::iterator old_it =
- enqueue_order_to_work_queue_maps_[set_index].begin();
EnqueueOrder enqueue_order;
if (work_queue->GetFrontTaskEnqueueOrder(&enqueue_order)) {
- // Amortized O(1) if the new location is close to |old_it|, otherwise
- // O(log n).
- enqueue_order_to_work_queue_maps_[set_index].insert(
- std::make_pair(enqueue_order, work_queue));
+ work_queue_heaps_[set_index].replaceMin({enqueue_order, work_queue});
+ } else {
+ work_queue_heaps_[set_index].eraseMin();
+ work_queue->set_heap_index(0);
}
- // O(1)
- enqueue_order_to_work_queue_maps_[set_index].erase(old_it);
}
bool WorkQueueSets::GetOldestQueueInSet(size_t set_index,
WorkQueue** out_work_queue) const {
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size());
- if (enqueue_order_to_work_queue_maps_[set_index].empty())
+ DCHECK_LT(set_index, work_queue_heaps_.size());
+ if (work_queue_heaps_[set_index].empty())
return false;
- *out_work_queue =
- enqueue_order_to_work_queue_maps_[set_index].begin()->second;
-#ifndef NDEBUG
- EnqueueOrder enqueue_order;
- DCHECK((*out_work_queue)->GetFrontTaskEnqueueOrder(&enqueue_order));
- DCHECK_EQ(enqueue_order,
- enqueue_order_to_work_queue_maps_[set_index].begin()->first);
-#endif
+ *out_work_queue = work_queue_heaps_[set_index].min().value;
return true;
}
bool WorkQueueSets::IsSetEmpty(size_t set_index) const {
- DCHECK_LT(set_index, enqueue_order_to_work_queue_maps_.size())
- << " set_index = " << set_index;
- return enqueue_order_to_work_queue_maps_[set_index].empty();
+ DCHECK_LT(set_index, work_queue_heaps_.size()) << " set_index = "
+ << set_index;
+ return work_queue_heaps_[set_index].empty();
}
#if DCHECK_IS_ON() || !defined(NDEBUG)
@@ -125,12 +119,11 @@ bool WorkQueueSets::ContainsWorkQueueForTest(
EnqueueOrder enqueue_order;
bool has_enqueue_order = work_queue->GetFrontTaskEnqueueOrder(&enqueue_order);
- for (const EnqueueOrderToWorkQueueMap& map :
- enqueue_order_to_work_queue_maps_) {
- for (const EnqueueOrderToWorkQueueMap::value_type& key_value_pair : map) {
- if (key_value_pair.second == work_queue) {
+ for (const IntrusiveHeap<HeapElement>& heap : work_queue_heaps_) {
+ for (size_t i = 1; i <= heap.size(); i++) {
+ if (heap.GetNodesForTesting()[i].value == work_queue) {
DCHECK(has_enqueue_order);
- DCHECK_EQ(key_value_pair.first, enqueue_order);
+ DCHECK_EQ(heap.GetNodesForTesting()[i].key, enqueue_order);
DCHECK_EQ(this, work_queue->work_queue_sets());
return true;
}

Powered by Google App Engine
This is Rietveld 408576698