ART: Add GetAllThreads
Add support for GetAllThreads. Add a test.
Bug: 31684593
Test: m test-art-host-run-test-924-threads
Change-Id: I7068dd4d3700a32a87a44d38590e53df0bd238c7
diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
index 4334ca3..e41f074 100644
--- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc
+++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc
@@ -127,7 +127,7 @@
}
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 e20f560..f7f63bd 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 @@
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 b6ffbb5..fca42ad 100644
--- a/runtime/openjdkjvmti/ti_thread.h
+++ b/runtime/openjdkjvmti/ti_thread.h
@@ -39,6 +39,8 @@
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);