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

Unified Diff: third_party/WebKit/Source/platform/scheduler/base/time_domain.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/time_domain.cc
diff --git a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
index e84c5c6f46ebbcf6c254ef35aaabc478ed4c0016..fa3199a70899650fa730a6583cb2ae3eb7fd7290 100644
--- a/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
+++ b/third_party/WebKit/Source/platform/scheduler/base/time_domain.cc
@@ -13,6 +13,15 @@
namespace blink {
namespace scheduler {
+struct TimeDomain::HeapElement {
+ base::TimeTicks key;
+ internal::TaskQueueImpl* value;
+
+ bool operator<=(const HeapElement& other) const { return key <= other.key; }
+
+ void SetHeapIndex(size_t i) { value->set_heap_index(i); }
+};
+
TimeDomain::TimeDomain(Observer* observer) : observer_(observer) {}
TimeDomain::~TimeDomain() {
@@ -29,17 +38,14 @@ void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) {
DCHECK_EQ(queue->GetTimeDomain(), this);
UnregisterAsUpdatableTaskQueue(queue);
- // If present remove |task_queue| from delayed_wakeup_multimap_.
- // O(log n)
- QueueToDelayedWakeupMultimapIteratorMap::iterator it =
- queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
-
- if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end())
+ // If no wakeup has been requested then bail out.
+ if (queue->time_domain_wakeup().is_null())
return;
- // O(1) amortized.
- delayed_wakeup_multimap_.erase(it->second);
- queue_to_delayed_wakeup_multimap_iterator_map_.erase(it);
+ // O(log n)
+ delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index());
+ queue->set_time_domain_wakeup(base::TimeTicks());
+ queue->set_heap_index(0u);
Sami 2016/10/14 07:26:16 Could we make 0u a named constant so 1-basedness o
alex clarke (OOO till 29th) 2016/10/14 13:55:35 I think I should actually move this into the templ
}
void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue,
@@ -53,21 +59,18 @@ void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue,
if (UnregisterAsUpdatableTaskQueue(queue))
destination_time_domain->updatable_queue_set_.insert(queue);
- // If present remove |task_queue| from delayed_wakeup_multimap_.
- // O(log n)
- QueueToDelayedWakeupMultimapIteratorMap::iterator it =
- queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
-
- if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end())
+ // If no wakeup has been requested then bail out.
+ if (queue->time_domain_wakeup().is_null())
return;
- base::TimeTicks destination_now = destination_time_domain->Now();
- destination_time_domain->ScheduleDelayedWork(queue, it->second->first,
- destination_now);
+ // O(log n)
+ delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index());
+ queue->set_time_domain_wakeup(base::TimeTicks());
+ queue->set_heap_index(0u);
- // O(1) amortized.
- delayed_wakeup_multimap_.erase(it->second);
- queue_to_delayed_wakeup_multimap_iterator_map_.erase(it);
+ base::TimeTicks destination_now = destination_time_domain->Now();
+ destination_time_domain->ScheduleDelayedWork(
+ queue, queue->time_domain_wakeup(), destination_now);
}
void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
@@ -76,27 +79,20 @@ void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
DCHECK(main_thread_checker_.CalledOnValidThread());
// We only want to store a single wakeup per queue, so we need to remove any
// previously registered wake up for |queue|.
- QueueToDelayedWakeupMultimapIteratorMap::iterator it =
- queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
-
- if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end())
- delayed_wakeup_multimap_.erase(it->second);
+ if (!queue->time_domain_wakeup().is_null()) {
+ delayed_wakeup_queue_.eraseHeapIndex(queue->heap_index());
+ queue->set_time_domain_wakeup(base::TimeTicks());
+ queue->set_heap_index(0u);
+ }
- if (delayed_wakeup_multimap_.empty() ||
- delayed_run_time < delayed_wakeup_multimap_.begin()->first) {
+ if (delayed_wakeup_queue_.empty() ||
+ delayed_run_time < delayed_wakeup_queue_.min().key) {
base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now);
RequestWakeup(now, delay);
}
- if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end()) {
- // TODO(alexclarke): Use C++17 extract & insert to more efficiently modify
- // |queue_to_delayed_wakeup_multimap_iterator_map_|.
- it->second = delayed_wakeup_multimap_.insert({delayed_run_time, queue});
- } else {
- // Insert the wakeup and store the map iterator for later convenience.
- queue_to_delayed_wakeup_multimap_iterator_map_.insert(
- {queue, delayed_wakeup_multimap_.insert({delayed_run_time, queue})});
- }
+ delayed_wakeup_queue_.insert({delayed_run_time, queue});
Sami 2016/10/14 07:26:16 Would it make sense to add an emplace() for this?
alex clarke (OOO till 29th) 2016/10/14 13:55:35 The thing about emplace is, if we're gonna do it w
+ queue->set_time_domain_wakeup(delayed_run_time);
if (observer_)
observer_->OnTimeDomainHasDelayedWork(queue);
@@ -167,38 +163,32 @@ void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) {
// Wake up any queues with pending delayed work. Note std::multipmap stores
// the elements sorted by key, so the begin() iterator points to the earliest
// queue to wakeup.
- while (!delayed_wakeup_multimap_.empty()) {
- DelayedWakeupMultimap::iterator next_wakeup =
- delayed_wakeup_multimap_.begin();
- if (next_wakeup->first > lazy_now->Now())
- break;
-
- internal::TaskQueueImpl* queue = next_wakeup->second;
-
- // O(1) amortized.
- delayed_wakeup_multimap_.erase(next_wakeup);
- // O(log n).
- queue_to_delayed_wakeup_multimap_iterator_map_.erase(queue);
+ while (!delayed_wakeup_queue_.empty() &&
+ delayed_wakeup_queue_.min().key <= lazy_now->Now()) {
+ internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().value;
+ // O(log n)
+ delayed_wakeup_queue_.eraseMin();
+ queue->set_time_domain_wakeup(base::TimeTicks());
queue->WakeUpForDelayedWork(lazy_now);
}
}
bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const {
DCHECK(main_thread_checker_.CalledOnValidThread());
- if (delayed_wakeup_multimap_.empty())
+ if (delayed_wakeup_queue_.empty())
return false;
- *out_time = delayed_wakeup_multimap_.begin()->first;
+ *out_time = delayed_wakeup_queue_.min().key;
return true;
}
bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const {
DCHECK(main_thread_checker_.CalledOnValidThread());
- if (delayed_wakeup_multimap_.empty())
+ if (delayed_wakeup_queue_.empty())
return false;
- *out_task_queue = delayed_wakeup_multimap_.begin()->second;
+ *out_task_queue = delayed_wakeup_queue_.min().value;
return true;
}
@@ -209,9 +199,9 @@ void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const {
for (auto* queue : updatable_queue_set_)
state->AppendString(queue->GetName());
state->EndArray();
- state->SetInteger("registered_delay_count", delayed_wakeup_multimap_.size());
- if (!delayed_wakeup_multimap_.empty()) {
- base::TimeDelta delay = delayed_wakeup_multimap_.begin()->first - Now();
+ state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size());
+ if (!delayed_wakeup_queue_.empty()) {
+ base::TimeDelta delay = delayed_wakeup_queue_.min().key - Now();
state->SetDouble("next_delay_ms", delay.InMillisecondsF());
}
AsValueIntoInternal(state);

Powered by Google App Engine
This is Rietveld 408576698