OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/thread_interrupter.h" | 5 #include "vm/thread_interrupter.h" |
6 | 6 |
7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
8 #include "vm/lockers.h" | 8 #include "vm/lockers.h" |
9 #include "vm/os.h" | 9 #include "vm/os.h" |
10 #include "vm/simulator.h" | 10 #include "vm/simulator.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 MonitorLocker ml(monitor_); | 141 MonitorLocker ml(monitor_); |
142 if (!InDeepSleep()) { | 142 if (!InDeepSleep()) { |
143 // No need to notify, regularly waking up. | 143 // No need to notify, regularly waking up. |
144 return; | 144 return; |
145 } | 145 } |
146 // Notify the interrupter to wake it from its deep sleep. | 146 // Notify the interrupter to wake it from its deep sleep. |
147 ml.Notify(); | 147 ml.Notify(); |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 // Register the currently running thread for interrupts. If the current thread | |
152 // is already registered, callback and data will be updated. | |
153 InterruptableThreadState* ThreadInterrupter::Register( | |
154 ThreadInterruptCallback callback, void* data) { | |
155 if (shutdown_) { | |
156 return NULL; | |
157 } | |
158 ASSERT(initialized_); | |
159 InterruptableThreadState* state = _EnsureThreadStateCreated(); | |
160 // Set callback and data. | |
161 UpdateStateObject(callback, data); | |
162 return state; | |
163 } | |
164 | |
165 | |
166 // Unregister the currently running thread for interrupts. | |
167 void ThreadInterrupter::Unregister() { | |
168 if (shutdown_) { | |
169 return; | |
170 } | |
171 ASSERT(initialized_); | |
172 _EnsureThreadStateCreated(); | |
173 // Clear callback and data. | |
174 UpdateStateObject(NULL, NULL); | |
175 } | |
176 | |
177 | |
178 InterruptableThreadState* ThreadInterrupter::_EnsureThreadStateCreated() { | |
179 InterruptableThreadState* state = CurrentThreadState(); | |
180 if (state == NULL) { | |
181 // Create thread state object lazily. | |
182 ThreadId current_thread = OSThread::GetCurrentThreadId(); | |
183 if (FLAG_trace_thread_interrupter) { | |
184 intptr_t tid = OSThread::ThreadIdToIntPtr(current_thread); | |
185 OS::Print("ThreadInterrupter Tracking %p\n", | |
186 reinterpret_cast<void*>(tid)); | |
187 } | |
188 // Note: We currently do not free a thread's InterruptableThreadState. | |
189 state = new InterruptableThreadState(); | |
190 ASSERT(state != NULL); | |
191 state->callback = NULL; | |
192 state->data = NULL; | |
193 state->id = current_thread; | |
194 SetCurrentThreadState(state); | |
195 } | |
196 return state; | |
197 } | |
198 | |
199 | |
200 void ThreadInterrupter::UpdateStateObject(ThreadInterruptCallback callback, | |
201 void* data) { | |
202 InterruptableThreadState* state = CurrentThreadState(); | |
203 ThreadId current_thread = OSThread::GetCurrentThreadId(); | |
204 ASSERT(state != NULL); | |
205 ASSERT(OSThread::Compare(state->id, OSThread::GetCurrentThreadId())); | |
206 SetCurrentThreadState(NULL); | |
207 // It is now safe to modify the state object. If an interrupt occurs, | |
208 // the current thread state will be NULL. | |
209 state->callback = callback; | |
210 state->data = data; | |
211 SetCurrentThreadState(state); | |
212 if (FLAG_trace_thread_interrupter) { | |
213 intptr_t tid = OSThread::ThreadIdToIntPtr(current_thread); | |
214 if (callback == NULL) { | |
215 OS::Print("ThreadInterrupter Cleared %p\n", reinterpret_cast<void*>(tid)); | |
216 } else { | |
217 OS::Print("ThreadInterrupter Updated %p\n", reinterpret_cast<void*>(tid)); | |
218 } | |
219 } | |
220 } | |
221 | |
222 | |
223 InterruptableThreadState* ThreadInterrupter::GetCurrentThreadState() { | |
224 return _EnsureThreadStateCreated(); | |
225 } | |
226 | |
227 | |
228 InterruptableThreadState* ThreadInterrupter::CurrentThreadState() { | |
229 Thread* thread = Thread::Current(); | |
230 return (thread == NULL) ? NULL : thread->thread_state(); | |
231 } | |
232 | |
233 | |
234 void ThreadInterrupter::SetCurrentThreadState(InterruptableThreadState* state) { | |
235 Thread::Current()->set_thread_state(state); | |
236 } | |
237 | |
238 | 151 |
239 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) { | 152 void ThreadInterruptNoOp(const InterruptedThreadState& state, void* data) { |
240 // NoOp. | 153 // NoOp. |
241 } | 154 } |
242 | 155 |
243 | 156 |
244 class ThreadInterrupterVisitIsolates : public IsolateVisitor { | 157 class ThreadInterrupterVisitIsolates : public IsolateVisitor { |
245 public: | 158 public: |
246 ThreadInterrupterVisitIsolates() { | 159 ThreadInterrupterVisitIsolates() { |
247 profiled_thread_count_ = 0; | 160 profiled_thread_count_ = 0; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 } | 226 } |
314 { | 227 { |
315 // Signal to main thread we are exiting. | 228 // Signal to main thread we are exiting. |
316 MonitorLocker shutdown_ml(monitor_); | 229 MonitorLocker shutdown_ml(monitor_); |
317 thread_running_ = false; | 230 thread_running_ = false; |
318 shutdown_ml.Notify(); | 231 shutdown_ml.Notify(); |
319 } | 232 } |
320 } | 233 } |
321 | 234 |
322 } // namespace dart | 235 } // namespace dart |
OLD | NEW |