OLD | NEW |
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/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
10 #include "platform/Task.h" | 10 #include "platform/Task.h" |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 ASSERT(isMainThread()); | 132 ASSERT(isMainThread()); |
133 m_currentFrameCommitted = false; | 133 m_currentFrameCommitted = false; |
134 m_estimatedNextBeginFrameSeconds = estimatedNextBeginFrameSeconds; | 134 m_estimatedNextBeginFrameSeconds = estimatedNextBeginFrameSeconds; |
135 // TODO: Schedule a deferred task here to run idle work if didCommitFrameToC
ompositor never gets called. | 135 // TODO: Schedule a deferred task here to run idle work if didCommitFrameToC
ompositor never gets called. |
136 } | 136 } |
137 | 137 |
138 void Scheduler::didCommitFrameToCompositor() | 138 void Scheduler::didCommitFrameToCompositor() |
139 { | 139 { |
140 ASSERT(isMainThread()); | 140 ASSERT(isMainThread()); |
141 m_currentFrameCommitted = true; | 141 m_currentFrameCommitted = true; |
| 142 flushIncomingIdleTasks(); |
142 maybePostMainThreadPendingIdleTask(); | 143 maybePostMainThreadPendingIdleTask(); |
143 } | 144 } |
144 | 145 |
145 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons
t Task& task, const char* traceName) | 146 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons
t Task& task, const char* traceName) |
146 { | 147 { |
147 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner(task, loc
ation, traceName)); | 148 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner(task, loc
ation, traceName)); |
148 atomicIncrement(&m_highPriorityTaskCount); | 149 atomicIncrement(&m_highPriorityTaskCount); |
149 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri
orityTasks", m_highPriorityTaskCount); | 150 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri
orityTasks", m_highPriorityTaskCount); |
150 } | 151 } |
151 | 152 |
152 void Scheduler::didRunHighPriorityTask() | 153 void Scheduler::didRunHighPriorityTask() |
153 { | 154 { |
154 atomicDecrement(&m_highPriorityTaskCount); | 155 atomicDecrement(&m_highPriorityTaskCount); |
155 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri
orityTasks", m_highPriorityTaskCount); | 156 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "PendingHighPri
orityTasks", m_highPriorityTaskCount); |
156 } | 157 } |
157 | 158 |
158 void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTa
sk& idleTask, const char* traceName) | 159 void Scheduler::postIdleTaskInternal(const TraceLocation& location, const IdleTa
sk& idleTask, const char* traceName) |
159 { | 160 { |
160 Locker<Mutex> lock(m_pendingIdleTasksMutex); | 161 Locker<Mutex> lock(m_incomingIdleTasksMutex); |
161 m_pendingIdleTasks.append(internal::TracedIdleTask::Create(idleTask, locatio
n, traceName)); | 162 m_incomingIdleTasks.append(internal::TracedIdleTask::Create(idleTask, locati
on, traceName)); |
162 } | 163 } |
163 | 164 |
164 void Scheduler::postTask(const TraceLocation& location, const Task& task) | 165 void Scheduler::postTask(const TraceLocation& location, const Task& task) |
165 { | 166 { |
166 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche
duler::MainThreadTask")); | 167 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche
duler::MainThreadTask")); |
167 } | 168 } |
168 | 169 |
169 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) | 170 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) |
170 { | 171 { |
171 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask"); | 172 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask"); |
(...skipping 21 matching lines...) Expand all Loading... |
193 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle
Task) | 194 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle
Task) |
194 { | 195 { |
195 postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask"); | 196 postIdleTaskInternal(location, idleTask, "Scheduler::IdleTask"); |
196 } | 197 } |
197 | 198 |
198 bool Scheduler::maybePostMainThreadPendingIdleTask() | 199 bool Scheduler::maybePostMainThreadPendingIdleTask() |
199 { | 200 { |
200 ASSERT(isMainThread()); | 201 ASSERT(isMainThread()); |
201 TRACE_EVENT0("blink", "Scheduler::maybePostMainThreadPendingIdleTask"); | 202 TRACE_EVENT0("blink", "Scheduler::maybePostMainThreadPendingIdleTask"); |
202 if (canRunIdleTask()) { | 203 if (canRunIdleTask()) { |
203 Locker<Mutex> lock(m_pendingIdleTasksMutex); | |
204 if (!m_pendingIdleTasks.isEmpty()) { | 204 if (!m_pendingIdleTasks.isEmpty()) { |
205 m_mainThread->postTask(new MainThreadPendingIdleTaskRunner()); | 205 m_mainThread->postTask(new MainThreadPendingIdleTaskRunner()); |
206 return true; | 206 return true; |
207 } | 207 } |
208 } | 208 } |
209 return false; | 209 return false; |
210 } | 210 } |
211 | 211 |
212 void Scheduler::tickSharedTimer() | 212 void Scheduler::tickSharedTimer() |
213 { | 213 { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // other threads. We could use locks here, but this function is (sometimes)
called a lot by | 256 // other threads. We could use locks here, but this function is (sometimes)
called a lot by |
257 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar
rier loads here which | 257 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar
rier loads here which |
258 // should be cheaper. | 258 // should be cheaper. |
259 // NOTE it's possible the barrier read is overkill here, since delayed yield
ing isn't a big deal. | 259 // NOTE it's possible the barrier read is overkill here, since delayed yield
ing isn't a big deal. |
260 return acquireLoad(&m_highPriorityTaskCount) != 0; | 260 return acquireLoad(&m_highPriorityTaskCount) != 0; |
261 } | 261 } |
262 | 262 |
263 bool Scheduler::maybeRunPendingIdleTask() | 263 bool Scheduler::maybeRunPendingIdleTask() |
264 { | 264 { |
265 ASSERT(isMainThread()); | 265 ASSERT(isMainThread()); |
266 if (!canRunIdleTask()) | 266 if (!canRunIdleTask() || m_pendingIdleTasks.isEmpty()) |
267 return false; | 267 return false; |
268 | 268 |
269 takeFirstPendingIdleTask()->run(); | 269 m_pendingIdleTasks.takeFirst()->run(); |
270 return true; | 270 return true; |
271 } | 271 } |
272 | 272 |
273 PassOwnPtr<internal::TracedIdleTask> Scheduler::takeFirstPendingIdleTask() | 273 void Scheduler::flushIncomingIdleTasks() |
274 { | 274 { |
275 Locker<Mutex> lock(m_pendingIdleTasksMutex); | 275 ASSERT(isMainThread()); |
276 ASSERT(!m_pendingIdleTasks.isEmpty()); | 276 Locker<Mutex> lock(m_incomingIdleTasksMutex); |
277 return m_pendingIdleTasks.takeFirst(); | 277 while (!m_incomingIdleTasks.isEmpty()) |
| 278 m_pendingIdleTasks.append(m_incomingIdleTasks.takeFirst()); |
278 } | 279 } |
279 | 280 |
280 double Scheduler::currentFrameDeadlineForIdleTasks() const | 281 double Scheduler::currentFrameDeadlineForIdleTasks() const |
281 { | 282 { |
282 ASSERT(isMainThread()); | 283 ASSERT(isMainThread()); |
283 // TODO: Make idle time more fine-grain chunks when in Compositor priority. | 284 // TODO: Make idle time more fine-grain chunks when in Compositor priority. |
284 return m_estimatedNextBeginFrameSeconds; | 285 return m_estimatedNextBeginFrameSeconds; |
285 } | 286 } |
286 | 287 |
287 bool Scheduler::canRunIdleTask() const | 288 bool Scheduler::canRunIdleTask() const |
(...skipping 23 matching lines...) Expand all Loading... |
311 { | 312 { |
312 ASSERT(m_policyStateMutex.locked()); | 313 ASSERT(m_policyStateMutex.locked()); |
313 if (schedulerPolicy == CompositorPriority) | 314 if (schedulerPolicy == CompositorPriority) |
314 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni
callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; | 315 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni
callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; |
315 | 316 |
316 releaseStore(&m_schedulerPolicy, schedulerPolicy); | 317 releaseStore(&m_schedulerPolicy, schedulerPolicy); |
317 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic
y", schedulerPolicy); | 318 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic
y", schedulerPolicy); |
318 } | 319 } |
319 | 320 |
320 } // namespace blink | 321 } // namespace blink |
OLD | NEW |