Index: runtime/vm/lockers.cc |
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1c95381aea7b769a01896ec6deeb1bff26436d90 |
--- /dev/null |
+++ b/runtime/vm/lockers.cc |
@@ -0,0 +1,37 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#include "platform/assert.h" |
+#include "vm/lockers.h" |
+#include "vm/safepoint.h" |
+ |
+namespace dart { |
+ |
+ |
+Monitor::WaitResult MonitorLocker::WaitWithSafepointCheck(Thread* thread, |
+ int64_t millis) { |
+ ASSERT(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 |