Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Unified Diff: Source/platform/heap/ThreadState.cpp

Issue 260723003: [oilpan]: Make parking threads for GC timeout in the case parking exceeds 100 MS (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/ThreadState.cpp
diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
index a8a66cb67fced14b8a90e6cafc677c3325ace37f..b6601b666d59a32f3c5fe813c44827169fcd1b1f 100644
--- a/Source/platform/heap/ThreadState.cpp
+++ b/Source/platform/heap/ThreadState.cpp
@@ -96,6 +96,13 @@ static Mutex& threadAttachMutex()
return mutex;
}
+static double lockingTimeout()
+{
+ // Wait time for parking all threads is at most 10 MS.
+ return 0.01;
+}
+
+
typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr_t*);
extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegistersCallback);
@@ -105,7 +112,7 @@ public:
~SafePointBarrier() { }
// Request other attached threads that are not at safe points to park themselves on safepoints.
- void parkOthers()
+ bool parkOthers()
{
ASSERT(ThreadState::current()->isAtSafePoint());
@@ -128,16 +135,30 @@ public:
interruptors[i]->requestInterrupt();
}
- while (acquireLoad(&m_unparkedThreadCount) > 0)
- m_parked.wait(m_mutex);
+ while (acquireLoad(&m_unparkedThreadCount) > 0) {
+ double expirationTime = currentTime() + lockingTimeout();
+ if (!m_parked.timedWait(m_mutex, expirationTime)) {
+ // One of the other threads did not return to a safepoint within the maximum
+ // time we allow for threads to be parked. Abandon the GC and resume the
+ // currently parked threads.
+ resumeOthers(true);
haraken 2014/05/01 04:03:56 Nit: It would be more consistent if you can remove
wibling-chromium 2014/05/01 06:51:48 Yes, that would be nice. However I am worried that
haraken 2014/05/01 07:33:50 Yes, but is it problematic that we allow another t
wibling-chromium 2014/05/01 08:25:18 No, that should be okay. However previously we wou
haraken 2014/05/01 08:36:31 Thanks for the clarification, makes sense!
+ return false;
+ }
+ }
+ return true;
}
- void resumeOthers()
+ void resumeOthers(bool barrierLocked = false)
{
ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads();
atomicSubtract(&m_unparkedThreadCount, threads.size());
haraken 2014/05/01 04:03:56 I guess this will confuse m_unparkedThreadCount. A
wibling-chromium 2014/05/01 06:51:48 I initially read the code the same way, but parkOt
haraken 2014/05/01 07:33:50 Thanks for the clarification. Your explanation sou
releaseStore(&m_canResume, 1);
- {
+
+ // FIXME: Resumed threads will all contend for m_mutex just to unlock it
+ // later which is a waste of resources.
+ if (UNLIKELY(barrierLocked)) {
+ m_resume.broadcast();
+ } else {
// FIXME: Resumed threads will all contend for
// m_mutex just to unlock it later which is a waste of
// resources.
@@ -159,6 +180,28 @@ public:
ASSERT(ThreadState::current()->isAtSafePoint());
}
+ void checkAndPark(ThreadState* state)
zerny-chromium 2014/05/01 07:05:38 Nit: avoid reordering/formatting for unchanged cod
wibling-chromium 2014/05/01 08:25:18 Done. I will revert that and do it in a separate c
+ {
+ ASSERT(!state->isSweepInProgress());
+ if (!acquireLoad(&m_canResume)) {
+ pushAllRegisters(this, state, parkAfterPushRegisters);
+ state->performPendingSweep();
+ }
+ }
+
+ void enterSafePoint(ThreadState* state)
+ {
+ ASSERT(!state->isSweepInProgress());
+ pushAllRegisters(this, state, enterSafePointAfterPushRegisters);
+ }
+
+ void leaveSafePoint(ThreadState* state)
+ {
+ if (atomicIncrement(&m_unparkedThreadCount) > 0)
+ checkAndPark(state);
+ }
+
+private:
void doPark(ThreadState* state, intptr_t* stackEnd)
{
state->recordStackEnd(stackEnd);
@@ -170,13 +213,9 @@ public:
atomicIncrement(&m_unparkedThreadCount);
}
- void checkAndPark(ThreadState* state)
+ static void parkAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state, intptr_t* stackEnd)
{
- ASSERT(!state->isSweepInProgress());
- if (!acquireLoad(&m_canResume)) {
- pushAllRegisters(this, state, parkAfterPushRegisters);
- state->performPendingSweep();
- }
+ barrier->doPark(state, stackEnd);
}
void doEnterSafePoint(ThreadState* state, intptr_t* stackEnd)
@@ -197,24 +236,6 @@ public:
}
}
- void enterSafePoint(ThreadState* state)
- {
- ASSERT(!state->isSweepInProgress());
- pushAllRegisters(this, state, enterSafePointAfterPushRegisters);
- }
-
- void leaveSafePoint(ThreadState* state)
- {
- if (atomicIncrement(&m_unparkedThreadCount) > 0)
- checkAndPark(state);
- }
-
-private:
- static void parkAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state, intptr_t* stackEnd)
- {
- barrier->doPark(state, stackEnd);
- }
-
static void enterSafePointAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state, intptr_t* stackEnd)
{
barrier->doEnterSafePoint(state, stackEnd);
@@ -701,9 +722,9 @@ void ThreadState::getStats(HeapStats& stats)
#endif
}
-void ThreadState::stopThreads()
+bool ThreadState::stopThreads()
{
- s_safePointBarrier->parkOthers();
+ return s_safePointBarrier->parkOthers();
}
void ThreadState::resumeThreads()
« no previous file with comments | « Source/platform/heap/ThreadState.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698