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 |