Skip to content

Commit 6f03c78

Browse files
committed
8360702: runtime/Thread/AsyncExceptionTest.java timed out
Reviewed-by: dholmes, fbredberg
1 parent c4ec983 commit 6f03c78

File tree

2 files changed

+33
-32
lines changed

2 files changed

+33
-32
lines changed

test/hotspot/jtreg/runtime/Thread/AsyncExceptionOnMonitorEnter.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
* @test
2626
* @bug 8283044
2727
* @summary Stress delivery of asynchronous exceptions while target is at monitorenter
28-
* @requires test.thread.factory == null
2928
* @library /test/hotspot/jtreg/testlibrary
3029
* @run main/othervm/native AsyncExceptionOnMonitorEnter 0
3130
* @run main/othervm/native -agentlib:AsyncExceptionOnMonitorEnter AsyncExceptionOnMonitorEnter 1
@@ -45,9 +44,13 @@ public class AsyncExceptionOnMonitorEnter extends Thread {
4544
public static native int exitRawMonitor();
4645
public static native void destroyRawMonitor();
4746

47+
// Avoid using CountDownLatch or similar objects that require unparking the
48+
// main thread. Otherwise, if the main thread is run as a virtual thread, the
49+
// async exception could be sent while the target is still executing FJP logic.
50+
public volatile boolean started = false;
51+
public volatile boolean gotMonitor = false;
52+
4853
private static Object o1 = new Object();
49-
private static boolean firstWorker = true;
50-
private static Semaphore sem = new Semaphore(0);
5154

5255
@Override
5356
public void run() {
@@ -60,11 +63,9 @@ public void run() {
6063

6164
public void testWithJavaMonitor() {
6265
try {
66+
started = true;
6367
synchronized (o1) {
64-
if (firstWorker) {
65-
firstWorker = false;
66-
sem.release();
67-
}
68+
gotMonitor = true;
6869
Thread.sleep(1000);
6970
}
7071
} catch (ThreadDeath td) {
@@ -75,20 +76,16 @@ public void testWithJavaMonitor() {
7576

7677

7778
public void testWithJVMTIRawMonitor() {
78-
boolean savedFirst = false;
7979
try {
80+
started = true;
8081
int retCode = enterRawMonitor();
81-
if (retCode != 0 && firstWorker) {
82+
if (retCode != 0) {
8283
throw new RuntimeException("error in JVMTI RawMonitorEnter: retCode=" + retCode);
8384
}
84-
if (firstWorker) {
85-
firstWorker = false;
86-
savedFirst = true;
87-
sem.release();
88-
}
89-
Thread.sleep(1000);
85+
gotMonitor = true;
86+
Thread.sleep(500);
9087
retCode = exitRawMonitor();
91-
if (retCode != 0 && savedFirst) {
88+
if (retCode != 0) {
9289
throw new RuntimeException("error in JVMTI RawMonitorExit: retCode=" + retCode);
9390
}
9491
} catch (ThreadDeath td) {
@@ -134,15 +131,18 @@ public static void main(String[] args) {
134131
AsyncExceptionOnMonitorEnter worker2 = new AsyncExceptionOnMonitorEnter();
135132

136133
try {
137-
// Start firstWorker worker and wait until monitor is acquired
138-
firstWorker = true;
134+
// Start first worker and wait until monitor is acquired
139135
worker1.start();
140-
sem.acquire();
136+
while (!worker1.gotMonitor) {
137+
Thread.sleep(1);
138+
}
141139

142140
// Start second worker and allow some time for target to block on monitorenter
143141
// before executing Thread.stop()
144142
worker2.start();
145-
Thread.sleep(300);
143+
while (!worker2.started) {
144+
Thread.sleep(10);
145+
}
146146

147147
while (true) {
148148
JVMTIUtils.stopThread(worker2);
@@ -151,6 +151,8 @@ public static void main(String[] args) {
151151
// not released worker2 will deadlock on enter
152152
JVMTIUtils.stopThread(worker1);
153153
}
154+
// Give time to throw exception
155+
Thread.sleep(10);
154156

155157
if (!worker1.isAlive() && !worker2.isAlive()) {
156158
// Done with Thread.stop() calls since

test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ public class AsyncExceptionTest extends Thread {
4949
private final static int DEF_TIME_MAX = 30; // default max # secs to test
5050
private final static String PROG_NAME = "AsyncExceptionTest";
5151

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

54-
private boolean firstEntry = true;
5557
private boolean receivedThreadDeathinInternal1 = false;
5658
private boolean receivedThreadDeathinInternal2 = false;
5759
private volatile RuntimeException error = null;
@@ -77,6 +79,7 @@ public void run() {
7779

7880
public void internalRun1() {
7981
try {
82+
started = true;
8083
while (!receivedThreadDeathinInternal2) {
8184
internalRun2();
8285
}
@@ -87,16 +90,10 @@ public void internalRun1() {
8790

8891
public void internalRun2() {
8992
try {
90-
Integer myLocalCount = 1;
91-
Integer myLocalCount2 = 1;
93+
int myLocalCount = 1;
94+
int myLocalCount2 = 1;
9295

93-
if (firstEntry) {
94-
// Tell main thread we have started.
95-
startSyncObj.countDown();
96-
firstEntry = false;
97-
}
98-
99-
while(myLocalCount > 0) {
96+
while (myLocalCount > 0) {
10097
myLocalCount2 = (myLocalCount % 3) / 2;
10198
myLocalCount -= 1;
10299
}
@@ -128,7 +125,9 @@ public static void main(String[] args) {
128125
thread.start();
129126
try {
130127
// Wait for the worker thread to get going.
131-
thread.startSyncObj.await();
128+
while (!thread.started) {
129+
Thread.sleep(1);
130+
}
132131
// Send async exception and wait until it is thrown
133132
JVMTIUtils.stopThread(thread);
134133
thread.join();

0 commit comments

Comments
 (0)