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

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: Avoid reposting idle tasks Created 6 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 | 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 "wtf/MainThread.h" 13 #include "wtf/MainThread.h"
14 14
15 namespace blink { 15 namespace blink {
16 16
17 namespace { 17 namespace {
18 18
19 // The time we should stay in CompositorPriority mode for, after a touch event. 19 // The time we should stay in CompositorPriority mode for, after a touch event.
20 double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1; 20 double kLowSchedulerPolicyAfterTouchTimeSeconds = 0.1;
21 21
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 22 } // namespace
49 23
50 // Typically only created from compositor or render threads. 24 // Typically only created from compositor or render threads.
51 // Note if the scheduler gets shutdown, this may be run after. 25 // Note if the scheduler gets shutdown, this may be run after.
52 class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Tas k { 26 class Scheduler::MainThreadPendingHighPriorityTaskRunner : public WebThread::Tas k {
53 public: 27 public:
54 MainThreadPendingHighPriorityTaskRunner() 28 MainThreadPendingHighPriorityTaskRunner()
55 { 29 {
56 ASSERT(Scheduler::shared()); 30 ASSERT(Scheduler::shared());
57 } 31 }
(...skipping 21 matching lines...) Expand all
79 const Scheduler::Task& task, const TraceLocation& location, const char* traceName) 53 const Scheduler::Task& task, const TraceLocation& location, const char* traceName)
80 : m_task(task, location, traceName) 54 : m_task(task, location, traceName)
81 { 55 {
82 ASSERT(Scheduler::shared()); 56 ASSERT(Scheduler::shared());
83 } 57 }
84 58
85 // WebThread::Task implementation. 59 // WebThread::Task implementation.
86 virtual void run() OVERRIDE 60 virtual void run() OVERRIDE
87 { 61 {
88 Scheduler* scheduler = Scheduler::shared(); 62 Scheduler* scheduler = Scheduler::shared();
89 // FIXME: This check should't be necessary, tasks should not outlive bli nk. 63 // FIXME: This check shouldn't be necessary, tasks should not outlive bl ink.
90 ASSERT(scheduler); 64 ASSERT(scheduler);
91 if (scheduler) 65 if (scheduler)
92 Scheduler::shared()->runPendingHighPriorityTasksIfInCompositorPriori ty(); 66 scheduler->runPendingHighPriorityTasksIfInCompositorPriority();
67
93 m_task.run(); 68 m_task.run();
94 } 69 }
95 70
96 TracedTask m_task; 71 private:
72 TracedStandardTask m_task;
97 }; 73 };
98 74
75
76 // Can be created from any thread.
77 // Note if the scheduler gets shutdown, this may be run after.
78 class Scheduler::MainThreadPendingIdleTaskRunner : public WebThread::Task {
79 public:
80 MainThreadPendingIdleTaskRunner()
81 {
82 ASSERT(Scheduler::shared());
83 }
84
85 // WebThread::Task implementation.
86 virtual void run() OVERRIDE
87 {
88 Scheduler* scheduler = Scheduler::shared();
89 // FIXME: This check shouldn't be necessary, tasks should not outlive bl ink.
90 ASSERT(scheduler);
91 if (scheduler) {
92 scheduler->runPendingHighPriorityTasksIfInCompositorPriority();
93 scheduler->runPendingIdleTaskIfCanRunIdleTask();
94 // If possible, run the next idle task by reposting on the main thre ad.
95 scheduler->maybePostMainThreadPendingIdleTask();
96 }
97 }
98
99 };
100
101
99 Scheduler* Scheduler::s_sharedScheduler = nullptr; 102 Scheduler* Scheduler::s_sharedScheduler = nullptr;
100 103
101 void Scheduler::initializeOnMainThread() 104 void Scheduler::initializeOnMainThread()
102 { 105 {
103 s_sharedScheduler = new Scheduler(); 106 s_sharedScheduler = new Scheduler();
104 } 107 }
105 108
106 void Scheduler::shutdown() 109 void Scheduler::shutdown()
107 { 110 {
108 delete s_sharedScheduler; 111 delete s_sharedScheduler;
109 s_sharedScheduler = nullptr; 112 s_sharedScheduler = nullptr;
110 } 113 }
111 114
112 Scheduler* Scheduler::shared() 115 Scheduler* Scheduler::shared()
113 { 116 {
114 return s_sharedScheduler; 117 return s_sharedScheduler;
115 } 118 }
116 119
117 Scheduler::Scheduler() 120 Scheduler::Scheduler()
118 : m_sharedTimerFunction(nullptr) 121 : m_sharedTimerFunction(nullptr)
119 , m_mainThread(blink::Platform::current()->currentThread()) 122 , m_mainThread(blink::Platform::current()->currentThread())
120 , m_compositorPriorityPolicyEndTimeSeconds(0) 123 , m_compositorPriorityPolicyEndTimeSeconds(0)
124 , m_currentFrameDeadlineSeconds(0)
121 , m_highPriorityTaskCount(0) 125 , m_highPriorityTaskCount(0)
122 , m_highPriorityTaskRunnerPosted(false) 126 , m_highPriorityTaskRunnerPosted(false)
123 , m_schedulerPolicy(Normal) 127 , m_schedulerPolicy(Normal)
124 { 128 {
125 } 129 }
126 130
127 Scheduler::~Scheduler() 131 Scheduler::~Scheduler()
128 { 132 {
129 while (hasPendingHighPriorityWork()) { 133 while (hasPendingHighPriorityWork()) {
130 swapQueuesAndRunPendingTasks(); 134 swapQueuesAndRunPendingTasks();
131 } 135 }
132 } 136 }
133 137
134 void Scheduler::willBeginFrame(const WebBeginFrameArgs& args) 138 void Scheduler::willBeginFrame(double frameDeadlineSeconds)
135 { 139 {
136 // TODO: Use frame deadline and interval to schedule idle tasks. 140 m_currentFrameCommitted = false;
141 m_currentFrameDeadlineSeconds = frameDeadlineSeconds;
142 // TODO: Schedule a deferred task here to run idle work if didCommitFrameToC ompositor never get's called
137 } 143 }
138 144
139 void Scheduler::didCommitFrameToCompositor() 145 void Scheduler::didCommitFrameToCompositor()
140 { 146 {
141 // TODO: Trigger the frame deadline immediately. 147 m_currentFrameCommitted = true;
142 } 148 maybePostMainThreadPendingIdleTask();
143
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 }
149 150
150 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons t Task& task, const char* traceName) 151 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons t Task& task, const char* traceName)
151 { 152 {
152 Locker<Mutex> lock(m_pendingTasksMutex); 153 Locker<Mutex> lock(m_pendingTasksMutex);
153 154
154 m_pendingHighPriorityTasks.append(TracedTask(task, location, traceName)); 155 m_pendingHighPriorityTasks.append(TracedStandardTask(task, location, traceNa me));
155 atomicIncrement(&m_highPriorityTaskCount); 156 atomicIncrement(&m_highPriorityTaskCount);
156 maybePostMainThreadPendingHighPriorityTaskRunner(); 157 maybePostMainThreadPendingHighPriorityTaskRunner();
157 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount); 158 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri orityTasks", m_highPriorityTaskCount);
158 } 159 }
159 160
161 void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTa sk& idleTask, const char* traceName)
162 {
163 Locker<Mutex> lock(m_pendingTasksMutex);
164 m_pendingIdleTasks.append(TracedIdleTask(idleTask, location, traceName));
165 }
166
160 void Scheduler::postTask(const TraceLocation& location, const Task& task) 167 void Scheduler::postTask(const TraceLocation& location, const Task& task)
161 { 168 {
162 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::MainThreadTask")); 169 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::MainThreadTask"));
163 } 170 }
164 171
165 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) 172 void Scheduler::postInputTask(const TraceLocation& location, const Task& task)
166 { 173 {
167 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask"); 174 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask");
168 } 175 }
169 176
170 void Scheduler::didReceiveInputEvent() 177 void Scheduler::didReceiveInputEvent()
171 { 178 {
172 enterSchedulerPolicy(CompositorPriority); 179 enterSchedulerPolicy(CompositorPriority);
173 } 180 }
174 181
175 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk) 182 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk)
176 { 183 {
177 postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask"); 184 postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask");
178 } 185 }
179 186
180 void Scheduler::postIpcTask(const TraceLocation& location, const Task& task) 187 void Scheduler::postIpcTask(const TraceLocation& location, const Task& task)
181 { 188 {
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 189 // 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. 190 // 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")); 191 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche duler::IpcTask"));
185 } 192 }
186 193
194 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task)
195 {
196 postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask");
197 }
198
187 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner() 199 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner()
188 { 200 {
189 ASSERT(m_pendingTasksMutex.locked()); 201 ASSERT(m_pendingTasksMutex.locked());
190 if (m_highPriorityTaskRunnerPosted) 202 if (m_highPriorityTaskRunnerPosted)
191 return; 203 return;
192 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); 204 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner());
193 m_highPriorityTaskRunnerPosted = true; 205 m_highPriorityTaskRunnerPosted = true;
194 } 206 }
195 207
196 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task) 208 bool Scheduler::maybePostMainThreadPendingIdleTask()
197 { 209 {
198 scheduleIdleTask(location, idleTask); 210 TRACE_EVENT0("blink", "Scheduler::maybePostMainThreadPendingIdleTask");
211 if (canRunIdleTask()) {
alexclarke 2014/10/03 09:59:19 Which threads will this function get called from?
Sami 2014/10/03 10:39:21 Looks like m_pendingIdleTasks is the only bit of c
rmcilroy 2014/10/03 21:41:21 Right, mpendingIdleTasks is the only bit of cross-
212 Locker<Mutex> lock(m_pendingTasksMutex);
213 if (!m_pendingIdleTasks.isEmpty()) {
214 m_mainThread->postTask(new MainThreadPendingIdleTaskRunner());
215 return true;
216 }
217 }
218 return false;
199 } 219 }
200 220
201 void Scheduler::tickSharedTimer() 221 void Scheduler::tickSharedTimer()
202 { 222 {
203 TRACE_EVENT0("blink", "Scheduler::tickSharedTimer"); 223 TRACE_EVENT0("blink", "Scheduler::tickSharedTimer");
204 224
205 // Run any high priority tasks that are queued up, otherwise the blink timer s will yield immediately. 225 // Run any high priority tasks that are queued up, otherwise the blink timer s will yield immediately.
206 bool workDone = runPendingHighPriorityTasksIfInCompositorPriority(); 226 bool workDone = runPendingHighPriorityTasksIfInCompositorPriority();
207 m_sharedTimerFunction(); 227 m_sharedTimerFunction();
208 228
209 // The blink timers may have just yielded, so run any high priority tasks th at where queued up 229 // The blink timers may have just yielded, so run any high priority tasks th at where queued up
210 // while the blink timers were executing. 230 // while the blink timers were executing.
211 if (!workDone) 231 if (!workDone)
212 runPendingHighPriorityTasksIfInCompositorPriority(); 232 runPendingHighPriorityTasksIfInCompositorPriority();
213 } 233 }
214 234
215 bool Scheduler::runPendingHighPriorityTasksIfInCompositorPriority() 235 bool Scheduler::runPendingHighPriorityTasksIfInCompositorPriority()
216 { 236 {
217 ASSERT(isMainThread()); 237 ASSERT(isMainThread());
218 if (schedulerPolicy() != CompositorPriority) 238 if (schedulerPolicy() != CompositorPriority)
219 return false; 239 return false;
220 240
221 return swapQueuesAndRunPendingTasks(); 241 return swapQueuesAndRunPendingTasks();
222 } 242 }
223 243
244 bool Scheduler::runPendingIdleTaskIfCanRunIdleTask()
alexclarke 2014/10/03 09:59:19 nit: how about maybeRunPendingIdleTask?
rmcilroy 2014/10/03 21:41:21 Done.
245 {
246 ASSERT(isMainThread());
247 m_pendingTasksMutex.lock();
Sami 2014/10/03 10:39:21 Is there a way we could rewrite this to use a Lock
rmcilroy 2014/10/03 21:41:21 I originally tried to write this to use a locker,
248 if (canRunIdleTask() && !m_pendingIdleTasks.isEmpty()) {
alexclarke 2014/10/03 09:59:18 While personally I like it your way, I'm under the
rmcilroy 2014/10/03 21:41:21 Done.
249 TracedIdleTask task = m_pendingIdleTasks.takeFirst();
250 m_pendingTasksMutex.unlock();
251 task.run();
252 return true;
253 }
254 m_pendingTasksMutex.unlock();
255 return false;
256 }
257
224 bool Scheduler::swapQueuesAndRunPendingTasks() 258 bool Scheduler::swapQueuesAndRunPendingTasks()
225 { 259 {
226 ASSERT(isMainThread()); 260 ASSERT(isMainThread());
227 261
228 // These locks guard against another thread posting input or compositor task s while we swap the buffers. 262 // 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. 263 // One the buffers have been swapped we can safely access the returned deque without having to lock.
230 m_pendingTasksMutex.lock(); 264 m_pendingTasksMutex.lock();
231 Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffer s(); 265 Deque<TracedStandardTask>& highPriorityTasks = m_pendingHighPriorityTasks.sw apBuffers();
232 maybeEnterNormalSchedulerPolicy(); 266 maybeEnterNormalSchedulerPolicy();
233 m_pendingTasksMutex.unlock(); 267 m_pendingTasksMutex.unlock();
234 return executeHighPriorityTasks(highPriorityTasks); 268 return executeHighPriorityTasks(highPriorityTasks);
235 } 269 }
236 270
237 void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting() 271 void Scheduler::swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPosting()
238 { 272 {
239 ASSERT(isMainThread()); 273 ASSERT(isMainThread());
240 274
241 // These locks guard against another thread posting input or compositor task s while we swap the buffers. 275 // 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. 276 // One the buffers have been swapped we can safely access the returned deque without having to lock.
243 m_pendingTasksMutex.lock(); 277 m_pendingTasksMutex.lock();
244 Deque<TracedTask>& highPriorityTasks = m_pendingHighPriorityTasks.swapBuffer s(); 278 Deque<TracedStandardTask>& highPriorityTasks = m_pendingHighPriorityTasks.sw apBuffers();
245 m_highPriorityTaskRunnerPosted = false; 279 m_highPriorityTaskRunnerPosted = false;
246 maybeEnterNormalSchedulerPolicy(); 280 maybeEnterNormalSchedulerPolicy();
247 m_pendingTasksMutex.unlock(); 281 m_pendingTasksMutex.unlock();
248 executeHighPriorityTasks(highPriorityTasks); 282 executeHighPriorityTasks(highPriorityTasks);
249 } 283 }
250 284
251 void Scheduler::maybeEnterNormalSchedulerPolicy() 285 void Scheduler::maybeEnterNormalSchedulerPolicy()
252 { 286 {
253 ASSERT(isMainThread()); 287 ASSERT(isMainThread());
254 ASSERT(m_pendingTasksMutex.locked()); 288 ASSERT(m_pendingTasksMutex.locked());
255 289
256 // Go back to the normal scheduler policy if enough time has elapsed. 290 // Go back to the normal scheduler policy if enough time has elapsed.
257 if (schedulerPolicy() == CompositorPriority && Platform::current()->monotoni callyIncreasingTime() > m_compositorPriorityPolicyEndTimeSeconds) 291 if (schedulerPolicy() == CompositorPriority && Platform::current()->monotoni callyIncreasingTime() > m_compositorPriorityPolicyEndTimeSeconds)
258 enterSchedulerPolicyLocked(Normal); 292 enterSchedulerPolicyLocked(Normal);
259 } 293 }
260 294
261 bool Scheduler::executeHighPriorityTasks(Deque<TracedTask>& highPriorityTasks) 295 bool Scheduler::executeHighPriorityTasks(Deque<TracedStandardTask>& highPriority Tasks)
262 { 296 {
263 TRACE_EVENT0("blink", "Scheduler::executeHighPriorityTasks"); 297 TRACE_EVENT0("blink", "Scheduler::executeHighPriorityTasks");
264 int highPriorityTasksExecuted = 0; 298 int highPriorityTasksExecuted = 0;
265 while (!highPriorityTasks.isEmpty()) { 299 while (!highPriorityTasks.isEmpty()) {
266 highPriorityTasks.takeFirst().run(); 300 highPriorityTasks.takeFirst().run();
267 highPriorityTasksExecuted++; 301 highPriorityTasksExecuted++;
268 } 302 }
269 303
270 int highPriorityTaskCount = atomicSubtract(&m_highPriorityTaskCount, highPri orityTasksExecuted); 304 int highPriorityTaskCount = atomicSubtract(&m_highPriorityTaskCount, highPri orityTasksExecuted);
271 ASSERT_UNUSED(highPriorityTaskCount, highPriorityTaskCount >= 0); 305 ASSERT_UNUSED(highPriorityTaskCount, highPriorityTaskCount >= 0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 bool Scheduler::hasPendingHighPriorityWork() const 340 bool Scheduler::hasPendingHighPriorityWork() const
307 { 341 {
308 // This method is expected to be run on the main thread, but the high priori ty tasks will be posted by 342 // 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 343 // 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 344 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar rier loads here which
311 // should be cheaper. 345 // should be cheaper.
312 // NOTE it's possible the barrier read is overkill here, since delayed yield ing isn't a big deal. 346 // 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; 347 return acquireLoad(&m_highPriorityTaskCount) != 0;
314 } 348 }
315 349
350 double Scheduler::currentFrameDeadlineSeconds() const
351 {
352 // TODO: Make idle time more fine-grain chunks when in Compositor priority.
353 return m_currentFrameDeadlineSeconds;
Sami 2014/10/03 10:39:21 ASSERT(isMainThread());
rmcilroy 2014/10/03 21:41:21 Done.
354 }
355
356 bool Scheduler::canRunIdleTask() const
357 {
358 return m_currentFrameCommitted && (m_currentFrameDeadlineSeconds > Platform: :current()->monotonicallyIncreasingTime());
Sami 2014/10/03 10:39:21 ASSERT(isMainThread());
rmcilroy 2014/10/03 21:41:21 Done.
359 }
360
316 Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const 361 Scheduler::SchedulerPolicy Scheduler::schedulerPolicy() const
317 { 362 {
318 ASSERT(isMainThread()); 363 ASSERT(isMainThread());
319 // It's important not to miss the transition from normal to low latency mode , otherwise we're likely to 364 // 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 365 // 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. 366 // need either a lock or a memory barrier, and the memory barrier is probabl y cheaper.
322 return static_cast<SchedulerPolicy>(acquireLoad(&m_schedulerPolicy)); 367 return static_cast<SchedulerPolicy>(acquireLoad(&m_schedulerPolicy));
323 } 368 }
324 369
325 void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy) 370 void Scheduler::enterSchedulerPolicy(SchedulerPolicy schedulerPolicy)
326 { 371 {
327 Locker<Mutex> lock(m_pendingTasksMutex); 372 Locker<Mutex> lock(m_pendingTasksMutex);
328 enterSchedulerPolicyLocked(schedulerPolicy); 373 enterSchedulerPolicyLocked(schedulerPolicy);
329 } 374 }
330 375
331 void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy) 376 void Scheduler::enterSchedulerPolicyLocked(SchedulerPolicy schedulerPolicy)
332 { 377 {
333 ASSERT(m_pendingTasksMutex.locked()); 378 ASSERT(m_pendingTasksMutex.locked());
334 if (schedulerPolicy == CompositorPriority) 379 if (schedulerPolicy == CompositorPriority)
335 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; 380 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds;
336 381
337 releaseStore(&m_schedulerPolicy, schedulerPolicy); 382 releaseStore(&m_schedulerPolicy, schedulerPolicy);
338 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy); 383 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy);
339 } 384 }
340 385
341 } // namespace blink 386 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698