8257831: Suspend with handshakes

Reviewed-by: dcubed, rrich, dholmes, pchilanomate, sspitsyn
This commit is contained in:
Robbin Ehn 2021-04-22 10:30:47 +00:00
parent 28af31db34
commit 86bd44fe80
40 changed files with 470 additions and 1081 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -29,7 +29,6 @@ extern "C" {
static jvmtiEnv* jvmti = NULL;
static jthread* threads = NULL;
static jsize threads_count = 0;
static jrawMonitorID agent_monitor = NULL;
#define LOG(...) \
do { \
@ -46,18 +45,6 @@ check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) {
}
}
static void
agent_lock(JNIEnv* jni) {
jvmtiError err = jvmti->RawMonitorEnter(agent_monitor);
check_jvmti_status(jni, err, "monitor_enter: error in JVMTI RawMonitorEnter");
}
static void
agent_unlock(JNIEnv* jni) {
jvmtiError err = jvmti->RawMonitorExit(agent_monitor);
check_jvmti_status(jni, err, "monitor_exit: error in JVMTI RawMonitorExit");
}
JNIEXPORT void JNICALL
Java_SuspendWithCurrentThread_registerTestedThreads(JNIEnv *jni, jclass cls, jobjectArray threadsArr) {
LOG("\nregisterTestedThreads: started");
@ -74,16 +61,6 @@ Java_SuspendWithCurrentThread_registerTestedThreads(JNIEnv *jni, jclass cls, job
LOG("registerTestedThreads: finished\n");
}
/* This function is executed on the suspender thread, not the Main thread */
JNIEXPORT void JNICALL
Java_ThreadToSuspend_init(JNIEnv *jni, jclass cls) {
jvmtiError err = jvmti->CreateRawMonitor("Agent monitor", &agent_monitor);
check_jvmti_status(jni, err, "Java_ThreadToSuspend_init: error in JVMTI CreateRawMonitor");
// Main thread has to wait for the suspender thread to complete tested threads suspension
agent_lock(jni);
}
/* This function is executed on the suspender thread which is not Main thread */
JNIEXPORT void JNICALL
Java_ThreadToSuspend_suspendTestedThreads(JNIEnv *jni, jclass cls) {
@ -106,9 +83,6 @@ Java_ThreadToSuspend_suspendTestedThreads(JNIEnv *jni, jclass cls) {
}
LOG("suspendTestedThreads: finished\n");
// Allow the Main thread to inspect the result of tested threads suspension
agent_unlock(jni);
err = jvmti->Deallocate((unsigned char*)results);
check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI Deallocate results");
}
@ -117,10 +91,6 @@ JNIEXPORT jboolean JNICALL
Java_SuspendWithCurrentThread_checkTestedThreadsSuspended(JNIEnv *jni, jclass cls) {
LOG("checkTestedThreadsSuspended: started");
// Block until the suspender thread competes the tested threads suspension
agent_lock(jni);
agent_unlock(jni);
for (int i = 0; i < threads_count; i++) {
jint state = 0;
jvmtiError err = jvmti->GetThreadState(threads[i], &state);
@ -129,7 +99,7 @@ Java_SuspendWithCurrentThread_checkTestedThreadsSuspended(JNIEnv *jni, jclass cl
if ((state & JVMTI_THREAD_STATE_SUSPENDED) == 0) {
LOG("thread #%d has not been suspended yet: "
"# state: (%#x)", i, (int)state);
jni->FatalError("checkTestedThreadsSuspended: error: expected all tested threads suspended");
return JNI_FALSE;
}
}
LOG("checkTestedThreadsSuspended: finished\n");
@ -167,8 +137,6 @@ Java_SuspendWithCurrentThread_releaseTestedThreadsInfo(JNIEnv *jni, jclass cls)
jvmtiError err;
LOG("\nreleaseTestedThreadsInfo: started");
err = jvmti->DestroyRawMonitor(agent_monitor);
check_jvmti_status(jni, err, "releaseTestedThreadsInfo: error in JVMTI DestroyRawMonitor");
for (int i = 0; i < threads_count; i++) {
if (threads[i] != NULL) {