summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Elliott Hughes <enh@google.com> 2011-12-15 17:27:34 -0800
committer Elliott Hughes <enh@google.com> 2011-12-15 17:27:34 -0800
commit831afe4c2334f3d96df39538023f122101c89384 (patch)
tree980cb1b75ba10ed3462c99ed827e75b23a5ffe0d
parentdbf05b722af99ba2fd2f4c4fc7eb6c3e9880e5d1 (diff)
Improve the ThreadStress test to send SIGQUIT, and fix the bug that finds.
I'd heard complaints of a system_server deadlock on crespo, but wasn't seeing it on mysid. I did see it soon after trying to use crespo, but system_server has way too many threads and adb is too damn unreliable for me to effectively debug that. This improves ThreadStress so we exercise that path lots, and catch the deadlock relatively quickly with relatively few threads. The fix is explained in a code comment that's larger than the fix. Change-Id: I593bc94cf1239065a604703568420986a03ce628
-rw-r--r--src/signal_catcher.cc6
-rw-r--r--test/ThreadStress/ThreadStress.java10
2 files changed, 15 insertions, 1 deletions
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc
index 9031c5e55f..80563e2bf4 100644
--- a/src/signal_catcher.cc
+++ b/src/signal_catcher.cc
@@ -95,6 +95,12 @@ void SignalCatcher::HandleSigQuit() {
Runtime* runtime = Runtime::Current();
ThreadList* thread_list = runtime->GetThreadList();
+ // We take the heap lock before suspending all threads so we don't end up in a situation where
+ // one of the suspended threads suspended via the implicit FullSuspendCheck on the slow path of
+ // Heap::Lock, which is the only case where a thread can be suspended while holding the heap lock.
+ // (We need the heap lock when we dump the thread list. We could probably fix this by duplicating
+ // more state from java.lang.Thread in struct Thread.)
+ ScopedHeapLock heap_lock;
thread_list->SuspendAll();
std::ostringstream os;
diff --git a/test/ThreadStress/ThreadStress.java b/test/ThreadStress/ThreadStress.java
index c294a3861a..1f8fb2d922 100644
--- a/test/ThreadStress/ThreadStress.java
+++ b/test/ThreadStress/ThreadStress.java
@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import libcore.io.*;
// Run on host with:
// javac ThreadTest.java && java ThreadStress && rm *.class
@@ -29,7 +30,8 @@ class ThreadStress implements Runnable {
enum Operation {
OOM(1),
- ALLOC(99),
+ SIGQUIT(19),
+ ALLOC(80),
EXIT(50),
WAIT(50);
@@ -194,6 +196,12 @@ class ThreadStress implements Runnable {
case EXIT: {
return;
}
+ case SIGQUIT: {
+ try {
+ Libcore.os.kill(Libcore.os.getpid(), OsConstants.SIGQUIT);
+ } catch (ErrnoException ex) {
+ }
+ }
case WAIT: {
synchronized (lock) {
try {