diff options
author | 2017-01-16 16:07:49 +0000 | |
---|---|---|
committer | 2017-01-16 16:07:49 +0000 | |
commit | 4ca818c31cc38746332e68a89ca48be88aa9d7b6 (patch) | |
tree | 6ca240e6dcd08a11ed9c35bdbae220939f1bcae2 | |
parent | 5e01df491f371cdafd5c348511c373b527329a01 (diff) | |
parent | 8580744607a963d408956c3eb712b0e070c139b0 (diff) |
Merge "ART: Add GetAllThreads"
-rw-r--r-- | runtime/openjdkjvmti/OpenjdkJvmTi.cc | 2 | ||||
-rw-r--r-- | runtime/openjdkjvmti/ti_thread.cc | 50 | ||||
-rw-r--r-- | runtime/openjdkjvmti/ti_thread.h | 2 | ||||
-rw-r--r-- | test/924-threads/expected.txt | 1 | ||||
-rw-r--r-- | test/924-threads/src/Main.java | 16 | ||||
-rw-r--r-- | test/924-threads/threads.cc | 20 |
6 files changed, 90 insertions, 1 deletions
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index 09fcc1c7e2..8674e6cae7 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -126,7 +126,7 @@ class JvmtiFunctions { } static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr) { - return ERR(NOT_IMPLEMENTED); + return ThreadUtil::GetAllThreads(env, threads_count_ptr, threads_ptr); } static jvmtiError SuspendThread(jvmtiEnv* env, jthread thread) { diff --git a/runtime/openjdkjvmti/ti_thread.cc b/runtime/openjdkjvmti/ti_thread.cc index e20f5605d8..f7f63bd19c 100644 --- a/runtime/openjdkjvmti/ti_thread.cc +++ b/runtime/openjdkjvmti/ti_thread.cc @@ -42,6 +42,7 @@ #include "obj_ptr.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" +#include "thread_list.h" #include "well_known_classes.h" namespace openjdkjvmti { @@ -354,4 +355,53 @@ jvmtiError ThreadUtil::GetThreadState(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } +jvmtiError ThreadUtil::GetAllThreads(jvmtiEnv* env, + jint* threads_count_ptr, + jthread** threads_ptr) { + if (threads_count_ptr == nullptr || threads_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + art::Thread* current = art::Thread::Current(); + + art::ScopedObjectAccess soa(current); + + art::MutexLock mu(current, *art::Locks::thread_list_lock_); + std::list<art::Thread*> thread_list = art::Runtime::Current()->GetThreadList()->GetList(); + + std::vector<art::ObjPtr<art::mirror::Object>> peers; + + for (art::Thread* thread : thread_list) { + // Skip threads that are still starting. + if (thread->IsStillStarting()) { + continue; + } + + art::ObjPtr<art::mirror::Object> peer = thread->GetPeer(); + if (peer != nullptr) { + peers.push_back(peer); + } + } + + if (peers.empty()) { + *threads_count_ptr = 0; + *threads_ptr = nullptr; + } else { + unsigned char* data; + jvmtiError data_result = env->Allocate(peers.size() * sizeof(jthread), &data); + if (data_result != ERR(NONE)) { + return data_result; + } + jthread* threads = reinterpret_cast<jthread*>(data); + for (size_t i = 0; i != peers.size(); ++i) { + threads[i] = soa.AddLocalReference<jthread>(peers[i]); + } + + *threads_count_ptr = static_cast<jint>(peers.size()); + *threads_ptr = threads; + } + + return ERR(NONE); +} + } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_thread.h b/runtime/openjdkjvmti/ti_thread.h index b6ffbb5f65..fca42ad2b5 100644 --- a/runtime/openjdkjvmti/ti_thread.h +++ b/runtime/openjdkjvmti/ti_thread.h @@ -39,6 +39,8 @@ namespace openjdkjvmti { class ThreadUtil { public: + static jvmtiError GetAllThreads(jvmtiEnv* env, jint* threads_count_ptr, jthread** threads_ptr); + static jvmtiError GetCurrentThread(jvmtiEnv* env, jthread* thread_ptr); static jvmtiError GetThreadInfo(jvmtiEnv* env, jthread thread, jvmtiThreadInfo* info_ptr); diff --git a/test/924-threads/expected.txt b/test/924-threads/expected.txt index 54065223cf..32e3368d02 100644 --- a/test/924-threads/expected.txt +++ b/test/924-threads/expected.txt @@ -28,3 +28,4 @@ class dalvik.system.PathClassLoader e1 = ALIVE|WAITING_WITH_TIMEOUT|SLEEPING|WAITING 5 = ALIVE|RUNNABLE 2 = TERMINATED +[Thread[FinalizerDaemon,5,system], Thread[FinalizerWatchdogDaemon,5,system], Thread[HeapTaskDaemon,5,system], Thread[ReferenceQueueDaemon,5,system], Thread[Signal Catcher,5,system], Thread[main,5,main]] diff --git a/test/924-threads/src/Main.java b/test/924-threads/src/Main.java index 048766604f..492a7ac6d1 100644 --- a/test/924-threads/src/Main.java +++ b/test/924-threads/src/Main.java @@ -17,6 +17,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; import java.util.concurrent.CountDownLatch; import java.util.HashMap; import java.util.List; @@ -53,6 +54,8 @@ public class Main { printThreadInfo(t3); doStateTests(); + + doAllThreadsTests(); } private static class Holder { @@ -155,6 +158,18 @@ public class Main { printThreadState(t); } + private static void doAllThreadsTests() { + Thread[] threads = getAllThreads(); + Arrays.sort(threads, THREAD_COMP); + System.out.println(Arrays.toString(threads)); + } + + private final static Comparator<Thread> THREAD_COMP = new Comparator<Thread>() { + public int compare(Thread o1, Thread o2) { + return o1.getName().compareTo(o2.getName()); + } + }; + private final static Map<Integer, String> STATE_NAMES = new HashMap<Integer, String>(); private final static List<Integer> STATE_KEYS = new ArrayList<Integer>(); static { @@ -213,4 +228,5 @@ public class Main { private static native Thread getCurrentThread(); private static native Object[] getThreadInfo(Thread t); private static native int getThreadState(Thread t); + private static native Thread[] getAllThreads(); } diff --git a/test/924-threads/threads.cc b/test/924-threads/threads.cc index 4abf8fcf93..1487b7c64d 100644 --- a/test/924-threads/threads.cc +++ b/test/924-threads/threads.cc @@ -100,5 +100,25 @@ extern "C" JNIEXPORT jint JNICALL Java_Main_getThreadState( return state; } +extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getAllThreads( + JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) { + jint thread_count; + jthread* threads; + + jvmtiError result = jvmti_env->GetAllThreads(&thread_count, &threads); + if (JvmtiErrorToException(env, result)) { + return nullptr; + } + + auto callback = [&](jint index) { + return threads[index]; + }; + jobjectArray ret = CreateObjectArray(env, thread_count, "java/lang/Thread", callback); + + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(threads)); + + return ret; +} + } // namespace Test924Threads } // namespace art |