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

Side by Side Diff: Source/platform/scheduler/Scheduler.cpp

Issue 595023002: Implement idle task scheduling. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "config.h" 5 #include "config.h"
6 #include "platform/scheduler/Scheduler.h" 6 #include "platform/scheduler/Scheduler.h"
7 7
8 #include "platform/PlatformThreadData.h" 8 #include "platform/PlatformThreadData.h"
9 #include "platform/Task.h" 9 #include "platform/Task.h"
10 #include "platform/ThreadTimers.h" 10 #include "platform/ThreadTimers.h"
11 #include "platform/TraceEvent.h" 11 #include "platform/TraceEvent.h"
12 #include "public/platform/Platform.h" 12 #include "public/platform/Platform.h"
13 // #include "public/web/WebBeginFrameArgs.h"
rmcilroy 2014/09/24 08:49:18 Sami: I get a checkdeps error when I include this
Sami 2014/09/24 14:00:40 Right, we can't use the web/ headers from platform
rmcilroy 2014/09/29 17:42:57 Done.
13 #include "wtf/MainThread.h" 14 #include "wtf/MainThread.h"
15 #include "wtf/PassOwnPtr.h"
14 16
15 namespace blink { 17 namespace blink {
16 18
17 namespace { 19 namespace {
18 20
19 // The time we should stay in CompositorPriority mode for, after a touch event. 21 // The time we should stay in CompositorPriority mode for, after a touch event.
20 double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1; 22 double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1;
21 23
22 // Can be created from any thread.
23 // Note if the scheduler gets shutdown, this may be run after.
24 class MainThreadIdleTaskAdapter : public WebThread::Task {
25 public:
26 MainThreadIdleTaskAdapter(const Scheduler::IdleTask& idleTask, double allott edTimeMs, const TraceLocation& location)
27 : m_idleTask(idleTask)
28 , m_allottedTimeMs(allottedTimeMs)
29 , m_location(location)
30 {
31 }
32
33 // WebThread::Task implementation.
34 virtual void run() OVERRIDE
35 {
36 TRACE_EVENT2("blink", "MainThreadIdleTaskAdapter::run",
37 "src_file", m_location.fileName(),
38 "src_func", m_location.functionName());
39 m_idleTask(m_allottedTimeMs);
40 }
41
42 private:
43 Scheduler::IdleTask m_idleTask;
44 double m_allottedTimeMs;
45 TraceLocation m_location;
46 };
47
48 } // namespace 24 } // namespace
49 25
50 // Typically only created from compositor or render threads. 26 // Typically only created from compositor or render threads.
51 // Note if the scheduler gets shutdown, this may be run after. 27 // Note if the scheduler gets shutdown, this may be run after.
52 class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Tas k { 28 class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Tas k {
53 public: 29 public:
54 MainThreadPendingHighPriorityTaskRunner() 30 MainThreadPendingHighPriorityTaskRunner()
55 { 31 {
56 ASSERT(Scheduler::shared()); 32 ASSERT(Scheduler::shared());
57 } 33 }
(...skipping 21 matching lines...) Expand all
79 const Scheduler::Task& task, const TraceLocation& location, const char* traceName) 55 const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
80 : m_task(task, location, traceName) 56 : m_task(task, location, traceName)
81 { 57 {
82 ASSERT(Scheduler::shared()); 58 ASSERT(Scheduler::shared());
83 } 59 }
84 60
85 // WebThread::Task implementation. 61 // WebThread::Task implementation.
86 virtual void run() OVERRIDE 62 virtual void run() OVERRIDE
87 { 63 {
88 Scheduler* scheduler = Scheduler::shared(); 64 Scheduler* scheduler = Scheduler::shared();
89 // FIXME: This check should't be necessary, tasks should not outlive bli nk. 65 // FIXME: This check shouldn't be necessary, tasks should not outlive bl ink.
90 ASSERT(scheduler); 66 ASSERT(scheduler);
91 if (scheduler) 67 if (scheduler)
92 Scheduler::shared()->runPendingHighPriorityTasksIfInCompositorPriori ty(); 68 Scheduler::shared()->runPendingHighPriorityTasksIfInCompositorPriori ty();
69
93 m_task.run(); 70 m_task.run();
94 } 71 }
95 72
96 TracedTask m_task; 73 private:
74 TracedStandardTask m_task;
97 }; 75 };
98 76
77
99 Scheduler* Scheduler::s_sharedScheduler = nullptr; 78 Scheduler* Scheduler::s_sharedScheduler = nullptr;
100 79
101 void Scheduler::initializeOnMainThread() 80 void Scheduler::initializeOnMainThread()
102 { 81 {
103 s_sharedScheduler = new Scheduler(); 82 s_sharedScheduler = new Scheduler();
104 } 83 }
105 84
106 void Scheduler::shutdown() 85 void Scheduler::shutdown()
107 { 86 {
108 delete s_sharedScheduler; 87 delete s_sharedScheduler;
109 s_sharedScheduler = nullptr; 88 s_sharedScheduler = nullptr;
110 } 89 }
111 90
112 Scheduler* Scheduler::shared() 91 Scheduler* Scheduler::shared()
113 { 92 {
114 return s_sharedScheduler; 93 return s_sharedScheduler;
115 } 94 }
116 95
117 Scheduler::Scheduler() 96 Scheduler::Scheduler()
118 : m_sharedTimerFunction(nullptr) 97 : m_sharedTimerFunction(nullptr)
119 , m_mainThread(blink::Platform::current()->currentThread()) 98 , m_mainThread(blink::Platform::current()->currentThread())
120 , m_compositorPriorityPolicyEndTimeSeconds(0) 99 , m_compositorPriorityPolicyEndTimeSeconds(0)
100 , m_currentFrameDeadlineSeconds(0)
121 , m_highPriorityTaskCount(0) 101 , m_highPriorityTaskCount(0)
122 , m_highPriorityTaskRunnerPosted(false) 102 , m_highPriorityTaskRunnerPosted(false)
123 , m_schedulerPolicy(Normal) 103 , m_schedulerPolicy(Normal)
124 { 104 {
125 } 105 }
126 106
127 Scheduler::~Scheduler() 107 Scheduler::~Scheduler()
128 { 108 {
129 while (hasPendingHighPriorityWork()) { 109 while (hasPendingHighPriorityWork()) {
130 swapQueuesAndRunPendingTasks(); 110 swapQueuesAndRunPendingTasks();
131 } 111 }
132 } 112 }
133 113
134 void Scheduler::willBeginFrame(const WebBeginFrameArgs& args) 114 void Scheduler::willBeginFrame(const WebBeginFrameArgs& args)
135 { 115 {
136 // TODO: Use frame deadline and interval to schedule idle tasks. 116 m_currentFrameDeadlineSeconds = args.lastFrameTimeMonotonic + args.interval;
rmcilroy 2014/09/24 08:49:18 This is the deadline used by the compositor implem
Sami 2014/09/24 14:00:40 I think there are two different deadlines here: 1)
rmcilroy 2014/09/29 17:42:57 Acknowledged.
137 } 117 }
138 118
139 void Scheduler::didCommitFrameToCompositor() 119 void Scheduler::didCommitFrameToCompositor()
140 { 120 {
121 if (getSecondsUntilFrameDeadline() > 0) {
Sami 2014/09/24 14:00:40 I don't think we want to run any tasks directly in
rmcilroy 2014/09/29 17:42:57 Sounds like a plan - done.
122 swapQueuesAndRunPendingIdleTasks();
123 }
124 // Reset frame deadline.
125 m_currentFrameDeadlineSeconds = 0;
126
141 // TODO: Trigger the frame deadline immediately. 127 // TODO: Trigger the frame deadline immediately.
142 } 128 }
143 129
144 void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask& idleTask)
145 {
146 // TODO: send a real allottedTime here.
147 m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location)) ;
148 }
149
150 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons t Task& task, const char* traceName) 130 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons t Task& task, const char* traceName)
151 { 131 {
152 Locker<Mutex> lock(m_pendingTasksMutex); 132 Locker<Mutex> lock(m_pendingTasksMutex);
153 133
154 m_pendingHighPriorityTasks.append(TracedTask(task, location, traceName)); 134 m_pendingHighPriorityTasks.append(adoptPtr(new TracedStandardTask(task, loca tion, traceName)));
155 atomicIncrement(&m_highPriorityTaskCount); 135 atomicIncrement(&m_highPriorityTaskCount);
156 maybePostMainThreadPendingHighPriorityTaskRunner(); 136 maybePostMainThreadPendingHighPriorityTaskRunner();
157 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount); 137 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount);
158 } 138 }
159 139
140 void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTa sk& idleTask, const char* traceName)
141 {
142 Locker<Mutex> lock(m_pendingTasksMutex);
143 m_pendingIdleTasks.append(adoptPtr(new TracedIdleTask(idleTask, location, tr aceName)));
144 }
145
160 void Scheduler::postTask(const TraceLocation& location, const Task& task) 146 void Scheduler::postTask(const TraceLocation& location, const Task& task)
161 { 147 {
162 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::MainThreadTask")); 148 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::MainThreadTask"));
163 } 149 }
164 150
165 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) 151 void Scheduler::postInputTask(const TraceLocation& location, const Task& task)
166 { 152 {
167 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask"); 153 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask");
168 } 154 }
169 155
170 void Scheduler::didReceiveInputEvent() 156 void Scheduler::didReceiveInputEvent()
171 { 157 {
172 enterSchedulerPolicy(CompositorPriority); 158 enterSchedulerPolicy(CompositorPriority);
173 } 159 }
174 160
175 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk) 161 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk)
176 { 162 {
177 postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask"); 163 postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask");
178 } 164 }
179 165
180 void Scheduler::postIpcTask(const TraceLocation& location, const Task& task) 166 void Scheduler::postIpcTask(const TraceLocation& location, const Task& task)
181 { 167 {
182 // FIXME: we want IPCs to be high priority, but we can't currently do that b ecause some of them can take a very long 168 // FIXME: we want IPCs to be high priority, but we can't currently do that b ecause some of them can take a very long
183 // time to process. These need refactoring but we need to add some infrastru cture to identify them. 169 // time to process. These need refactoring but we need to add some infrastru cture to identify them.
184 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::IpcTask")); 170 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::IpcTask"));
185 } 171 }
186 172
173 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task)
174 {
175 postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask");
176 }
177
187 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner() 178 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner()
188 { 179 {
189 ASSERT(m_pendingTasksMutex.locked()); 180 ASSERT(m_pendingTasksMutex.locked());
190 if (m_highPriorityTaskRunnerPosted) 181 if (m_highPriorityTaskRunnerPosted)
191 return; 182 return;
192 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); 183 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner());
193 m_highPriorityTaskRunnerPosted = true; 184 m_highPriorityTaskRunnerPosted = true;
194 } 185 }
195 186
196 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task)
197 {
198 scheduleIdleTask(location, idleTask);
199 }
200 187
201 void Scheduler::tickSharedTimer() 188 void Scheduler::tickSharedTimer()
202 { 189 {
203 TRACE_EVENT0("blink", "Scheduler::tickSharedTimer"); 190 TRACE_EVENT0("blink", "Scheduler::tickSharedTimer");
204 191
205 // Run any high priority tasks that are queued up, otherwise the blink timer s will yield immediately. 192 // Run any high priority tasks that are queued up, otherwise the blink timer s will yield immediately.
206 bool workDone = runPendingHighPriorityTasksIfInCompositorPriority(); 193 bool workDone = runPendingHighPriorityTasksIfInCompositorPriority();
207 m_sharedTimerFunction(); 194 m_sharedTimerFunction();
208 195
209 // The blink timers may have just yielded, so run any high priority tasks th at where queued up 196 // The blink timers may have just yielded, so run any high priority tasks th at where queued up
(...skipping 11 matching lines...) Expand all
221 return swapQueuesAndRunPendingTasks(); 208 return swapQueuesAndRunPendingTasks();
222 } 209 }
223 210
224 bool Scheduler::swapQueuesAndRunPendingTasks() 211 bool Scheduler::swapQueuesAndRunPendingTasks()
225 { 212 {
226 ASSERT(isMainThread()); 213 ASSERT(isMainThread());
227 214
228 // These locks guard against another thread posting input or compositor task s while we swap the buffers. 215 // These locks guard against another thread posting input or compositor task s while we swap the buffers.
229 // One the buffers have been swapped we can safely access the returned deque without having to lock. 216 // One the buffers have been swapped we can safely access the returned deque without having to lock.
230 m_pendingTasksMutex.lock(); 217 m_pendingTasksMutex.lock();
231 Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffer s(); 218 Deque<OwnPtr<TracedTask> >& highPriorityTasks = m_pendingHighPriorityTasks.s wapBuffers();
232 maybeEnterNormalSchedulerPolicy(); 219 maybeEnterNormalSchedulerPolicy();
233 m_pendingTasksMutex.unlock(); 220 m_pendingTasksMutex.unlock();
234 return executeHighPriorityTasks(highPriorityTasks); 221 return executeHighPriorityTasks(highPriorityTasks);
235 } 222 }
236 223
237 void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting() 224 void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting()
238 { 225 {
239 ASSERT(isMainThread()); 226 ASSERT(isMainThread());
240 227
241 // These locks guard against another thread posting input or compositor task s while we swap the buffers. 228 // These locks guard against another thread posting input or compositor task s while we swap the buffers.
242 // One the buffers have been swapped we can safely access the returned deque without having to lock. 229 // One the buffers have been swapped we can safely access the returned deque without having to lock.
243 m_pendingTasksMutex.lock(); 230 m_pendingTasksMutex.lock();
244 Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffer s(); 231 Deque<OwnPtr<TracedTask> >& highPriorityTasks = m_pendingHighPriorityTasks.s wapBuffers();
245 m_highPriorityTaskRunnerPosted = false; 232 m_highPriorityTaskRunnerPosted = false;
246 maybeEnterNormalSchedulerPolicy(); 233 maybeEnterNormalSchedulerPolicy();
247 m_pendingTasksMutex.unlock(); 234 m_pendingTasksMutex.unlock();
248 executeHighPriorityTasks(highPriorityTasks); 235 executeHighPriorityTasks(highPriorityTasks);
249 } 236 }
250 237
251 void Scheduler::maybeEnterNormalSchedulerPolicy() 238 void Scheduler::maybeEnterNormalSchedulerPolicy()
252 { 239 {
253 ASSERT(isMainThread()); 240 ASSERT(isMainThread());
254 ASSERT(m_pendingTasksMutex.locked()); 241 ASSERT(m_pendingTasksMutex.locked());
255 242
256 // Go back to the normal scheduler policy if enough time has elapsed. 243 // Go back to the normal scheduler policy if enough time has elapsed.
257 if (schedulerPolicy() == CompositorPriority && Platform::current()->monotoni callyIncreasingTime() > m_compositorPriorityPolicyEndTimeSeconds) 244 if (schedulerPolicy() == CompositorPriority && Platform::current()->monotoni callyIncreasingTime() > m_compositorPriorityPolicyEndTimeSeconds)
258 enterSchedulerPolicyLocked(Normal); 245 enterSchedulerPolicyLocked(Normal);
259 } 246 }
260 247
261 bool Scheduler::executeHighPriorityTasks(Deque<TracedTask>& highPriorityTasks) 248 bool Scheduler::executeHighPriorityTasks(Deque<OwnPtr<TracedTask> >& highPriorit yTasks)
262 { 249 {
263 TRACE_EVENT0("blink", "Scheduler::executeHighPriorityTasks"); 250 TRACE_EVENT0("blink", "Scheduler::executeHighPriorityTasks");
264 int highPriorityTasksExecuted = 0; 251 int highPriorityTasksExecuted = 0;
265 while (!highPriorityTasks.isEmpty()) { 252 while (!highPriorityTasks.isEmpty()) {
266 highPriorityTasks.takeFirst().run(); 253 highPriorityTasks.takeFirst()->run();
267 highPriorityTasksExecuted++; 254 highPriorityTasksExecuted++;
268 } 255 }
269 256
270 int highPriorityTaskCount = atomicSubtract(&m_highPriorityTaskCount, highPri orityTasksExecuted); 257 int highPriorityTaskCount = atomicSubtract(&m_highPriorityTaskCount, highPri orityTasksExecuted);
271 ASSERT_UNUSED(highPriorityTaskCount, highPriorityTaskCount >= 0); 258 ASSERT_UNUSED(highPriorityTaskCount, highPriorityTaskCount >= 0);
272 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount); 259 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount);
273 return highPriorityTasksExecuted > 0; 260 return highPriorityTasksExecuted > 0;
274 } 261 }
275 262
263 bool Scheduler::swapQueuesAndRunPendingIdleTasks()
264 {
265 ASSERT(isMainThread());
266
267 // These locks guard against another thread posting input or compositor task s while we swap the buffers.
268 // One the buffers have been swapped we can safely access the returned deque without having to lock.
269 m_pendingTasksMutex.lock();
270 Deque<OwnPtr<TracedTask> >& idleTasks = m_pendingIdleTasks.swapBuffers();
271 m_pendingTasksMutex.unlock();
272 return executeIdleTasks(idleTasks);
273 }
picksi1 2014/09/25 08:53:31 I wonder if the added complexity of swapping buffe
rmcilroy 2014/09/29 17:42:57 I've re-worked this completely such that we only e
274
275 bool Scheduler::executeIdleTasks(Deque<OwnPtr<TracedTask> >& idleTasks)
276 {
277 TRACE_EVENT0("blink", "Scheduler::executeIdleTasks");
278 int idleTasksExecuted = 0;
279 while (!idleTasks.isEmpty() && getSecondsUntilFrameDeadline() > 0) {
280 idleTasks.takeFirst()->run();
281 idleTasksExecuted++;
282
283 // Give high priority a chance to preempt idle tasks.
284 runPendingHighPriorityTasksIfInCompositorPriority();
285 }
286
287 if (!idleTasks.isEmpty()) {
288 repostAllIdleTasks(idleTasks);
289 }
290 ASSERT(idleTasks.isEmpty());
291
292 return idleTasksExecuted > 0;
293 }
294
295 void Scheduler::repostAllIdleTasks(Deque<OwnPtr<TracedTask> >& idleTasks)
296 {
297 Locker<Mutex> lock(m_pendingTasksMutex);
298 while (!idleTasks.isEmpty()) {
299 // TODO: Post at the front to avoid starvation?
300 m_pendingIdleTasks.append(idleTasks.takeFirst());
301 }
302 }
303
276 void Scheduler::sharedTimerAdapter() 304 void Scheduler::sharedTimerAdapter()
277 { 305 {
278 shared()->tickSharedTimer(); 306 shared()->tickSharedTimer();
279 } 307 }
280 308
281 void Scheduler::setSharedTimerFiredFunction(void (*function)()) 309 void Scheduler::setSharedTimerFiredFunction(void (*function)())
282 { 310 {
283 m_sharedTimerFunction = function; 311 m_sharedTimerFunction = function;
284 blink::Platform::current()->setSharedTimerFiredFunction(function ? &Schedule r::sharedTimerAdapter : nullptr); 312 blink::Platform::current()->setSharedTimerFiredFunction(function ? &Schedule r::sharedTimerAdapter : nullptr);
285 } 313 }
(...skipping 20 matching lines...) Expand all
306 bool Scheduler::hasPendingHighPriorityWork() const 334 bool Scheduler::hasPendingHighPriorityWork() const
307 { 335 {
308 // This method is expected to be run on the main thread, but the high priori ty tasks will be posted by 336 // This method is expected to be run on the main thread, but the high priori ty tasks will be posted by
309 // other threads. We could use locks here, but this function is (sometimes) called a lot by 337 // other threads. We could use locks here, but this function is (sometimes) called a lot by
310 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar rier loads here which 338 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar rier loads here which
311 // should be cheaper. 339 // should be cheaper.
312 // NOTE it's possible the barrier read is overkill here, since delayed yield ing isn't a big deal. 340 // NOTE it's possible the barrier read is overkill here, since delayed yield ing isn't a big deal.
313 return acquireLoad(&m_highPriorityTaskCount) != 0; 341 return acquireLoad(&m_highPriorityTaskCount) != 0;
314 } 342 }
315 343
344 double Scheduler::getSecondsUntilFrameDeadline() const
345 {
346 double delta = m_currentFrameDeadlineSeconds - Platform::current()->monotoni callyIncreasingTime();
347 return (delta > 0) ? delta : 0;
348 }
349
picksi1 2014/09/25 08:53:31 Do we actually need the result in seconds? Is it w
rmcilroy 2014/09/29 17:42:57 Reworked this so that we have canRunIdleTask() and
316 Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const 350 Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const
317 { 351 {
318 ASSERT(isMainThread()); 352 ASSERT(isMainThread());
319 // It's important not to miss the transition from normal to low latency mode , otherwise we're likely to 353 // It's important not to miss the transition from normal to low latency mode , otherwise we're likely to
320 // delay the processing of input tasks. Since that transition is triggered b y a different thread, we 354 // delay the processing of input tasks. Since that transition is triggered b y a different thread, we
321 // need either a lock or a memory barrier, and the memory barrier is probabl y cheaper. 355 // need either a lock or a memory barrier, and the memory barrier is probabl y cheaper.
322 return static_cast<SchedulerPolicy>(acquireLoad(&m_schedulerPolicy)); 356 return static_cast<SchedulerPolicy>(acquireLoad(&m_schedulerPolicy));
323 } 357 }
324 358
325 void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy) 359 void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy)
326 { 360 {
327 Locker<Mutex> lock(m_pendingTasksMutex); 361 Locker<Mutex> lock(m_pendingTasksMutex);
328 enterSchedulerPolicyLocked(schedulerPolicy); 362 enterSchedulerPolicyLocked(schedulerPolicy);
329 } 363 }
330 364
331 void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy) 365 void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy)
332 { 366 {
333 ASSERT(m_pendingTasksMutex.locked()); 367 ASSERT(m_pendingTasksMutex.locked());
334 if (schedulerPolicy == CompositorPriority) 368 if (schedulerPolicy == CompositorPriority)
335 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; 369 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds;
336 370
337 releaseStore(&m_schedulerPolicy, schedulerPolicy); 371 releaseStore(&m_schedulerPolicy, schedulerPolicy);
338 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy); 372 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy);
339 } 373 }
340 374
341 } // namespace blink 375 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698