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

Side by Side Diff: components/scheduler/renderer/throttling_helper.cc

Issue 2080563003: (Merge m52) Fix a bug with throttling and timer queue suspension (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: Created 4 years, 6 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 "components/scheduler/renderer/throttling_helper.h" 5 #include "components/scheduler/renderer/throttling_helper.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "components/scheduler/base/real_time_domain.h" 8 #include "components/scheduler/base/real_time_domain.h"
9 #include "components/scheduler/child/scheduler_tqm_delegate.h" 9 #include "components/scheduler/child/scheduler_tqm_delegate.h"
10 #include "components/scheduler/renderer/renderer_scheduler_impl.h" 10 #include "components/scheduler/renderer/renderer_scheduler_impl.h"
(...skipping 25 matching lines...) Expand all
36 // before unregistering the time domain. 36 // before unregistering the time domain.
37 for (const TaskQueueMap::value_type& map_entry : throttled_queues_) { 37 for (const TaskQueueMap::value_type& map_entry : throttled_queues_) {
38 TaskQueue* task_queue = map_entry.first; 38 TaskQueue* task_queue = map_entry.first;
39 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 39 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
40 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); 40 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
41 } 41 }
42 42
43 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get()); 43 renderer_scheduler_->UnregisterTimeDomain(time_domain_.get());
44 } 44 }
45 45
46 void ThrottlingHelper::SetQueueEnabled(TaskQueue* task_queue, bool enabled) {
47 TaskQueueMap::iterator find_it = throttled_queues_.find(task_queue);
48
49 if (find_it == throttled_queues_.end()) {
50 task_queue->SetQueueEnabled(enabled);
51 return;
52 }
53
54 find_it->second.enabled = enabled;
55
56 // We don't enable the queue here because it's throttled and there might be
57 // tasks in it's work queue that would execute immediatly rather than after
58 // PumpThrottledTasks runs.
59 if (!enabled)
60 task_queue->SetQueueEnabled(false);
61 }
62
46 void ThrottlingHelper::IncreaseThrottleRefCount(TaskQueue* task_queue) { 63 void ThrottlingHelper::IncreaseThrottleRefCount(TaskQueue* task_queue) {
47 DCHECK_NE(task_queue, task_runner_.get()); 64 DCHECK_NE(task_queue, task_runner_.get());
48 65
49 std::pair<TaskQueueMap::iterator, bool> insert_result = 66 std::pair<TaskQueueMap::iterator, bool> insert_result =
50 throttled_queues_.insert(std::make_pair(task_queue, 1)); 67 throttled_queues_.insert(std::make_pair(
68 task_queue, Metadata(1, task_queue->IsQueueEnabled())));
51 69
52 if (insert_result.second) { 70 if (insert_result.second) {
53 // The insert was succesful so we need to throttle the queue. 71 // The insert was succesful so we need to throttle the queue.
54 task_queue->SetTimeDomain(time_domain_.get()); 72 task_queue->SetTimeDomain(time_domain_.get());
55 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); 73 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
56 task_queue->SetQueueEnabled(false); 74 task_queue->SetQueueEnabled(false);
57 75
58 if (!task_queue->IsEmpty()) { 76 if (!task_queue->IsEmpty()) {
59 if (task_queue->HasPendingImmediateWork()) { 77 if (task_queue->HasPendingImmediateWork()) {
60 OnTimeDomainHasImmediateWork(); 78 OnTimeDomainHasImmediateWork();
61 } else { 79 } else {
62 OnTimeDomainHasDelayedWork(); 80 OnTimeDomainHasDelayedWork();
63 } 81 }
64 } 82 }
65 } else { 83 } else {
66 // An entry already existed in the map so we need to increment the refcount. 84 // An entry already existed in the map so we need to increment the refcount.
67 insert_result.first->second++; 85 insert_result.first->second.throttling_ref_count++;
68 } 86 }
69 } 87 }
70 88
71 void ThrottlingHelper::DecreaseThrottleRefCount(TaskQueue* task_queue) { 89 void ThrottlingHelper::DecreaseThrottleRefCount(TaskQueue* task_queue) {
72 TaskQueueMap::iterator iter = throttled_queues_.find(task_queue); 90 TaskQueueMap::iterator iter = throttled_queues_.find(task_queue);
73 91
74 if (iter != throttled_queues_.end() && --iter->second == 0) { 92 if (iter != throttled_queues_.end() &&
93 --iter->second.throttling_ref_count == 0) {
94 bool enabled = iter->second.enabled;
75 // The refcount has become zero, we need to unthrottle the queue. 95 // The refcount has become zero, we need to unthrottle the queue.
76 throttled_queues_.erase(iter); 96 throttled_queues_.erase(iter);
77 97
78 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain()); 98 task_queue->SetTimeDomain(renderer_scheduler_->real_time_domain());
79 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); 99 task_queue->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
80 task_queue->SetQueueEnabled(true); 100 task_queue->SetQueueEnabled(enabled);
81 } 101 }
82 } 102 }
83 103
84 void ThrottlingHelper::UnregisterTaskQueue(TaskQueue* task_queue) { 104 void ThrottlingHelper::UnregisterTaskQueue(TaskQueue* task_queue) {
85 throttled_queues_.erase(task_queue); 105 throttled_queues_.erase(task_queue);
86 } 106 }
87 107
88 void ThrottlingHelper::OnTimeDomainHasImmediateWork() { 108 void ThrottlingHelper::OnTimeDomainHasImmediateWork() {
89 // Forward to the main thread if called from another thread. 109 // Forward to the main thread if called from another thread.
90 if (!task_runner_->RunsTasksOnCurrentThread()) { 110 if (!task_runner_->RunsTasksOnCurrentThread()) {
(...skipping 22 matching lines...) Expand all
113 TRACE_EVENT0(tracing_category_, "ThrottlingHelper::PumpThrottledTasks"); 133 TRACE_EVENT0(tracing_category_, "ThrottlingHelper::PumpThrottledTasks");
114 pending_pump_throttled_tasks_runtime_ = base::TimeTicks(); 134 pending_pump_throttled_tasks_runtime_ = base::TimeTicks();
115 135
116 base::TimeTicks now = tick_clock_->NowTicks(); 136 base::TimeTicks now = tick_clock_->NowTicks();
117 time_domain_->AdvanceTo(now); 137 time_domain_->AdvanceTo(now);
118 for (const TaskQueueMap::value_type& map_entry : throttled_queues_) { 138 for (const TaskQueueMap::value_type& map_entry : throttled_queues_) {
119 TaskQueue* task_queue = map_entry.first; 139 TaskQueue* task_queue = map_entry.first;
120 if (task_queue->IsEmpty()) 140 if (task_queue->IsEmpty())
121 continue; 141 continue;
122 142
123 task_queue->SetQueueEnabled(true); 143 task_queue->SetQueueEnabled(map_entry.second.enabled);
124 task_queue->PumpQueue(false); 144 task_queue->PumpQueue(false);
125 } 145 }
126 // Make sure NextScheduledRunTime gives us an up-to date result. 146 // Make sure NextScheduledRunTime gives us an up-to date result.
127 time_domain_->ClearExpiredWakeups(); 147 time_domain_->ClearExpiredWakeups();
128 148
129 base::TimeTicks next_scheduled_delayed_task; 149 base::TimeTicks next_scheduled_delayed_task;
130 // Maybe schedule a call to ThrottlingHelper::PumpThrottledTasks if there is 150 // Maybe schedule a call to ThrottlingHelper::PumpThrottledTasks if there is
131 // a pending delayed task. NOTE posting a non-delayed task in the future will 151 // a pending delayed task. NOTE posting a non-delayed task in the future will
132 // result in ThrottlingHelper::OnTimeDomainHasImmediateWork being called. 152 // result in ThrottlingHelper::OnTimeDomainHasImmediateWork being called.
133 if (time_domain_->NextScheduledRunTime(&next_scheduled_delayed_task)) { 153 if (time_domain_->NextScheduledRunTime(&next_scheduled_delayed_task)) {
(...skipping 29 matching lines...) Expand all
163 183
164 base::TimeDelta delay = pending_pump_throttled_tasks_runtime_ - now; 184 base::TimeDelta delay = pending_pump_throttled_tasks_runtime_ - now;
165 TRACE_EVENT1(tracing_category_, 185 TRACE_EVENT1(tracing_category_,
166 "ThrottlingHelper::MaybeSchedulePumpThrottledTasksLocked", 186 "ThrottlingHelper::MaybeSchedulePumpThrottledTasksLocked",
167 "delay_till_next_pump_ms", delay.InMilliseconds()); 187 "delay_till_next_pump_ms", delay.InMilliseconds());
168 task_runner_->PostDelayedTask( 188 task_runner_->PostDelayedTask(
169 from_here, suspend_timers_when_backgrounded_closure_.callback(), delay); 189 from_here, suspend_timers_when_backgrounded_closure_.callback(), delay);
170 } 190 }
171 191
172 } // namespace scheduler 192 } // namespace scheduler
OLDNEW
« no previous file with comments | « components/scheduler/renderer/throttling_helper.h ('k') | components/scheduler/renderer/throttling_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698