xref: /aosp_15_r20/art/test/924-threads/threads.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <mutex>
20*795d594fSAndroid Build Coastguard Worker #include <string>
21*795d594fSAndroid Build Coastguard Worker #include <vector>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
24*795d594fSAndroid Build Coastguard Worker #include "android-base/stringprintf.h"
25*795d594fSAndroid Build Coastguard Worker #include "jni.h"
26*795d594fSAndroid Build Coastguard Worker #include "jvmti.h"
27*795d594fSAndroid Build Coastguard Worker #include "scoped_local_ref.h"
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker // Test infrastructure
30*795d594fSAndroid Build Coastguard Worker #include "jni_helper.h"
31*795d594fSAndroid Build Coastguard Worker #include "jvmti_helper.h"
32*795d594fSAndroid Build Coastguard Worker #include "test_env.h"
33*795d594fSAndroid Build Coastguard Worker #include "ti_macros.h"
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace art {
36*795d594fSAndroid Build Coastguard Worker namespace Test924Threads {
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker struct WaiterStruct {
39*795d594fSAndroid Build Coastguard Worker   std::atomic<bool> started;
40*795d594fSAndroid Build Coastguard Worker   std::atomic<bool> finish;
41*795d594fSAndroid Build Coastguard Worker };
42*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_nativeWaiterStructAlloc(JNIEnv * env,jclass TestClass)43*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jlong JNICALL Java_art_Test924_nativeWaiterStructAlloc(
44*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass TestClass) {
45*795d594fSAndroid Build Coastguard Worker   WaiterStruct* s = nullptr;
46*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env,
47*795d594fSAndroid Build Coastguard Worker                             jvmti_env,
48*795d594fSAndroid Build Coastguard Worker                             jvmti_env->Allocate(sizeof(WaiterStruct),
49*795d594fSAndroid Build Coastguard Worker                                                 reinterpret_cast<unsigned char**>(&s)))) {
50*795d594fSAndroid Build Coastguard Worker     return 0;
51*795d594fSAndroid Build Coastguard Worker   }
52*795d594fSAndroid Build Coastguard Worker   s->started = false;
53*795d594fSAndroid Build Coastguard Worker   s->finish = false;
54*795d594fSAndroid Build Coastguard Worker   return static_cast<jlong>(reinterpret_cast<intptr_t>(s));
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_nativeWaiterStructWaitForNative(JNIEnv * env,jclass TestClass,jlong waiter_struct)57*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test924_nativeWaiterStructWaitForNative(
58*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass TestClass, jlong waiter_struct) {
59*795d594fSAndroid Build Coastguard Worker   WaiterStruct* s = reinterpret_cast<WaiterStruct*>(static_cast<intptr_t>(waiter_struct));
60*795d594fSAndroid Build Coastguard Worker   while (!s->started) { }
61*795d594fSAndroid Build Coastguard Worker }
62*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_nativeWaiterStructFinish(JNIEnv * env,jclass TestClass,jlong waiter_struct)63*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test924_nativeWaiterStructFinish(
64*795d594fSAndroid Build Coastguard Worker     [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass TestClass, jlong waiter_struct) {
65*795d594fSAndroid Build Coastguard Worker   WaiterStruct* s = reinterpret_cast<WaiterStruct*>(static_cast<intptr_t>(waiter_struct));
66*795d594fSAndroid Build Coastguard Worker   s->finish = true;
67*795d594fSAndroid Build Coastguard Worker }
68*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_nativeLoop(JNIEnv * env,jclass TestClass,jlong waiter_struct)69*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test924_nativeLoop(JNIEnv* env,
70*795d594fSAndroid Build Coastguard Worker                                                               [[maybe_unused]] jclass TestClass,
71*795d594fSAndroid Build Coastguard Worker                                                               jlong waiter_struct) {
72*795d594fSAndroid Build Coastguard Worker   WaiterStruct* s = reinterpret_cast<WaiterStruct*>(static_cast<intptr_t>(waiter_struct));
73*795d594fSAndroid Build Coastguard Worker   s->started = true;
74*795d594fSAndroid Build Coastguard Worker   while (!s->finish) { }
75*795d594fSAndroid Build Coastguard Worker   JvmtiErrorToException(env, jvmti_env, jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(s)));
76*795d594fSAndroid Build Coastguard Worker }
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker // private static native Thread getCurrentThread();
79*795d594fSAndroid Build Coastguard Worker // private static native Object[] getThreadInfo(Thread t);
80*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getCurrentThread(JNIEnv * env,jclass Main_klass)81*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jthread JNICALL Java_art_Test924_getCurrentThread(
82*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass) {
83*795d594fSAndroid Build Coastguard Worker   jthread thread = nullptr;
84*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->GetCurrentThread(&thread);
85*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, result)) {
86*795d594fSAndroid Build Coastguard Worker     return nullptr;
87*795d594fSAndroid Build Coastguard Worker   }
88*795d594fSAndroid Build Coastguard Worker   return thread;
89*795d594fSAndroid Build Coastguard Worker }
90*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getThreadInfo(JNIEnv * env,jclass Main_klass,jthread thread)91*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test924_getThreadInfo(
92*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jthread thread) {
93*795d594fSAndroid Build Coastguard Worker   jvmtiThreadInfo info;
94*795d594fSAndroid Build Coastguard Worker   memset(&info, 0, sizeof(jvmtiThreadInfo));
95*795d594fSAndroid Build Coastguard Worker 
96*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->GetThreadInfo(thread, &info);
97*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, result)) {
98*795d594fSAndroid Build Coastguard Worker     return nullptr;
99*795d594fSAndroid Build Coastguard Worker   }
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker   auto callback = [&](jint component_index) -> jobject {
102*795d594fSAndroid Build Coastguard Worker     switch (component_index) {
103*795d594fSAndroid Build Coastguard Worker       // The name.
104*795d594fSAndroid Build Coastguard Worker       case 0:
105*795d594fSAndroid Build Coastguard Worker         return (info.name == nullptr) ? nullptr : env->NewStringUTF(info.name);
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker       // The priority. Use a string for simplicity of construction.
108*795d594fSAndroid Build Coastguard Worker       case 1:
109*795d594fSAndroid Build Coastguard Worker         return env->NewStringUTF(android::base::StringPrintf("%d", info.priority).c_str());
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker       // Whether it's a daemon. Use a string for simplicity of construction.
112*795d594fSAndroid Build Coastguard Worker       case 2:
113*795d594fSAndroid Build Coastguard Worker         return env->NewStringUTF(info.is_daemon == JNI_TRUE ? "true" : "false");
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker       // The thread group;
116*795d594fSAndroid Build Coastguard Worker       case 3:
117*795d594fSAndroid Build Coastguard Worker         return env->NewLocalRef(info.thread_group);
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker       // The context classloader.
120*795d594fSAndroid Build Coastguard Worker       case 4:
121*795d594fSAndroid Build Coastguard Worker         return env->NewLocalRef(info.context_class_loader);
122*795d594fSAndroid Build Coastguard Worker     }
123*795d594fSAndroid Build Coastguard Worker     LOG(FATAL) << "Should not reach here";
124*795d594fSAndroid Build Coastguard Worker     UNREACHABLE();
125*795d594fSAndroid Build Coastguard Worker   };
126*795d594fSAndroid Build Coastguard Worker   jobjectArray ret = CreateObjectArray(env, 5, "java/lang/Object", callback);
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(info.name));
129*795d594fSAndroid Build Coastguard Worker   if (info.thread_group != nullptr) {
130*795d594fSAndroid Build Coastguard Worker     env->DeleteLocalRef(info.thread_group);
131*795d594fSAndroid Build Coastguard Worker   }
132*795d594fSAndroid Build Coastguard Worker   if (info.context_class_loader != nullptr) {
133*795d594fSAndroid Build Coastguard Worker     env->DeleteLocalRef(info.context_class_loader);
134*795d594fSAndroid Build Coastguard Worker   }
135*795d594fSAndroid Build Coastguard Worker 
136*795d594fSAndroid Build Coastguard Worker   return ret;
137*795d594fSAndroid Build Coastguard Worker }
138*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getThreadState(JNIEnv * env,jclass Main_klass,jthread thread)139*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jint JNICALL Java_art_Test924_getThreadState(
140*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jthread thread) {
141*795d594fSAndroid Build Coastguard Worker   jint state;
142*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->GetThreadState(thread, &state);
143*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, result)) {
144*795d594fSAndroid Build Coastguard Worker     return 0;
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker   return state;
147*795d594fSAndroid Build Coastguard Worker }
148*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getAllThreads(JNIEnv * env,jclass Main_klass)149*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test924_getAllThreads(
150*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass) {
151*795d594fSAndroid Build Coastguard Worker   jint thread_count;
152*795d594fSAndroid Build Coastguard Worker   jthread* threads;
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->GetAllThreads(&thread_count, &threads);
155*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, result)) {
156*795d594fSAndroid Build Coastguard Worker     return nullptr;
157*795d594fSAndroid Build Coastguard Worker   }
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   auto callback = [&](jint index) {
160*795d594fSAndroid Build Coastguard Worker     return threads[index];
161*795d594fSAndroid Build Coastguard Worker   };
162*795d594fSAndroid Build Coastguard Worker   jobjectArray ret = CreateObjectArray(env, thread_count, "java/lang/Thread", callback);
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(threads));
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker   return ret;
167*795d594fSAndroid Build Coastguard Worker }
168*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getTLS(JNIEnv * env,jclass Main_klass,jthread thread)169*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jlong JNICALL Java_art_Test924_getTLS(
170*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jthread thread) {
171*795d594fSAndroid Build Coastguard Worker   void* tls;
172*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->GetThreadLocalStorage(thread, &tls);
173*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, result)) {
174*795d594fSAndroid Build Coastguard Worker     return 0;
175*795d594fSAndroid Build Coastguard Worker   }
176*795d594fSAndroid Build Coastguard Worker   return static_cast<jlong>(reinterpret_cast<uintptr_t>(tls));
177*795d594fSAndroid Build Coastguard Worker }
178*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_setTLS(JNIEnv * env,jclass Main_klass,jthread thread,jlong val)179*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test924_setTLS(
180*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jthread thread, jlong val) {
181*795d594fSAndroid Build Coastguard Worker   const void* tls = reinterpret_cast<void*>(static_cast<uintptr_t>(val));
182*795d594fSAndroid Build Coastguard Worker   jvmtiError result = jvmti_env->SetThreadLocalStorage(thread, tls);
183*795d594fSAndroid Build Coastguard Worker   JvmtiErrorToException(env, jvmti_env, result);
184*795d594fSAndroid Build Coastguard Worker }
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker static std::mutex gEventsMutex;
187*795d594fSAndroid Build Coastguard Worker static std::vector<std::string> gEvents;
188*795d594fSAndroid Build Coastguard Worker 
ThreadEvent(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread,bool is_start)189*795d594fSAndroid Build Coastguard Worker static void JNICALL ThreadEvent(jvmtiEnv* jvmti_env,
190*795d594fSAndroid Build Coastguard Worker                                 JNIEnv* jni_env,
191*795d594fSAndroid Build Coastguard Worker                                 jthread thread,
192*795d594fSAndroid Build Coastguard Worker                                 bool is_start) {
193*795d594fSAndroid Build Coastguard Worker   jvmtiThreadInfo info;
194*795d594fSAndroid Build Coastguard Worker   {
195*795d594fSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> guard(gEventsMutex);
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker     jvmtiError result = jvmti_env->GetThreadInfo(thread, &info);
198*795d594fSAndroid Build Coastguard Worker     if (result != JVMTI_ERROR_NONE) {
199*795d594fSAndroid Build Coastguard Worker       gEvents.push_back("Error getting thread info");
200*795d594fSAndroid Build Coastguard Worker       return;
201*795d594fSAndroid Build Coastguard Worker     }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker     gEvents.push_back(android::base::StringPrintf("Thread(%s): %s",
204*795d594fSAndroid Build Coastguard Worker                                                   info.name,
205*795d594fSAndroid Build Coastguard Worker                                                   is_start ? "start" : "end"));
206*795d594fSAndroid Build Coastguard Worker   }
207*795d594fSAndroid Build Coastguard Worker 
208*795d594fSAndroid Build Coastguard Worker   jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(info.name));
209*795d594fSAndroid Build Coastguard Worker   jni_env->DeleteLocalRef(info.thread_group);
210*795d594fSAndroid Build Coastguard Worker   jni_env->DeleteLocalRef(info.context_class_loader);
211*795d594fSAndroid Build Coastguard Worker }
212*795d594fSAndroid Build Coastguard Worker 
ThreadStart(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)213*795d594fSAndroid Build Coastguard Worker static void JNICALL ThreadStart(jvmtiEnv* jvmti_env,
214*795d594fSAndroid Build Coastguard Worker                                 JNIEnv* jni_env,
215*795d594fSAndroid Build Coastguard Worker                                 jthread thread) {
216*795d594fSAndroid Build Coastguard Worker   ThreadEvent(jvmti_env, jni_env, thread, true);
217*795d594fSAndroid Build Coastguard Worker }
218*795d594fSAndroid Build Coastguard Worker 
ThreadEnd(jvmtiEnv * jvmti_env,JNIEnv * jni_env,jthread thread)219*795d594fSAndroid Build Coastguard Worker static void JNICALL ThreadEnd(jvmtiEnv* jvmti_env,
220*795d594fSAndroid Build Coastguard Worker                               JNIEnv* jni_env,
221*795d594fSAndroid Build Coastguard Worker                               jthread thread) {
222*795d594fSAndroid Build Coastguard Worker   ThreadEvent(jvmti_env, jni_env, thread, false);
223*795d594fSAndroid Build Coastguard Worker }
224*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_enableThreadEvents(JNIEnv * env,jclass Main_klass,jboolean b)225*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT void JNICALL Java_art_Test924_enableThreadEvents(
226*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass, jboolean b) {
227*795d594fSAndroid Build Coastguard Worker   if (b == JNI_FALSE) {
228*795d594fSAndroid Build Coastguard Worker     jvmtiError ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
229*795d594fSAndroid Build Coastguard Worker                                                          JVMTI_EVENT_THREAD_START,
230*795d594fSAndroid Build Coastguard Worker                                                          nullptr);
231*795d594fSAndroid Build Coastguard Worker     if (JvmtiErrorToException(env, jvmti_env, ret)) {
232*795d594fSAndroid Build Coastguard Worker       return;
233*795d594fSAndroid Build Coastguard Worker     }
234*795d594fSAndroid Build Coastguard Worker     ret = jvmti_env->SetEventNotificationMode(JVMTI_DISABLE,
235*795d594fSAndroid Build Coastguard Worker                                               JVMTI_EVENT_THREAD_END,
236*795d594fSAndroid Build Coastguard Worker                                               nullptr);
237*795d594fSAndroid Build Coastguard Worker     JvmtiErrorToException(env, jvmti_env, ret);
238*795d594fSAndroid Build Coastguard Worker     return;
239*795d594fSAndroid Build Coastguard Worker   }
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker   jvmtiEventCallbacks callbacks;
242*795d594fSAndroid Build Coastguard Worker   memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
243*795d594fSAndroid Build Coastguard Worker   callbacks.ThreadStart = ThreadStart;
244*795d594fSAndroid Build Coastguard Worker   callbacks.ThreadEnd = ThreadEnd;
245*795d594fSAndroid Build Coastguard Worker   jvmtiError ret = jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
246*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, ret)) {
247*795d594fSAndroid Build Coastguard Worker     return;
248*795d594fSAndroid Build Coastguard Worker   }
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker   ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
251*795d594fSAndroid Build Coastguard Worker                                             JVMTI_EVENT_THREAD_START,
252*795d594fSAndroid Build Coastguard Worker                                             nullptr);
253*795d594fSAndroid Build Coastguard Worker   if (JvmtiErrorToException(env, jvmti_env, ret)) {
254*795d594fSAndroid Build Coastguard Worker     return;
255*795d594fSAndroid Build Coastguard Worker   }
256*795d594fSAndroid Build Coastguard Worker   ret = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
257*795d594fSAndroid Build Coastguard Worker                                             JVMTI_EVENT_THREAD_END,
258*795d594fSAndroid Build Coastguard Worker                                             nullptr);
259*795d594fSAndroid Build Coastguard Worker   JvmtiErrorToException(env, jvmti_env, ret);
260*795d594fSAndroid Build Coastguard Worker }
261*795d594fSAndroid Build Coastguard Worker 
Java_art_Test924_getThreadEventMessages(JNIEnv * env,jclass Main_klass)262*795d594fSAndroid Build Coastguard Worker extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test924_getThreadEventMessages(
263*795d594fSAndroid Build Coastguard Worker     JNIEnv* env, [[maybe_unused]] jclass Main_klass) {
264*795d594fSAndroid Build Coastguard Worker   std::lock_guard<std::mutex> guard(gEventsMutex);
265*795d594fSAndroid Build Coastguard Worker   jobjectArray ret = CreateObjectArray(env,
266*795d594fSAndroid Build Coastguard Worker                                        static_cast<jint>(gEvents.size()),
267*795d594fSAndroid Build Coastguard Worker                                        "java/lang/String",
268*795d594fSAndroid Build Coastguard Worker                                        [&](jint i) {
269*795d594fSAndroid Build Coastguard Worker     return env->NewStringUTF(gEvents[i].c_str());
270*795d594fSAndroid Build Coastguard Worker   });
271*795d594fSAndroid Build Coastguard Worker   gEvents.clear();
272*795d594fSAndroid Build Coastguard Worker   return ret;
273*795d594fSAndroid Build Coastguard Worker }
274*795d594fSAndroid Build Coastguard Worker 
275*795d594fSAndroid Build Coastguard Worker }  // namespace Test924Threads
276*795d594fSAndroid Build Coastguard Worker }  // namespace art
277