Index: Source/platform/heap/ThreadState.h |
diff --git a/Source/platform/heap/ThreadState.h b/Source/platform/heap/ThreadState.h |
index 296261e17646ce7c8a1e26b0b46a6494c04afe83..02f4a68d38d59e21be7d6f35ab1e615b4e0a4b34 100644 |
--- a/Source/platform/heap/ThreadState.h |
+++ b/Source/platform/heap/ThreadState.h |
@@ -52,6 +52,7 @@ class HeapObjectHeader; |
class PersistentNode; |
class Visitor; |
class SafePointBarrier; |
+class SafePointAwareMutexLocker; |
template<typename Header> class ThreadHeap; |
class CallbackStack; |
@@ -369,7 +370,7 @@ public: |
// Mark current thread as running inside safepoint. |
void enterSafePointWithoutPointers() { enterSafePoint(NoHeapPointersOnStack, 0); } |
void enterSafePointWithPointers(void* scopeMarker) { enterSafePoint(HeapPointersOnStack, scopeMarker); } |
- void leaveSafePoint(); |
+ void leaveSafePoint(SafePointAwareMutexLocker* = 0); |
bool isAtSafePoint() const { return m_atSafePoint; } |
class SafePointScope { |
@@ -510,6 +511,7 @@ private: |
~ThreadState(); |
friend class SafePointBarrier; |
+ friend class SafePointAwareMutexLocker; |
void enterSafePoint(StackState, void*); |
NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); |
@@ -601,6 +603,51 @@ public: |
static ThreadState* state() { return ThreadState::current(); } |
}; |
+// The SafePointAwareMutexLocker is used to enter a safepoint while waiting for |
+// mutex lock. It also ensures that the lock is not held while waiting for a GC |
+// to complete in the leaveSafePoint method, by releasing the lock if the |
+// leaveSafePoint method cannot complete without blocking, see |
+// SafePointBarrier::checkAndPark. |
zerny-chromium
2014/06/17 11:12:56
Nits:
The SafePointAwareMutexLocker is -> SafePoin
wibling-chromium
2014/06/17 12:06:40
Done.
haraken
2014/06/17 12:25:41
... It also ensures that the lock is not held whil
|
+class SafePointAwareMutexLocker { |
+ WTF_MAKE_NONCOPYABLE(SafePointAwareMutexLocker); |
+public: |
+ SafePointAwareMutexLocker(Mutex& mutex) : m_mutex(mutex), m_locked(false) |
zerny-chromium
2014/06/17 11:12:56
nit: explicit
wibling-chromium
2014/06/17 12:06:40
Done.
|
+ { |
+ ThreadState* state = ThreadState::current(); |
+ do { |
+ bool leaveSafePoint = false; |
+ if (!state->isAtSafePoint()) { |
+ state->enterSafePoint(ThreadState::HeapPointersOnStack, this); |
+ leaveSafePoint = true; |
+ } |
+ m_mutex.lock(); |
+ m_locked = true; |
+ if (leaveSafePoint) { |
haraken
2014/06/17 12:25:41
Do we need |leaveSafePoint|? Probably we can use '
wibling-chromium
2014/06/17 12:38:21
No, unfortunately not since we only want to leave
|
+ state->leaveSafePoint(this); |
zerny-chromium
2014/06/17 11:12:56
Maybe add a comment here about "leaveSafePoint" po
wibling-chromium
2014/06/17 12:06:40
Done.
|
+ } |
+ } while (!m_locked); |
+ } |
+ |
+ ~SafePointAwareMutexLocker() |
+ { |
+ ASSERT(m_locked); |
+ m_mutex.unlock(); |
+ } |
+ |
+private: |
+ friend class SafePointBarrier; |
+ |
+ void reset() |
+ { |
+ ASSERT(m_locked); |
+ m_mutex.unlock(); |
+ m_locked = false; |
+ } |
+ |
+ Mutex& m_mutex; |
+ bool m_locked; |
+}; |
+ |
} |
#endif // ThreadState_h |