< prev index next > test/hotspot/jtreg/serviceability/jvmti/vthread/StopThreadTest/StopThreadTest.java
Print this page
/*
* @test id=default
* @summary Verifies JVMTI StopThread support for virtual threads.
* @requires vm.continuations
* @run main/othervm/native -agentlib:StopThreadTest StopThreadTest
*/
/*
* @test id=no-vmcontinuations
* @summary Verifies JVMTI StopThread support for bound virtual threads.
! * @run main/othervm/native -agentlib:StopThreadTest -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations StopThreadTest
*/
/*
* @test id=platform
* @summary Verifies JVMTI StopThread support for platform threads.
* @run main/othervm/native -agentlib:StopThreadTest StopThreadTest platform
*/
import java.lang.AssertionError;
/*
* The test exercises the JVMTI function: StopThread(jthread).
* The test creates a new virtual or platform thread.
/*
* @test id=default
* @summary Verifies JVMTI StopThread support for virtual threads.
* @requires vm.continuations
+ * @library /test/lib
* @run main/othervm/native -agentlib:StopThreadTest StopThreadTest
*/
/*
* @test id=no-vmcontinuations
* @summary Verifies JVMTI StopThread support for bound virtual threads.
! * @library /test/lib
+ * @run main/othervm/native -agentlib:StopThreadTest -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations -DboundVThread=true StopThreadTest
*/
/*
* @test id=platform
* @summary Verifies JVMTI StopThread support for platform threads.
+ * @library /test/lib
* @run main/othervm/native -agentlib:StopThreadTest StopThreadTest platform
*/
+ import jdk.test.lib.Platform;
import java.lang.AssertionError;
/*
* The test exercises the JVMTI function: StopThread(jthread).
* The test creates a new virtual or platform thread.
* - method C() that forces agent to send AssertionError exception to its own thread
* All cases are using JVMTI StopThread to send an AssertionError object.
*/
public class StopThreadTest {
private static final String agentLib = "StopThreadTest";
+ static final boolean isBoundVThread = Boolean.getBoolean("boundVThread");
static final int JVMTI_ERROR_NONE = 0;
+ static final int JVMTI_ERROR_OPAQUE_FRAME = 32;
static final int THREAD_NOT_SUSPENDED = 13;
static final int PASSED = 0;
static final int FAILED = 2;
static void log(String str) { System.out.println(str); }
if (is_virtual) {
testTaskThread = Thread.ofVirtual().name("TestTaskThread").start(testTask);
} else {
testTaskThread = Thread.ofPlatform().name("TestTaskThread").start(testTask);
}
! TestTask.ensureAtPointA();
if (is_virtual) { // this check is for virtual target thread only
log("\nMain #A.1: unsuspended");
retCode = stopThread(testTaskThread);
if (retCode != THREAD_NOT_SUSPENDED) {
if (is_virtual) {
testTaskThread = Thread.ofVirtual().name("TestTaskThread").start(testTask);
} else {
testTaskThread = Thread.ofPlatform().name("TestTaskThread").start(testTask);
}
! TestTask.ensureAtPointA(testTaskThread);
if (is_virtual) { // this check is for virtual target thread only
log("\nMain #A.1: unsuspended");
retCode = stopThread(testTaskThread);
if (retCode != THREAD_NOT_SUSPENDED) {
}
log("\nMain #A.2: suspended");
suspendThread(testTaskThread);
retCode = stopThread(testTaskThread);
! if (retCode != JVMTI_ERROR_NONE) {
! throwFailed("Main #A.2: expected JVMTI_ERROR_NONE instead of: " + retCode);
} else {
! log("Main #A.2: got expected JVMTI_ERROR_NONE");
}
resumeThread(testTaskThread);
}
log("\nMain #B: method B() must be blocked in a breakpoint event handler");
{
}
log("\nMain #A.2: suspended");
suspendThread(testTaskThread);
retCode = stopThread(testTaskThread);
! int expectedRetCode = (is_virtual && !isBoundVThread && (Platform.isX64() || Platform.isAArch64())) ? JVMTI_ERROR_OPAQUE_FRAME : JVMTI_ERROR_NONE;
! String expectedRetCodeName = (is_virtual && !isBoundVThread && (Platform.isX64() || Platform.isAArch64())) ?
+ "JVMTI_ERROR_OPAQUE_FRAME" : "JVMTI_ERROR_NONE";
+ if (retCode != expectedRetCode) {
+ throwFailed("Main #A.2: expected " + expectedRetCodeName + " instead of: " + retCode);
} else {
! log("Main #A.2: got expected " + expectedRetCodeName);
}
resumeThread(testTaskThread);
}
log("\nMain #B: method B() must be blocked in a breakpoint event handler");
{
} catch (InterruptedException e) {
throw new RuntimeException("Interruption in TestTask.sleep: \n\t" + e);
}
}
! static void ensureAtPointA() {
! while (!atPointA) {
sleep(1);
}
}
// Ensure thread is finished.
} catch (InterruptedException e) {
throw new RuntimeException("Interruption in TestTask.sleep: \n\t" + e);
}
}
! static void ensureAtPointA(Thread vt) {
! // wait while the thread state is not the expected one
+ while (vt.getState() != Thread.State.BLOCKED) {
sleep(1);
}
}
// Ensure thread is finished.
} catch (AssertionError ex) {
log("TestTask.run: caught expected AssertionError from method A()");
seenExceptionFromA = true;
}
Thread.interrupted();
! if (!seenExceptionFromA) {
StopThreadTest.setFailed("TestTask.run: expected AssertionError from method A()");
}
sleep(1); // to cause yield
boolean seenExceptionFromB = false;
} catch (AssertionError ex) {
log("TestTask.run: caught expected AssertionError from method A()");
seenExceptionFromA = true;
}
Thread.interrupted();
! if (!seenExceptionFromA
+ && !(is_virtual
+ && !isBoundVThread
+ && (Platform.isX64() || (Platform.isAArch64())) )) {
StopThreadTest.setFailed("TestTask.run: expected AssertionError from method A()");
}
sleep(1); // to cause yield
boolean seenExceptionFromB = false;
// StopThread is used to send an AssertionError object two times:
// - when not suspended: THREAD_NOT_SUSPENDED is expected
// - when suspended: JVMTI_ERROR_NONE is expected
static void A() {
log("TestTask.A: started");
- atPointA = true;
synchronized (lock) {
}
log("TestTask.A: finished");
}
< prev index next >