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/Task.h" | 9 #include "platform/Task.h" |
| 10 #include "platform/ThreadTimers.h" | 10 #include "platform/ThreadTimers.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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) |
| 77 : m_task(task, location) | 77 : m_task(task, location, TracedTask::Type::MainThread) |
| 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()->runHighPriorityTasks(); | 89 Scheduler::shared()->runHighPriorityTasks(); |
| 90 m_task.run(); | 90 m_task.run(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 Scheduler::TracedTask m_task; | 93 Scheduler::TracedTask m_task; |
| 94 }; | 94 }; |
| 95 | 95 |
| 96 | |
|
Sami
2014/08/20 14:20:57
nit: extra whitespace
picksi1
2014/08/29 14:11:28
Done.
| |
| 96 Scheduler* Scheduler::s_sharedScheduler = nullptr; | 97 Scheduler* Scheduler::s_sharedScheduler = nullptr; |
| 97 | 98 |
| 98 void Scheduler::initializeOnMainThread() | 99 void Scheduler::initializeOnMainThread() |
| 99 { | 100 { |
| 100 s_sharedScheduler = new Scheduler(); | 101 s_sharedScheduler = new Scheduler(); |
| 101 } | 102 } |
| 102 | 103 |
| 103 void Scheduler::shutdown() | 104 void Scheduler::shutdown() |
| 104 { | 105 { |
| 105 delete s_sharedScheduler; | 106 delete s_sharedScheduler; |
| 106 s_sharedScheduler = nullptr; | 107 s_sharedScheduler = nullptr; |
| 107 } | 108 } |
| 108 | 109 |
| 109 Scheduler* Scheduler::shared() | 110 Scheduler* Scheduler::shared() |
| 110 { | 111 { |
| 111 return s_sharedScheduler; | 112 return s_sharedScheduler; |
| 112 } | 113 } |
| 113 | 114 |
| 114 Scheduler::Scheduler() | 115 Scheduler::Scheduler() |
| 115 : m_sharedTimerFunction(nullptr) | 116 : m_sharedTimerFunction(nullptr) |
| 116 , m_mainThread(blink::Platform::current()->currentThread()) | 117 , m_mainThread(blink::Platform::current()->currentThread()) |
| 117 , m_highPriorityTaskCount(0) | 118 , m_highPriorityTaskCount(0) |
| 118 { | 119 { |
| 120 // Set up static array with names used for tracing. Set up dynamically | |
| 121 // to avoid the need to ensure enums and strings remain in sync. | |
| 122 TracedTask::setTypeName(TracedTask::Type::Compositor, "Scheduler::Compositor Task"); | |
| 123 TracedTask::setTypeName(TracedTask::Type::Input, "Scheduler::InputTask"); | |
| 124 TracedTask::setTypeName(TracedTask::Type::MainThread, "Scheduler::MainThread Task"); | |
| 119 } | 125 } |
| 120 | 126 |
| 121 Scheduler::~Scheduler() | 127 Scheduler::~Scheduler() |
| 122 { | 128 { |
| 123 while (hasPendingHighPriorityWork()) { | 129 while (hasPendingHighPriorityWork()) { |
| 124 runHighPriorityTasks(); | 130 runHighPriorityTasks(); |
| 125 } | 131 } |
| 126 } | 132 } |
| 127 | 133 |
| 128 void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask& idleTask) | 134 void Scheduler::scheduleIdleTask(const TraceLocation& location, const IdleTask& idleTask) |
| 129 { | 135 { |
| 130 // TODO: send a real allottedTime here. | 136 // TODO: send a real allottedTime here. |
| 131 m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location)) ; | 137 m_mainThread->postTask(new MainThreadIdleTaskAdapter(idleTask, 0, location)) ; |
| 132 } | 138 } |
| 133 | 139 |
| 134 void Scheduler::postTask(const TraceLocation& location, const Task& task) | 140 void Scheduler::postTask(const TraceLocation& location, const Task& task) |
| 135 { | 141 { |
| 136 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location)); | 142 m_mainThread->postTask(new MainThreadPendingTaskRunner(task, location)); |
| 137 } | 143 } |
| 138 | 144 |
| 139 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) | 145 void Scheduler::postInputTask(const TraceLocation& location, const Task& task) |
| 140 { | 146 { |
| 141 Locker<Mutex> lock(m_pendingTasksMutex); | 147 Locker<Mutex> lock(m_pendingTasksMutex); |
| 142 m_pendingInputTasks.append(TracedTask(task, location)); | 148 TracedTask tracedTask = TracedTask(task, location, TracedTask::Type::Input); |
| 149 m_pendingInputTasks.append(tracedTask); | |
| 143 atomicIncrement(&m_highPriorityTaskCount); | 150 atomicIncrement(&m_highPriorityTaskCount); |
| 144 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); | 151 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); |
| 145 } | 152 } |
| 146 | 153 |
| 147 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk) | 154 void Scheduler::postCompositorTask(const TraceLocation& location, const Task& ta sk) |
| 148 { | 155 { |
| 149 Locker<Mutex> lock(m_pendingTasksMutex); | 156 Locker<Mutex> lock(m_pendingTasksMutex); |
| 150 m_pendingCompositorTasks.append(TracedTask(task, location)); | 157 TracedTask tracedTask = TracedTask(task, location, TracedTask::Type::Composi tor); |
| 158 m_pendingCompositorTasks.append(tracedTask); | |
| 151 atomicIncrement(&m_highPriorityTaskCount); | 159 atomicIncrement(&m_highPriorityTaskCount); |
| 152 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); | 160 m_mainThread->postTask(new MainThreadPendingHighPriorityTaskRunner()); |
| 153 } | 161 } |
| 154 | 162 |
| 155 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task) | 163 void Scheduler::postIdleTask(const TraceLocation& location, const IdleTask& idle Task) |
| 156 { | 164 { |
| 157 scheduleIdleTask(location, idleTask); | 165 scheduleIdleTask(location, idleTask); |
| 158 } | 166 } |
| 159 | 167 |
| 160 void Scheduler::tickSharedTimer() | 168 void Scheduler::tickSharedTimer() |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 226 bool Scheduler::hasPendingHighPriorityWork() const | 234 bool Scheduler::hasPendingHighPriorityWork() const |
| 227 { | 235 { |
| 228 // This method is expected to be run on the main thread, but the high priori ty tasks will be posted by | 236 // This method is expected to be run on the main thread, but the high priori ty tasks will be posted by |
| 229 // other threads. We could use locks here, but this function is (sometimes) called a lot by | 237 // other threads. We could use locks here, but this function is (sometimes) called a lot by |
| 230 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar rier loads here which | 238 // ThreadTimers::sharedTimerFiredInternal so we decided to use atomics + bar rier loads here which |
| 231 // should be cheaper. | 239 // should be cheaper. |
| 232 // NOTE it's possible the barrier read is overkill here, since delayed yield ing isn't a big deal. | 240 // NOTE it's possible the barrier read is overkill here, since delayed yield ing isn't a big deal. |
| 233 return acquireLoad(&m_highPriorityTaskCount) != 0; | 241 return acquireLoad(&m_highPriorityTaskCount) != 0; |
| 234 } | 242 } |
| 235 | 243 |
| 244 FlowTraceID Scheduler::TracedTask::s_NextFlowTraceID = 0; | |
| 245 char const * Scheduler::TracedTask::s_typeNames[TracedTask::Type::TypeCount]; | |
| 246 | |
| 236 void Scheduler::TracedTask::run() | 247 void Scheduler::TracedTask::run() |
| 237 { | 248 { |
| 238 TRACE_EVENT2("blink", "TracedTask::run", | 249 TRACE_EVENT_FLOW_END2("blink", s_typeNames[m_type], TRACE_ID_MANGLE(m_FlowT raceID), |
| 239 "src_file", m_location.fileName(), | 250 "src_file", m_location.fileName(), |
|
Sami
2014/08/20 14:20:57
No need to report the same src_file and src_func h
picksi1
2014/08/29 14:11:28
file and func removed, will add queue duration as
| |
| 240 "src_func", m_location.functionName()); | 251 "src_func", m_location.functionName()); |
| 252 | |
| 253 TRACE_EVENT2("blink", s_typeNames[m_type], | |
| 254 "src_file", m_location.fileName(), | |
| 255 "src_func", m_location.functionName()); | |
| 256 | |
| 241 m_task(); | 257 m_task(); |
| 242 } | 258 } |
| 243 | 259 |
| 260 void Scheduler::TracedTask::setTypeName(TracedTask::Type type, char const * name ) | |
| 261 { | |
| 262 ASSERT((type >= 0) && (type < TracedTask::Type::TypeCount)); | |
| 263 s_typeNames[type] = name; | |
| 264 } | |
| 265 | |
| 266 Scheduler::TracedTask::TracedTask(const Task& task, const TraceLocation& locatio n, TracedTask::Type type) | |
| 267 : m_FlowTraceID(s_NextFlowTraceID++) | |
|
Sami
2014/08/20 14:20:57
Unfortunately TracedTasks can get constructed on a
picksi1
2014/08/29 14:11:28
Done.
| |
| 268 , m_task(task) | |
| 269 , m_location(location) | |
| 270 , m_type(type) | |
| 271 { | |
| 272 TRACE_EVENT_FLOW_BEGIN2("blink", s_typeNames[type], TRACE_ID_MANGLE(m_FlowTr aceID), | |
| 273 "src_file", m_location.fileName(), | |
| 274 "src_func", m_location.functionName()); | |
| 275 } | |
| 276 | |
| 277 | |
| 244 } // namespace blink | 278 } // namespace blink |
| OLD | NEW |