| 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/Task.h" | 9 #include "platform/Task.h" |
| 10 #include "platform/ThreadTimers.h" | 10 #include "platform/ThreadTimers.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 scheduler->swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPostin
g(); | 66 scheduler->swapQueuesRunPendingTasksAndAllowHighPriorityTaskRunnerPostin
g(); |
| 67 } | 67 } |
| 68 }; | 68 }; |
| 69 | 69 |
| 70 | 70 |
| 71 // Can be created from any thread. | 71 // Can be created from any thread. |
| 72 // Note if the scheduler gets shutdown, this may be run after. | 72 // Note if the scheduler gets shutdown, this may be run after. |
| 73 class Scheduler::MainThreadPendingTaskRunner : public WebThread::Task { | 73 class Scheduler::MainThreadPendingTaskRunner : public WebThread::Task { |
| 74 public: | 74 public: |
| 75 MainThreadPendingTaskRunner( | 75 MainThreadPendingTaskRunner( |
| 76 const Scheduler::Task& task, const TraceLocation& location) | 76 const Scheduler::Task& task, const TraceLocation& location, const char*
traceName) |
| 77 : m_task(task, location) | 77 : m_task(task, location, traceName) |
| 78 { | 78 { |
| 79 ASSERT(Scheduler::shared()); | 79 ASSERT(Scheduler::shared()); |
| 80 } | 80 } |
| 81 | 81 |
| 82 // WebThread::Task implementation. | 82 // WebThread::Task implementation. |
| 83 virtual void run() OVERRIDE | 83 virtual void run() OVERRIDE |
| 84 { | 84 { |
| 85 Scheduler* scheduler = Scheduler::shared(); | 85 Scheduler* scheduler = Scheduler::shared(); |
| 86 // FIXME: This check should't be necessary, tasks should not outlive bli
nk. | 86 // FIXME: This check should't be necessary, tasks should not outlive bli
nk. |
| 87 ASSERT(scheduler); | 87 ASSERT(scheduler); |
| 88 if (scheduler) | 88 if (scheduler) |
| 89 Scheduler::shared()->swapQueuesAndRunPendingTasks(); | 89 Scheduler::shared()->swapQueuesAndRunPendingTasks(); |
| 90 m_task.run(); | 90 m_task.run(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 Scheduler::TracedTask m_task; | 93 TracedTask m_task; |
| 94 }; | 94 }; |
| 95 | 95 |
| 96 Scheduler* Scheduler::s_sharedScheduler = nullptr; | 96 Scheduler* Scheduler::s_sharedScheduler = nullptr; |
| 97 | 97 |
| 98 void Scheduler::initializeOnMainThread() | 98 void Scheduler::initializeOnMainThread() |
| 99 { | 99 { |
| 100 s_sharedScheduler = new Scheduler(); | 100 s_sharedScheduler = new Scheduler(); |
| 101 } | 101 } |
| 102 | 102 |
| 103 void Scheduler::shutdown() | 103 void Scheduler::shutdown() |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 { | 135 { |
| 136 // TODO: Trigger the frame deadline immediately. | 136 // TODO: Trigger the frame deadline immediately. |
| 137 } | 137 } |
| 138 | 138 |
| 139 void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask&
idleTask) | 139 void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask&
idleTask) |
| 140 { | 140 { |
| 141 // TODO: send a real allottedTime here. | 141 // TODO: send a real allottedTime here. |
| 142 m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location))
; | 142 m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location))
; |
| 143 } | 143 } |
| 144 | 144 |
| 145 void Scheduler::postHighPriorityTaskInternal(const TraceLocation& location, cons
t Task& task, const char* traceName) |
| 146 { |
| 147 Locker<Mutex> lock(m_pendingTasksMutex); |
| 148 |
| 149 m_pendingHighPriorityTasks.append(TracedTask(task, location, traceName)); |
| 150 atomicIncrement(&m_highPriorityTaskCount); |
| 151 maybePostMainThreadPendingHighPriorityTaskRunner(); |
| 152 } |
| 153 |
| 145 void Scheduler::postTask(const TraceLocation& location, const Task& task) | 154 void Scheduler::postTask(const TraceLocation& location, const Task& task) |
| 146 { | 155 { |
| 147 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location)); | 156 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location, "Sche
duler::MainThreadTask")); |
| 148 } | 157 } |
| 149 | 158 |
| 150 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) | 159 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) |
| 151 { | 160 { |
| 152 Locker<Mutex> lock(m_pendingTasksMutex); | 161 postHighPriorityTaskInternal(location, task, "Scheduler::InputTask"); |
| 153 m_pendingHighPriorityTasks.append(TracedTask(task, location)); | |
| 154 atomicIncrement(&m_highPriorityTaskCount); | |
| 155 maybePostMainThreadPendingHighPriorityTaskRunner(); | |
| 156 } | 162 } |
| 157 | 163 |
| 158 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta
sk) | 164 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta
sk) |
| 159 { | 165 { |
| 160 Locker<Mutex> lock(m_pendingTasksMutex); | 166 postHighPriorityTaskInternal(location, task, "Scheduler::CompositorTask"); |
| 161 m_pendingHighPriorityTasks.append(TracedTask(task, location)); | |
| 162 atomicIncrement(&m_highPriorityTaskCount); | |
| 163 maybePostMainThreadPendingHighPriorityTaskRunner(); | |
| 164 } | 167 } |
| 165 | 168 |
| 166 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner() | 169 void Scheduler::maybePostMainThreadPendingHighPriorityTaskRunner() |
| 167 { | 170 { |
| 168 ASSERT(m_pendingTasksMutex.locked()); | 171 ASSERT(m_pendingTasksMutex.locked()); |
| 169 if (m_highPriorityTaskRunnerPosted) | 172 if (m_highPriorityTaskRunnerPosted) |
| 170 return; | 173 return; |
| 171 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); | 174 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); |
| 172 m_highPriorityTaskRunnerPosted = true; | 175 m_highPriorityTaskRunnerPosted = true; |
| 173 } | 176 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 bool Scheduler::hasPendingHighPriorityWork() const | 262 bool Scheduler::hasPendingHighPriorityWork() const |
| 260 { | 263 { |
| 261 // This method is expected to be run on the main thread, but the high priori
ty tasks will be posted by | 264 // This method is expected to be run on the main thread, but the high priori
ty tasks will be posted by |
| 262 // other threads. We could use locks here, but this function is (sometimes)
called a lot by | 265 // other threads. We could use locks here, but this function is (sometimes)
called a lot by |
| 263 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar
rier loads here which | 266 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar
rier loads here which |
| 264 // should be cheaper. | 267 // should be cheaper. |
| 265 // NOTE it's possible the barrier read is overkill here, since delayed yield
ing isn't a big deal. | 268 // NOTE it's possible the barrier read is overkill here, since delayed yield
ing isn't a big deal. |
| 266 return acquireLoad(&m_highPriorityTaskCount) != 0; | 269 return acquireLoad(&m_highPriorityTaskCount) != 0; |
| 267 } | 270 } |
| 268 | 271 |
| 269 void Scheduler::TracedTask::run() | |
| 270 { | |
| 271 TRACE_EVENT2("blink", "TracedTask::run", | |
| 272 "src_file", m_location.fileName(), | |
| 273 "src_func", m_location.functionName()); | |
| 274 m_task(); | |
| 275 } | |
| 276 | |
| 277 } // namespace blink | 272 } // namespace blink |
| OLD | NEW |