Chromium Code Reviews| 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); |
|
Sami
2014/10/10 17:31:31
I'm trying to decide whether we should only do thi
rmcilroy
2014/10/13 11:41:19
I don't think it would make much of a difference e
| |
| 277 return m_pendingIdleTasks.takeFirst(); | 277 if (m_incomingIdleTasks.isEmpty()) |
| 278 return; | |
| 279 | |
|
picksi1
2014/10/13 09:38:09
Is it worth doing this empty check here? The follo
rmcilroy
2014/10/13 11:41:19
Makes sense, dropped it.
| |
| 280 while (!m_incomingIdleTasks.isEmpty()) { | |
|
jochen (gone - plz use gerrit)
2014/10/13 08:09:11
nit. no { }
what happens if the idle task immedia
rmcilroy
2014/10/13 11:41:19
If the idle task immediately posts a new task it w
| |
| 281 m_pendingIdleTasks.append(m_incomingIdleTasks.takeFirst()); | |
| 282 } | |
|
picksi1
2014/10/13 09:38:09
Is there no quick way to append the entire queue h
rmcilroy
2014/10/13 11:41:19
I couldn't find any faster append in Deque - let m
| |
| 278 } | 283 } |
| 279 | 284 |
| 280 double Scheduler::currentFrameDeadlineForIdleTasks() const | 285 double Scheduler::currentFrameDeadlineForIdleTasks() const |
| 281 { | 286 { |
| 282 ASSERT(isMainThread()); | 287 ASSERT(isMainThread()); |
| 283 // TODO: Make idle time more fine-grain chunks when in Compositor priority. | 288 // TODO: Make idle time more fine-grain chunks when in Compositor priority. |
| 284 return m_estimatedNextBeginFrameSeconds; | 289 return m_estimatedNextBeginFrameSeconds; |
| 285 } | 290 } |
| 286 | 291 |
| 287 bool Scheduler::canRunIdleTask() const | 292 bool Scheduler::canRunIdleTask() const |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 311 { | 316 { |
| 312 ASSERT(m_policyStateMutex.locked()); | 317 ASSERT(m_policyStateMutex.locked()); |
| 313 if (schedulerPolicy == CompositorPriority) | 318 if (schedulerPolicy == CompositorPriority) |
| 314 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; | 319 m_compositorPriorityPolicyEndTimeSeconds = Platform::current()->monotoni callyIncreasingTime() + kLowSchedulerPolicyAfterTouchTimeSeconds; |
| 315 | 320 |
| 316 releaseStore(&m_schedulerPolicy, schedulerPolicy); | 321 releaseStore(&m_schedulerPolicy, schedulerPolicy); |
| 317 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy); | 322 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.scheduler"), "SchedulerPolic y", schedulerPolicy); |
| 318 } | 323 } |
| 319 | 324 |
| 320 } // namespace blink | 325 } // namespace blink |
| OLD | NEW |