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

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

Issue 2590593002: Revert of [Reland] Scheduler refactoring to virtually eliminate redundant DoWorks (Closed)
Patch Set: Created 3 years, 12 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"
11 #include "platform/scheduler/base/work_queue.h" 11 #include "platform/scheduler/base/work_queue.h"
12 12
13 namespace blink { 13 namespace blink {
14 namespace scheduler { 14 namespace scheduler {
15 15
16 TimeDomain::TimeDomain(Observer* observer) : observer_(observer) {} 16 TimeDomain::TimeDomain(Observer* observer) : observer_(observer) {}
17 17
18 TimeDomain::~TimeDomain() { 18 TimeDomain::~TimeDomain() {
19 DCHECK(main_thread_checker_.CalledOnValidThread()); 19 DCHECK(main_thread_checker_.CalledOnValidThread());
20 } 20 }
21 21
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 31
31 // If no wakeup has been requested then bail out. 32 // If no wakeup has been requested then bail out.
32 if (!queue->heap_handle().IsValid()) 33 if (!queue->heap_handle().IsValid())
33 return; 34 return;
34 35
35 DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks()); 36 DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks());
36 37
37 // O(log n) 38 // O(log n)
38 delayed_wakeup_queue_.erase(queue->heap_handle()); 39 delayed_wakeup_queue_.erase(queue->heap_handle());
39 } 40 }
40 41
41 void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue, 42 void TimeDomain::MigrateQueue(internal::TaskQueueImpl* queue,
42 TimeDomain* destination_time_domain) { 43 TimeDomain* destination_time_domain) {
43 DCHECK(main_thread_checker_.CalledOnValidThread()); 44 DCHECK(main_thread_checker_.CalledOnValidThread());
44 DCHECK_EQ(queue->GetTimeDomain(), this); 45 DCHECK_EQ(queue->GetTimeDomain(), this);
45 DCHECK(destination_time_domain); 46 DCHECK(destination_time_domain);
46 47
48 // Make sure we remember to update |queue| if it's got incoming immediate
49 // work.
50 if (UnregisterAsUpdatableTaskQueue(queue))
51 destination_time_domain->updatable_queue_set_.insert(queue);
52
47 // If no wakeup has been requested then bail out. 53 // If no wakeup has been requested then bail out.
48 if (!queue->heap_handle().IsValid()) 54 if (!queue->heap_handle().IsValid())
49 return; 55 return;
50 56
51 base::TimeTicks wake_up_time = queue->scheduled_time_domain_wakeup(); 57 base::TimeTicks wake_up_time = queue->scheduled_time_domain_wakeup();
52 DCHECK_NE(wake_up_time, base::TimeTicks()); 58 DCHECK_NE(wake_up_time, base::TimeTicks());
53 59
54 // O(log n) 60 // O(log n)
55 delayed_wakeup_queue_.erase(queue->heap_handle()); 61 delayed_wakeup_queue_.erase(queue->heap_handle());
56 62
(...skipping 24 matching lines...) Expand all
81 // If |queue| is the first wakeup then request the wakeup. 87 // If |queue| is the first wakeup then request the wakeup.
82 if (delayed_wakeup_queue_.min().queue == queue) { 88 if (delayed_wakeup_queue_.min().queue == queue) {
83 base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now); 89 base::TimeDelta delay = std::max(base::TimeDelta(), delayed_run_time - now);
84 RequestWakeup(now, delay); 90 RequestWakeup(now, delay);
85 } 91 }
86 92
87 if (observer_) 93 if (observer_)
88 observer_->OnTimeDomainHasDelayedWork(queue); 94 observer_->OnTimeDomainHasDelayedWork(queue);
89 } 95 }
90 96
91 void TimeDomain::OnQueueHasImmediateWork(internal::TaskQueueImpl* queue) { 97 void TimeDomain::RegisterAsUpdatableTaskQueue(internal::TaskQueueImpl* queue) {
98 {
99 base::AutoLock lock(newly_updatable_lock_);
100 newly_updatable_.push_back(queue);
101 }
92 if (observer_) 102 if (observer_)
93 observer_->OnTimeDomainHasImmediateWork(queue); 103 observer_->OnTimeDomainHasImmediateWork(queue);
94 } 104 }
95 105
106 bool TimeDomain::UnregisterAsUpdatableTaskQueue(
107 internal::TaskQueueImpl* queue) {
108 DCHECK(main_thread_checker_.CalledOnValidThread());
109
110 bool was_updatable = updatable_queue_set_.erase(queue) != 0;
111
112 base::AutoLock lock(newly_updatable_lock_);
113 // Remove all copies of |queue| from |newly_updatable_|.
114 for (size_t i = 0; i < newly_updatable_.size();) {
115 if (newly_updatable_[i] == queue) {
116 // Move last element into slot #i and then compact.
117 newly_updatable_[i] = newly_updatable_.back();
118 newly_updatable_.pop_back();
119 was_updatable = true;
120 } else {
121 i++;
122 }
123 }
124 return was_updatable;
125 }
126
127 void TimeDomain::UpdateWorkQueues(LazyNow lazy_now) {
128 DCHECK(main_thread_checker_.CalledOnValidThread());
129
130 // Move any ready delayed tasks into the Incoming queues.
131 WakeupReadyDelayedQueues(&lazy_now);
132
133 MoveNewlyUpdatableQueuesIntoUpdatableQueueSet();
134
135 std::set<internal::TaskQueueImpl*>::iterator iter =
136 updatable_queue_set_.begin();
137 while (iter != updatable_queue_set_.end()) {
138 std::set<internal::TaskQueueImpl*>::iterator queue_it = iter++;
139 internal::TaskQueueImpl* queue = *queue_it;
140
141 // Update the queue and remove from the set if subsequent updates are not
142 // required.
143 if (!queue->MaybeUpdateImmediateWorkQueues())
144 updatable_queue_set_.erase(queue_it);
145 }
146 }
147
148 void TimeDomain::MoveNewlyUpdatableQueuesIntoUpdatableQueueSet() {
149 DCHECK(main_thread_checker_.CalledOnValidThread());
150 base::AutoLock lock(newly_updatable_lock_);
151 while (!newly_updatable_.empty()) {
152 updatable_queue_set_.insert(newly_updatable_.back());
153 newly_updatable_.pop_back();
154 }
155 }
156
96 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) { 157 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) {
97 DCHECK(main_thread_checker_.CalledOnValidThread()); 158 DCHECK(main_thread_checker_.CalledOnValidThread());
98 // Wake up any queues with pending delayed work. Note std::multipmap stores 159 // Wake up any queues with pending delayed work. Note std::multipmap stores
99 // the elements sorted by key, so the begin() iterator points to the earliest 160 // the elements sorted by key, so the begin() iterator points to the earliest
100 // queue to wakeup. 161 // queue to wakeup.
101 while (!delayed_wakeup_queue_.empty() && 162 while (!delayed_wakeup_queue_.empty() &&
102 delayed_wakeup_queue_.min().time <= lazy_now->Now()) { 163 delayed_wakeup_queue_.min().time <= lazy_now->Now()) {
103 internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue; 164 internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue;
104 base::Optional<base::TimeTicks> next_wakeup = 165 // O(log n)
105 queue->WakeUpForDelayedWork(lazy_now); 166 delayed_wakeup_queue_.pop();
106 167
107 if (next_wakeup) { 168 queue->WakeUpForDelayedWork(lazy_now);
108 // O(log n)
109 delayed_wakeup_queue_.ChangeKey(queue->heap_handle(),
110 {next_wakeup.value(), queue});
111 queue->set_scheduled_time_domain_wakeup(next_wakeup.value());
112 } else {
113 // O(log n)
114 delayed_wakeup_queue_.pop();
115 }
116 } 169 }
117 } 170 }
118 171
119 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const { 172 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const {
120 DCHECK(main_thread_checker_.CalledOnValidThread()); 173 DCHECK(main_thread_checker_.CalledOnValidThread());
121 if (delayed_wakeup_queue_.empty()) 174 if (delayed_wakeup_queue_.empty())
122 return false; 175 return false;
123 176
124 *out_time = delayed_wakeup_queue_.min().time; 177 *out_time = delayed_wakeup_queue_.min().time;
125 return true; 178 return true;
126 } 179 }
127 180
128 bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const { 181 bool TimeDomain::NextScheduledTaskQueue(TaskQueue** out_task_queue) const {
129 DCHECK(main_thread_checker_.CalledOnValidThread()); 182 DCHECK(main_thread_checker_.CalledOnValidThread());
130 if (delayed_wakeup_queue_.empty()) 183 if (delayed_wakeup_queue_.empty())
131 return false; 184 return false;
132 185
133 *out_task_queue = delayed_wakeup_queue_.min().queue; 186 *out_task_queue = delayed_wakeup_queue_.min().queue;
134 return true; 187 return true;
135 } 188 }
136 189
137 void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const { 190 void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const {
138 state->BeginDictionary(); 191 state->BeginDictionary();
139 state->SetString("name", GetName()); 192 state->SetString("name", GetName());
193 state->BeginArray("updatable_queue_set");
194 for (auto* queue : updatable_queue_set_)
195 state->AppendString(queue->GetName());
196 state->EndArray();
140 state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size()); 197 state->SetInteger("registered_delay_count", delayed_wakeup_queue_.size());
141 if (!delayed_wakeup_queue_.empty()) { 198 if (!delayed_wakeup_queue_.empty()) {
142 base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now(); 199 base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now();
143 state->SetDouble("next_delay_ms", delay.InMillisecondsF()); 200 state->SetDouble("next_delay_ms", delay.InMillisecondsF());
144 } 201 }
145 AsValueIntoInternal(state); 202 AsValueIntoInternal(state);
146 state->EndDictionary(); 203 state->EndDictionary();
147 } 204 }
148 205
149 } // namespace scheduler 206 } // namespace scheduler
150 } // namespace blink 207 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698