os << "DALVIK THREADS (" << list_.size() << "):\n";
}
DumpCheckpoint checkpoint(&os, dump_native_stack);
- size_t threads_running_checkpoint = RunCheckpoint(&checkpoint);
+ size_t threads_running_checkpoint;
+ {
+ // Use SOA to prevent deadlocks if multiple threads are calling Dump() at the same time.
+ ScopedObjectAccess soa(Thread::Current());
+ threads_running_checkpoint = RunCheckpoint(&checkpoint);
+ }
if (threads_running_checkpoint != 0) {
checkpoint.WaitForThreadsToRunThroughCheckpoint(threads_running_checkpoint);
}
import java.util.Map;
public class Main implements Runnable {
- static final int numberOfThreads = 8;
+ static final int numberOfThreads = 4;
public static void main(String[] args) throws Exception {
System.loadLibrary(args[0]);
namespace art {
extern "C" JNIEXPORT void JNICALL Java_Main_suspendAndResume(JNIEnv*, jclass) {
- usleep(100 * 1000); // Leave some time for threads to get in here before we start suspending.
- for (size_t i = 0; i < 500; ++i) {
- Runtime::Current()->GetThreadList()->SuspendAll(__FUNCTION__);
- usleep(500);
- Runtime::Current()->GetThreadList()->ResumeAll();
+ static constexpr size_t kInitialSleepUS = 100 * 1000; // 100ms.
+ static constexpr size_t kIterations = 500;
+ usleep(kInitialSleepUS); // Leave some time for threads to get in here before we start suspending.
+ enum Operation {
+ kOPSuspendAll,
+ kOPDumpStack,
+ kOPSuspendAllDumpStack,
+ // Total number of operations.
+ kOPNumber,
+ };
+ for (size_t i = 0; i < kIterations; ++i) {
+ switch (static_cast<Operation>(i % kOPNumber)) {
+ case kOPSuspendAll: {
+ ScopedSuspendAll ssa(__FUNCTION__);
+ usleep(500);
+ break;
+ }
+ case kOPDumpStack: {
+ Runtime::Current()->GetThreadList()->Dump(LOG(INFO));
+ usleep(500);
+ break;
+ }
+ case kOPSuspendAllDumpStack: {
+ // Not yet supported.
+ // ScopedSuspendAll ssa(__FUNCTION__);
+ // Runtime::Current()->GetThreadList()->Dump(LOG(INFO));
+ break;
+ }
+ case kOPNumber:
+ break;
+ }
}
}