Index: runtime/vm/lockers.cc |
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc |
index 839d40ccdb43d03bd1393e715dc725be89176923..ba70bca9bb2cd8738c14b59707495b3887c13ad2 100644 |
--- a/runtime/vm/lockers.cc |
+++ b/runtime/vm/lockers.cc |
@@ -59,4 +59,55 @@ SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) { |
} |
} |
+ |
+SafepointMonitorLocker::SafepointMonitorLocker(Monitor* monitor) |
+ : monitor_(monitor) { |
+ ASSERT(monitor_ != NULL); |
+ if (!monitor_->TryEnter()) { |
+ // We did not get the lock and could potentially block, so transition |
+ // accordingly. |
+ Thread* thread = Thread::Current(); |
+ thread->set_execution_state(Thread::kThreadInBlockedState); |
+ thread->EnterSafepoint(); |
+ monitor_->Enter(); |
+ // First try a fast update of the thread state to indicate it is not at a |
+ // safepoint anymore. |
+ uword old_state = Thread::SetAtSafepoint(true, 0); |
+ uword addr = |
+ reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset(); |
+ if (AtomicOperations::CompareAndSwapWord( |
+ reinterpret_cast<uword*>(addr), old_state, 0) != old_state) { |
+ // Fast update failed which means we could potentially be in the middle |
+ // of a safepoint operation and need to block for it. |
+ SafepointHandler* handler = thread->isolate()->safepoint_handler(); |
Cutch
2016/03/01 15:08:07
This 'fast update of the thread state' code is the
siva
2016/03/01 18:59:53
Done.
|
+ handler->ExitSafepointUsingLock(thread); |
+ } |
+ thread->set_execution_state(Thread::kThreadInVM); |
+ } |
+} |
+ |
+ |
+Monitor::WaitResult SafepointMonitorLocker::Wait(int64_t millis) { |
+ Thread* thread = Thread::Current(); |
+ thread->set_execution_state(Thread::kThreadInBlockedState); |
+ thread->EnterSafepoint(); |
+ Monitor::WaitResult result = monitor_->Wait(millis); |
+ // First try a fast update of the thread state to indicate it is not at a |
+ // safepoint anymore. |
+ uword old_state = Thread::SetAtSafepoint(true, 0); |
+ uword addr = |
+ reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset(); |
+ if (AtomicOperations::CompareAndSwapWord( |
+ reinterpret_cast<uword*>(addr), old_state, 0) != old_state) { |
+ // Fast update failed which means we could potentially be in the middle |
+ // of a safepoint operation and need to block for it. |
+ monitor_->Exit(); |
+ SafepointHandler* handler = thread->isolate()->safepoint_handler(); |
+ handler->ExitSafepointUsingLock(thread); |
+ monitor_->Enter(); |
+ } |
+ thread->set_execution_state(Thread::kThreadInVM); |
+ return result; |
+} |
+ |
} // namespace dart |