Index: runtime/vm/lockers.cc |
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc |
index 839d40ccdb43d03bd1393e715dc725be89176923..8eddc7390f3f20aa06bb4b8e78ced906ac3c4463 100644 |
--- a/runtime/vm/lockers.cc |
+++ b/runtime/vm/lockers.cc |
@@ -9,6 +9,23 @@ |
namespace dart { |
+static void updateThreadState(Thread* thread) { |
+ // 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(); |
+ handler->ExitSafepointUsingLock(thread); |
+ } |
+ thread->set_execution_state(Thread::kThreadInVM); |
+} |
+ |
+ |
Monitor::WaitResult MonitorLocker::WaitWithSafepointCheck(Thread* thread, |
int64_t millis) { |
ASSERT(thread == Thread::Current()); |
@@ -43,20 +60,49 @@ SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) { |
thread->set_execution_state(Thread::kThreadInBlockedState); |
thread->EnterSafepoint(); |
mutex->Lock(); |
- // 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(); |
- handler->ExitSafepointUsingLock(thread); |
- } |
- thread->set_execution_state(Thread::kThreadInVM); |
+ // Update thread state and block if a safepoint operation is in progress. |
+ updateThreadState(thread); |
+ } |
+} |
+ |
+ |
+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(); |
+ // Update thread state and block if a safepoint operation is in progress. |
+ updateThreadState(thread); |
+ } |
+} |
+ |
+ |
+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 |