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