| 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 |