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

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

Issue 2718293003: scheduler: Ensure consistent delayed task ordering between task queues (Closed)
Patch Set: Created 3 years, 9 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 15 matching lines...) Expand all
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 30
31 CancelDelayedWork(queue); 31 CancelDelayedWork(queue);
32 } 32 }
33 33
34 void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue, 34 void TimeDomain::ScheduleDelayedWork(internal::TaskQueueImpl* queue,
35 base::TimeTicks delayed_run_time, 35 base::TimeTicks delayed_run_time,
36 int sequence_num,
36 base::TimeTicks now) { 37 base::TimeTicks now) {
37 DCHECK(main_thread_checker_.CalledOnValidThread()); 38 DCHECK(main_thread_checker_.CalledOnValidThread());
38 DCHECK_EQ(queue->GetTimeDomain(), this); 39 DCHECK_EQ(queue->GetTimeDomain(), this);
39 DCHECK(queue->IsQueueEnabled()); 40 DCHECK(queue->IsQueueEnabled());
40 // We only want to store a single wakeup per queue, so we need to remove any 41 // We only want to store a single wakeup per queue, so we need to remove any
41 // previously registered wake up for |queue|. 42 // previously registered wake up for |queue|.
42 if (queue->heap_handle().IsValid()) { 43 if (queue->heap_handle().IsValid()) {
43 DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks()); 44 DCHECK_NE(queue->scheduled_time_domain_wakeup(), base::TimeTicks());
44 45
45 // O(log n) 46 // O(log n)
46 delayed_wakeup_queue_.ChangeKey(queue->heap_handle(), 47 delayed_wakeup_queue_.ChangeKey(queue->heap_handle(),
47 {delayed_run_time, queue}); 48 {delayed_run_time, sequence_num, queue});
48 } else { 49 } else {
49 // O(log n) 50 // O(log n)
50 delayed_wakeup_queue_.insert({delayed_run_time, queue}); 51 delayed_wakeup_queue_.insert({delayed_run_time, sequence_num, queue});
51 } 52 }
52 53
53 queue->set_scheduled_time_domain_wakeup(delayed_run_time); 54 queue->set_scheduled_time_domain_wakeup(delayed_run_time);
54 55
55 // If |queue| is the first wakeup then request the wakeup. 56 // If |queue| is the first wakeup then request the wakeup.
56 if (delayed_wakeup_queue_.min().queue == queue) 57 if (delayed_wakeup_queue_.min().queue == queue)
57 RequestWakeupAt(now, delayed_run_time); 58 RequestWakeupAt(now, delayed_run_time);
58 59
59 if (observer_) 60 if (observer_)
60 observer_->OnTimeDomainHasDelayedWork(queue); 61 observer_->OnTimeDomainHasDelayedWork(queue);
(...skipping 22 matching lines...) Expand all
83 if (delayed_wakeup_queue_.empty()) { 84 if (delayed_wakeup_queue_.empty()) {
84 CancelWakeupAt(prev_first_wakeup); 85 CancelWakeupAt(prev_first_wakeup);
85 } else if (prev_first_wakeup != delayed_wakeup_queue_.min().time) { 86 } else if (prev_first_wakeup != delayed_wakeup_queue_.min().time) {
86 CancelWakeupAt(prev_first_wakeup); 87 CancelWakeupAt(prev_first_wakeup);
87 RequestWakeupAt(Now(), delayed_wakeup_queue_.min().time); 88 RequestWakeupAt(Now(), delayed_wakeup_queue_.min().time);
88 } 89 }
89 } 90 }
90 91
91 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) { 92 void TimeDomain::WakeupReadyDelayedQueues(LazyNow* lazy_now) {
92 DCHECK(main_thread_checker_.CalledOnValidThread()); 93 DCHECK(main_thread_checker_.CalledOnValidThread());
93 // Wake up any queues with pending delayed work. Note std::multipmap stores 94 // Wake up any queues with pending delayed work. Note std::multimap stores
94 // the elements sorted by key, so the begin() iterator points to the earliest 95 // the elements sorted by key, so the begin() iterator points to the earliest
95 // queue to wakeup. 96 // queue to wakeup.
96 while (!delayed_wakeup_queue_.empty() && 97 while (!delayed_wakeup_queue_.empty() &&
97 delayed_wakeup_queue_.min().time <= lazy_now->Now()) { 98 delayed_wakeup_queue_.min().time <= lazy_now->Now()) {
98 internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue; 99 internal::TaskQueueImpl* queue = delayed_wakeup_queue_.min().queue;
99 base::Optional<base::TimeTicks> next_wakeup = 100 base::TimeTicks next_wake_up_time;
100 queue->WakeUpForDelayedWork(lazy_now); 101 int next_wake_up_sequence_num;
102 bool needs_wake_up = queue->WakeUpForDelayedWork(
103 lazy_now, &next_wake_up_time, &next_wake_up_sequence_num);
101 104
102 if (next_wakeup) { 105 if (needs_wake_up) {
103 // O(log n) 106 // O(log n)
104 delayed_wakeup_queue_.ReplaceMin({next_wakeup.value(), queue}); 107 delayed_wakeup_queue_.ReplaceMin(
105 queue->set_scheduled_time_domain_wakeup(next_wakeup.value()); 108 {next_wake_up_time, next_wake_up_sequence_num, queue});
109 queue->set_scheduled_time_domain_wakeup(next_wake_up_time);
106 } else { 110 } else {
107 // O(log n) 111 // O(log n)
108 delayed_wakeup_queue_.pop(); 112 delayed_wakeup_queue_.pop();
109 DCHECK_EQ(queue->scheduled_time_domain_wakeup(), base::TimeTicks()); 113 DCHECK_EQ(queue->scheduled_time_domain_wakeup(), base::TimeTicks());
110 } 114 }
111 } 115 }
112 } 116 }
113 117
114 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const { 118 bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const {
115 DCHECK(main_thread_checker_.CalledOnValidThread()); 119 DCHECK(main_thread_checker_.CalledOnValidThread());
(...skipping 20 matching lines...) Expand all
136 if (!delayed_wakeup_queue_.empty()) { 140 if (!delayed_wakeup_queue_.empty()) {
137 base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now(); 141 base::TimeDelta delay = delayed_wakeup_queue_.min().time - Now();
138 state->SetDouble("next_delay_ms", delay.InMillisecondsF()); 142 state->SetDouble("next_delay_ms", delay.InMillisecondsF());
139 } 143 }
140 AsValueIntoInternal(state); 144 AsValueIntoInternal(state);
141 state->EndDictionary(); 145 state->EndDictionary();
142 } 146 }
143 147
144 } // namespace scheduler 148 } // namespace scheduler
145 } // namespace blink 149 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698