1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "jni.h" 18 #include "jvmti.h" 19 20 #include <vector> 21 22 #include "jvmti_helper.h" 23 #include "test_env.h" 24 25 namespace art { 26 namespace common_suspension { 27 28 extern "C" JNIEXPORT jboolean JNICALL Java_art_Suspension_isSuspended( 29 JNIEnv* env, jclass, jthread thr) { 30 jint state; 31 if (JvmtiErrorToException(env, jvmti_env, jvmti_env->GetThreadState(thr, &state))) { 32 return false; 33 } 34 return (state & JVMTI_THREAD_STATE_SUSPENDED) != 0; 35 } 36 37 static std::vector<jthread> CopyToVector(JNIEnv* env, jobjectArray thrs) { 38 jsize len = env->GetArrayLength(thrs); 39 std::vector<jthread> ret; 40 for (jsize i = 0; i < len; i++) { 41 ret.push_back(reinterpret_cast<jthread>(env->GetObjectArrayElement(thrs, i))); 42 } 43 return ret; 44 } 45 46 extern "C" JNIEXPORT jintArray JNICALL Java_art_Suspension_resumeList(JNIEnv* env, 47 jclass, 48 jobjectArray thr) { 49 static_assert(sizeof(jvmtiError) == sizeof(jint), "cannot use jintArray as jvmtiError array"); 50 std::vector<jthread> threads(CopyToVector(env, thr)); 51 if (env->ExceptionCheck()) { 52 return nullptr; 53 } 54 jintArray ret = env->NewIntArray(threads.size()); 55 if (env->ExceptionCheck()) { 56 return nullptr; 57 } 58 jint* elems = env->GetIntArrayElements(ret, nullptr); 59 JvmtiErrorToException(env, jvmti_env, 60 jvmti_env->ResumeThreadList(threads.size(), 61 threads.data(), 62 reinterpret_cast<jvmtiError*>(elems))); 63 env->ReleaseIntArrayElements(ret, elems, 0); 64 return ret; 65 } 66 67 extern "C" JNIEXPORT jintArray JNICALL Java_art_Suspension_suspendList(JNIEnv* env, 68 jclass, 69 jobjectArray thrs) { 70 static_assert(sizeof(jvmtiError) == sizeof(jint), "cannot use jintArray as jvmtiError array"); 71 std::vector<jthread> threads(CopyToVector(env, thrs)); 72 if (env->ExceptionCheck()) { 73 return nullptr; 74 } 75 jintArray ret = env->NewIntArray(threads.size()); 76 if (env->ExceptionCheck()) { 77 return nullptr; 78 } 79 jint* elems = env->GetIntArrayElements(ret, nullptr); 80 JvmtiErrorToException(env, jvmti_env, 81 jvmti_env->SuspendThreadList(threads.size(), 82 threads.data(), 83 reinterpret_cast<jvmtiError*>(elems))); 84 env->ReleaseIntArrayElements(ret, elems, 0); 85 return ret; 86 } 87 88 extern "C" JNIEXPORT void JNICALL Java_art_Suspension_resume(JNIEnv* env, jclass, jthread thr) { 89 JvmtiErrorToException(env, jvmti_env, jvmti_env->ResumeThread(thr)); 90 } 91 92 extern "C" JNIEXPORT void JNICALL Java_art_Suspension_suspend(JNIEnv* env, jclass, jthread thr) { 93 JvmtiErrorToException(env, jvmti_env, jvmti_env->SuspendThread(thr)); 94 } 95 96 } // namespace common_suspension 97 } // namespace art 98 99