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

Unified Diff: Source/platform/heap/HeapTest.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: Add safepoint scopes around yield Created 6 years, 7 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/Heap.cpp ('k') | Source/platform/heap/RunAllTests.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/heap/HeapTest.cpp
diff --git a/Source/platform/heap/HeapTest.cpp b/Source/platform/heap/HeapTest.cpp
index c36cf9191d2e4705be01fe3c6ca608758538c6ed..09443de1873a22364d2c2eb2007a277bf7a06c3d 100644
--- a/Source/platform/heap/HeapTest.cpp
+++ b/Source/platform/heap/HeapTest.cpp
@@ -36,6 +36,7 @@
#include "platform/heap/HeapTerminatedArrayBuilder.h"
#include "platform/heap/ThreadState.h"
#include "platform/heap/Visitor.h"
+#include "public/platform/Platform.h"
#include "wtf/HashTraits.h"
#include "wtf/LinkedHashSet.h"
@@ -99,28 +100,39 @@ public:
explicit TestGCScope(ThreadState::StackState state)
: m_state(ThreadState::current())
, m_safePointScope(state)
+ , m_parkedAllThreads(false)
{
m_state->checkThread();
EXPECT_FALSE(m_state->isInGC());
- ThreadState::stopThreads();
- m_state->enterGC();
+ if (LIKELY(ThreadState::stopThreads())) {
+ m_state->enterGC();
+ m_parkedAllThreads = true;
+ }
}
+ bool allThreadsParked() { return m_parkedAllThreads; }
+
~TestGCScope()
{
- m_state->leaveGC();
- EXPECT_FALSE(m_state->isInGC());
- ThreadState::resumeThreads();
+ // Only cleanup if we parked all threads in which case the GC happened
+ // and we need to resume the other threads.
+ if (LIKELY(m_parkedAllThreads)) {
+ m_state->leaveGC();
+ EXPECT_FALSE(m_state->isInGC());
+ ThreadState::resumeThreads();
+ }
}
private:
ThreadState* m_state;
ThreadState::SafePointScope m_safePointScope;
+ bool m_parkedAllThreads; // False if we fail to park all threads
};
static void getHeapStats(HeapStats* stats)
{
TestGCScope scope(ThreadState::NoHeapPointersOnStack);
+ EXPECT_TRUE(scope.allThreadsParked());
Heap::getStats(stats);
}
@@ -350,7 +362,7 @@ protected:
for (int i = 0; i < numberOfThreads; i++)
createThread(&threadFunc, tester, "testing thread");
while (tester->m_threadsToFinish) {
- ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
+ ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
yield();
}
delete tester;
@@ -408,8 +420,8 @@ protected:
wrapper = IntWrapper::create(0x0bbac0de);
if (!(i % 10)) {
globalPersistent = adoptPtr(new GlobalIntWrapperPersistent(IntWrapper::create(0x0ed0cabb)));
- ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
}
+ ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
yield();
}
@@ -423,6 +435,7 @@ protected:
EXPECT_EQ(wrapper->value(), 0x0bbac0de);
EXPECT_EQ((*globalPersistent)->value(), 0x0ed0cabb);
}
+ ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
yield();
}
ThreadState::detach();
@@ -452,9 +465,7 @@ private:
for (int i = 0; i < numberOfAllocations; i++) {
weakMap->add(static_cast<unsigned>(i), IntWrapper::create(0));
weakMap2.add(static_cast<unsigned>(i), IntWrapper::create(0));
- if (!(i % 10)) {
- ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
- }
+ ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
yield();
}
@@ -468,6 +479,7 @@ private:
EXPECT_TRUE(weakMap->isEmpty());
EXPECT_TRUE(weakMap2.isEmpty());
}
+ ThreadState::SafePointScope scope(ThreadState::NoHeapPointersOnStack);
yield();
}
ThreadState::detach();
@@ -3273,6 +3285,7 @@ TEST(HeapTest, CheckAndMarkPointer)
// checkAndMarkPointer tests.
{
TestGCScope scope(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(scope.allThreadsParked()); // Fail the test if we could not park all threads.
Heap::makeConsistentForGC();
for (size_t i = 0; i < objectAddresses.size(); i++) {
EXPECT_TRUE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
@@ -3291,6 +3304,7 @@ TEST(HeapTest, CheckAndMarkPointer)
clearOutOldGarbage(&initialHeapStats);
{
TestGCScope scope(ThreadState::HeapPointersOnStack);
+ EXPECT_TRUE(scope.allThreadsParked());
Heap::makeConsistentForGC();
for (size_t i = 0; i < objectAddresses.size(); i++) {
EXPECT_FALSE(Heap::checkAndMarkPointer(&visitor, objectAddresses[i]));
@@ -3880,4 +3894,64 @@ TEST(HeapTest, MultipleMixins)
EXPECT_EQ(3, IntWrapper::s_destructorCalls);
}
+class GCParkingThreadTester {
+public:
+ static void test()
+ {
+ createThread(&sleeperMainFunc, 0, "SleepingThread");
+
+ // Wait for the sleeper to run.
+ while (!s_sleeperRunning) {
+ yield();
+ }
+
+ {
+ // Expect the first attempt to park the sleeping thread to fail
+ TestGCScope scope(ThreadState::NoHeapPointersOnStack);
+ EXPECT_FALSE(scope.allThreadsParked());
+ }
+
+ s_sleeperDone = true;
+
+ // Wait for the sleeper to finish.
+ while (s_sleeperRunning) {
+ // We enter the safepoint here since the sleeper thread will detach
+ // causing it to GC.
+ ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
+ yield();
+ }
+ {
+ // Since the sleeper thread has detached this is the only thread.
+ TestGCScope scope(ThreadState::NoHeapPointersOnStack);
+ EXPECT_TRUE(scope.allThreadsParked());
+ }
+ }
+
+private:
+ static void sleeperMainFunc(void* data)
+ {
+ ThreadState::attach();
+ s_sleeperRunning = true;
+
+ // Simulate a long running op that is not entering a safepoint.
+ while (!s_sleeperDone) {
+ yield();
+ }
+
+ ThreadState::detach();
+ s_sleeperRunning = false;
+ }
+
+ static volatile bool s_sleeperRunning;
+ static volatile bool s_sleeperDone;
+};
+
+volatile bool GCParkingThreadTester::s_sleeperRunning = false;
+volatile bool GCParkingThreadTester::s_sleeperDone = false;
+
+TEST(HeapTest, GCParkingTimeout)
+{
+ GCParkingThreadTester::test();
+}
+
} // WebCore namespace
« no previous file with comments | « Source/platform/heap/Heap.cpp ('k') | Source/platform/heap/RunAllTests.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698