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

Side by Side Diff: third_party/WebKit/Source/platform/scheduler/base/time_domain.cc

Issue 2428073002: Revert of [Reland] Optimize blink scheduler with an intrusive heap (Closed)
Patch Set: 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/scheduler/base/time_domain.h" 5 #include "platform/scheduler/base/time_domain.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "platform/scheduler/base/task_queue_impl.h" 9 #include "platform/scheduler/base/task_queue_impl.h"
10 #include "platform/scheduler/base/task_queue_manager_delegate.h" 10 #include "platform/scheduler/base/task_queue_manager_delegate.h"
(...skipping 11 matching lines...) Expand all
22 void TimeDomain::RegisterQueue(internal::TaskQueueImpl* queue) { 22 void TimeDomain::RegisterQueue(internal::TaskQueueImpl* queue) {
23 DCHECK(main_thread_checker_.CalledOnValidThread()); 23 DCHECK(main_thread_checker_.CalledOnValidThread());
24 DCHECK_EQ(queue->GetTimeDomain(), this); 24 DCHECK_EQ(queue->GetTimeDomain(), this);
25 } 25 }
26 26
27 void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) { 27 void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) {
28 DCHECK(main_thread_checker_.CalledOnValidThread()); 28 DCHECK(main_thread_checker_.CalledOnValidThread());
29 DCHECK_EQ(queue->GetTimeDomain(), this); 29 DCHECK_EQ(queue->GetTimeDomain(), this);
30 UnregisterAsUpdatableTaskQueue(queue); 30 UnregisterAsUpdatableTaskQueue(queue);
31 31
32 // If no wakeup has been requested then bail out. 32 // If present remove |task_queue| from delayed_wakeup_multimap_.
33 if (queue->scheduled_time_domain_wakeup().is_null()) 33 // O(log n)
34 QueueToDelayedWakeupMultimapIteratorMap::iterator it =
35 queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
36
37 if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end())
34 return; 38 return;
35 39
36 // O(log n) 40 // O(1) amortized.
37 delayed_wakeup_queue_.erase(queue->heap_handle()); 41 delayed_wakeup_multimap_.erase(it->second);
38 queue->set_scheduled_time_domain_wakeup(base::TimeTicks()); 42 queue_to_delayed_wakeup_multimap_iterator_map_.erase(it);
39 } 43 }
40 44
41 void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue, 45 void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue,
42 TimeDomain* destination_time_domain) { 46 TimeDomain* destination_time_domain) {
43 DCHECK(main_thread_checker_.CalledOnValidThread()); 47 DCHECK(main_thread_checker_.CalledOnValidThread());
44 DCHECK_EQ(queue->GetTimeDomain(), this); 48 DCHECK_EQ(queue->GetTimeDomain(), this);
45 DCHECK(destination_time_domain); 49 DCHECK(destination_time_domain);
46 50
47 // Make sure we remember to update |queue| if it's got incoming immediate 51 // Make sure we remember to update |queue| if it's got incoming immediate
48 // work. 52 // work.
49 if (UnregisterAsUpdatableTaskQueue(queue)) 53 if (UnregisterAsUpdatableTaskQueue(queue))
50 destination_time_domain->updatable_queue_set_.insert(queue); 54 destination_time_domain->updatable_queue_set_.insert(queue);
51 55
52 // If no wakeup has been requested then bail out. 56 // If present remove |task_queue| from delayed_wakeup_multimap_.
53 if (queue->scheduled_time_domain_wakeup().is_null()) 57 // O(log n)
58 QueueToDelayedWakeupMultimapIteratorMap::iterator it =
59 queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
60
61 if (it == queue_to_delayed_wakeup_multimap_iterator_map_.end())
54 return; 62 return;
55 63
56 // O(log n) 64 base::TimeTicks destination_now = destination_time_domain->Now();
57 delayed_wakeup_queue_.erase(queue->heap_handle()); 65 destination_time_domain->ScheduleDelayedWork(queue, it->second->first,
58 queue->set_scheduled_time_domain_wakeup(base::TimeTicks()); 66 destination_now);
59 67
60 base::TimeTicks destination_now = destination_time_domain->Now(); 68 // O(1) amortized.
61 destination_time_domain->ScheduleDelayedWork( 69 delayed_wakeup_multimap_.erase(it->second);
62 queue, queue->scheduled_time_domain_wakeup(), destination_now); 70 queue_to_delayed_wakeup_multimap_iterator_map_.erase(it);
63 } 71 }
64 72
65 void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue, 73 void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
66 base::TimeTicks delayed_run_time, 74 base::TimeTicks delayed_run_time,
67 base::TimeTicks now) { 75 base::TimeTicks now) {
68 DCHECK(main_thread_checker_.CalledOnValidThread()); 76 DCHECK(main_thread_checker_.CalledOnValidThread());
69 // We only want to store a single wakeup per queue, so we need to remove any 77 // We only want to store a single wakeup per queue, so we need to remove any
70 // previously registered wake up for |queue|. 78 // previously registered wake up for |queue|.
71 if (!queue->scheduled_time_domain_wakeup().is_null()) { 79 QueueToDelayedWakeupMultimapIteratorMap::iterator it =
72 delayed_wakeup_queue_.erase(queue->heap_handle()); 80 queue_to_delayed_wakeup_multimap_iterator_map_.find(queue);
73 queue->set_scheduled_time_domain_wakeup(base::TimeTicks());
74 }
75 81
76 if (delayed_wakeup_queue_.empty() || 82 if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end())
77 delayed_run_time < delayed_wakeup_queue_.min().time) { 83 delayed_wakeup_multimap_.erase(it->second);
84
85 if (delayed_wakeup_multimap_.empty() ||
86 delayed_run_time < delayed_wakeup_multimap_.begin()->first) {
78 base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now); 87 base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now);
79 RequestWakeup(now, delay); 88 RequestWakeup(now, delay);
80 } 89 }
81 90
82 delayed_wakeup_queue_.insert({delayed_run_time, queue}); 91 if (it != queue_to_delayed_wakeup_multimap_iterator_map_.end()) {
83 queue->set_scheduled_time_domain_wakeup(delayed_run_time); 92 // TODO(alexclarke): Use C++17 extract & insert to more efficiently modify
93 // |queue_to_delayed_wakeup_multimap_iterator_map_|.
94 it->second = delayed_wakeup_multimap_.insert({delayed_run_time, queue});
95 } else {
96 // Insert the wakeup and store the map iterator for later convenience.
97 queue_to_delayed_wakeup_multimap_iterator_map_.insert(
98 {queue, delayed_wakeup_multimap_.insert({delayed_run_time, queue})});
99 }
84 100
85 if (observer_) 101 if (observer_)
86 observer_->OnTimeDomainHasDelayedWork(queue); 102 observer_->OnTimeDomainHasDelayedWork(queue);
87 } 103 }
88 104
89 void TimeDomain::RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue) { 105 void TimeDomain::RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue) {
90 { 106 {
91 base::AutoLock lock(newly_updatable_lock_); 107 base::AutoLock lock(newly_updatable_lock_);
92 newly_updatable_.push_back(queue); 108 newly_updatable_.push_back(queue);
93 } 109 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 updatable_queue_set_.insert(newly_updatable_.back()); 160 updatable_queue_set_.insert(newly_updatable_.back());
145 newly_updatable_.pop_back(); 161 newly_updatable_.pop_back();
146 } 162 }
147 } 163 }
148 164
149 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) { 165 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) {
150 DCHECK(main_thread_checker_.CalledOnValidThread()); 166 DCHECK(main_thread_checker_.CalledOnValidThread());
151 // Wake up any queues with pending delayed work. Note std::multipmap stores 167 // Wake up any queues with pending delayed work. Note std::multipmap stores
152 // the elements sorted by key, so the begin() iterator points to the earliest 168 // the elements sorted by key, so the begin() iterator points to the earliest
153 // queue to wakeup. 169 // queue to wakeup.
154 while (!delayed_wakeup_queue_.empty() && 170 while (!delayed_wakeup_multimap_.empty()) {
155 delayed_wakeup_queue_.min().time <= lazy_now->Now()) { 171 DelayedWakeupMultimap::iterator next_wakeup =
156 internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue; 172 delayed_wakeup_multimap_.begin();
157 // O(log n) 173 if (next_wakeup->first > lazy_now->Now())
158 delayed_wakeup_queue_.pop(); 174 break;
159 175
160 queue->set_scheduled_time_domain_wakeup(base::TimeTicks()); 176 internal::TaskQueueImpl* queue = next_wakeup->second;
177
178 // O(1) amortized.
179 delayed_wakeup_multimap_.erase(next_wakeup);
180 // O(log n).
181 queue_to_delayed_wakeup_multimap_iterator_map_.erase(queue);
182
161 queue->WakeUpForDelayedWork(lazy_now); 183 queue->WakeUpForDelayedWork(lazy_now);
162 } 184 }
163 } 185 }
164 186
165 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const { 187 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const {
166 DCHECK(main_thread_checker_.CalledOnValidThread()); 188 DCHECK(main_thread_checker_.CalledOnValidThread());
167 if (delayed_wakeup_queue_.empty()) 189 if (delayed_wakeup_multimap_.empty())
168 return false; 190 return false;
169 191
170 *out_time = delayed_wakeup_queue_.min().time; 192 *out_time = delayed_wakeup_multimap_.begin()->first;
171 return true; 193 return true;
172 } 194 }
173 195
174 bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const { 196 bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const {
175 DCHECK(main_thread_checker_.CalledOnValidThread()); 197 DCHECK(main_thread_checker_.CalledOnValidThread());
176 if (delayed_wakeup_queue_.empty()) 198 if (delayed_wakeup_multimap_.empty())
177 return false; 199 return false;
178 200
179 *out_task_queue = delayed_wakeup_queue_.min().queue; 201 *out_task_queue = delayed_wakeup_multimap_.begin()->second;
180 return true; 202 return true;
181 } 203 }
182 204
183 void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const { 205 void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const {
184 state->BeginDictionary(); 206 state->BeginDictionary();
185 state->SetString("name", GetName()); 207 state->SetString("name", GetName());
186 state->BeginArray("updatable_queue_set"); 208 state->BeginArray("updatable_queue_set");
187 for (auto* queue : updatable_queue_set_) 209 for (auto* queue : updatable_queue_set_)
188 state->AppendString(queue->GetName()); 210 state->AppendString(queue->GetName());
189 state->EndArray(); 211 state->EndArray();
190 state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size()); 212 state->SetInteger("registered_delay_count", delayed_wakeup_multimap_.size());
191 if (!delayed_wakeup_queue_.empty()) { 213 if (!delayed_wakeup_multimap_.empty()) {
192 base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now(); 214 base::TimeDelta delay = delayed_wakeup_multimap_.begin()->first - Now();
193 state->SetDouble("next_delay_ms", delay.InMillisecondsF()); 215 state->SetDouble("next_delay_ms", delay.InMillisecondsF());
194 } 216 }
195 AsValueIntoInternal(state); 217 AsValueIntoInternal(state);
196 state->EndDictionary(); 218 state->EndDictionary();
197 } 219 }
198 220
199 } // namespace scheduler 221 } // namespace scheduler
200 } // namespace blink 222 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698