Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion test/hotspot/jtreg/ProblemList-Virtual.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,5 @@ vmTestbase/nsk/jdi/ThreadReference/isSuspended/issuspended002/TestDescription.ja
gc/arguments/TestNewSizeThreadIncrease.java 0000000 generic-all
gc/g1/TestSkipRebuildRemsetPhase.java 0000000 generic-all
runtime/ErrorHandling/MachCodeFramesInErrorFile.java 0000000 generic-all
runtime/Thread/AsyncExceptionOnMonitorEnter.java 0000000 generic-all
runtime/Thread/StopAtExit.java 0000000 generic-all
runtime/handshake/HandshakeWalkStackTest.java 0000000 generic-all
41 changes: 22 additions & 19 deletions test/hotspot/jtreg/runtime/Thread/AsyncExceptionOnMonitorEnter.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ public class AsyncExceptionOnMonitorEnter extends Thread {
public static native int exitRawMonitor();
public static native void destroyRawMonitor();

// Avoid using CountDownLatch or similar objects that require unparking the
// main thread. Otherwise, if the main thread is run as a virtual thread, the
// async exception could be sent while the target is still executing FJP logic.
public volatile boolean started = false;
public volatile boolean gotMonitor = false;

private static Object o1 = new Object();
private static boolean firstWorker = true;
private static Semaphore sem = new Semaphore(0);

@Override
public void run() {
Expand All @@ -59,11 +63,9 @@ public void run() {

public void testWithJavaMonitor() {
try {
started = true;
synchronized (o1) {
if (firstWorker) {
firstWorker = false;
sem.release();
}
gotMonitor = true;
Thread.sleep(1000);
}
} catch (ThreadDeath td) {
Expand All @@ -74,20 +76,16 @@ public void testWithJavaMonitor() {


public void testWithJVMTIRawMonitor() {
boolean savedFirst = false;
try {
started = true;
int retCode = enterRawMonitor();
if (retCode != 0 && firstWorker) {
if (retCode != 0) {
throw new RuntimeException("error in JVMTI RawMonitorEnter: retCode=" + retCode);
}
if (firstWorker) {
firstWorker = false;
savedFirst = true;
sem.release();
}
Thread.sleep(1000);
gotMonitor = true;
Thread.sleep(500);
retCode = exitRawMonitor();
if (retCode != 0 && savedFirst) {
if (retCode != 0) {
throw new RuntimeException("error in JVMTI RawMonitorExit: retCode=" + retCode);
}
} catch (ThreadDeath td) {
Expand Down Expand Up @@ -133,15 +131,18 @@ public static void main(String[] args) {
AsyncExceptionOnMonitorEnter worker2 = new AsyncExceptionOnMonitorEnter();

try {
// Start firstWorker worker and wait until monitor is acquired
firstWorker = true;
// Start first worker and wait until monitor is acquired
worker1.start();
sem.acquire();
while (!worker1.gotMonitor) {
Thread.sleep(1);
}

// Start second worker and allow some time for target to block on monitorenter
// before executing Thread.stop()
worker2.start();
Thread.sleep(300);
while (!worker2.started) {
Thread.sleep(10);
}

while (true) {
JVMTIUtils.stopThread(worker2);
Expand All @@ -150,6 +151,8 @@ public static void main(String[] args) {
// not released worker2 will deadlock on enter
JVMTIUtils.stopThread(worker1);
}
// Give time to throw exception
Thread.sleep(10);

if (!worker1.isAlive() && !worker2.isAlive()) {
// Done with Thread.stop() calls since
Expand Down
17 changes: 8 additions & 9 deletions test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ public class AsyncExceptionTest extends Thread {
private final static int DEF_TIME_MAX = 30; // default max # secs to test
private final static String PROG_NAME = "AsyncExceptionTest";

public CountDownLatch startSyncObj = new CountDownLatch(1);
// Avoid using CountDownLatch or similar objects that require unparking the
// main thread. Otherwise, if the main thread is run as a virtual thread, the
// async exception could be sent while the target is still executing FJP logic.
public volatile boolean started = false;

private boolean firstEntry = true;
private boolean receivedThreadDeathinInternal1 = false;
private boolean receivedThreadDeathinInternal2 = false;
private volatile RuntimeException error = null;
Expand All @@ -77,6 +79,7 @@ public void run() {

public void internalRun1() {
try {
started = true;
while (!receivedThreadDeathinInternal2) {
internalRun2();
}
Expand All @@ -90,12 +93,6 @@ public void internalRun2() {
Integer myLocalCount = 1;
Integer myLocalCount2 = 1;

if (firstEntry) {
// Tell main thread we have started.
startSyncObj.countDown();
firstEntry = false;
}

while(myLocalCount > 0) {
myLocalCount2 = (myLocalCount % 3) / 2;
myLocalCount -= 1;
Expand Down Expand Up @@ -128,7 +125,9 @@ public static void main(String[] args) {
thread.start();
try {
// Wait for the worker thread to get going.
thread.startSyncObj.await();
while (!thread.started) {
Thread.sleep(1);
}
// Send async exception and wait until it is thrown
JVMTIUtils.stopThread(thread);
thread.join();
Expand Down