< prev index next > test/hotspot/jtreg/serviceability/jvmti/vthread/GetThreadState/GetThreadStateTest.java
Print this page
/*
* @test id=default
* @bug 8312498
* @summary Basic test for JVMTI GetThreadState with virtual threads
* @run junit/othervm/native GetThreadStateTest
*/
/*
* @test id=no-vmcontinuations
* @requires vm.continuations
* @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest
*/
import java.util.StringJoiner;
- import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class GetThreadStateTest {
/*
* @test id=default
* @bug 8312498
* @summary Basic test for JVMTI GetThreadState with virtual threads
+ * @library /test/lib
* @run junit/othervm/native GetThreadStateTest
*/
/*
* @test id=no-vmcontinuations
* @requires vm.continuations
+ * @library /test/lib
* @run junit/othervm/native -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations GetThreadStateTest
*/
import java.util.StringJoiner;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
+ import jdk.test.lib.thread.VThreadPinner;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class GetThreadStateTest {
/**
* Test state of runnable thread.
*/
@Test
void testRunnable() throws Exception {
! var latch = new CountDownLatch(1);
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! latch.countDown();
// spin until done
while (!done.get()) {
Thread.onSpinWait();
}
});
try {
// wait for thread to start execution
! latch.await();
// thread should be runnable
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE;
check(thread, expected);
/**
* Test state of runnable thread.
*/
@Test
void testRunnable() throws Exception {
! var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! started.set(true);
// spin until done
while (!done.get()) {
Thread.onSpinWait();
}
});
try {
// wait for thread to start execution
! awaitTrue(started);
// thread should be runnable
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_RUNNABLE;
check(thread, expected);
/**
* Test state of thread waiting to enter a monitor.
*/
@Test
void testMonitorEnter() throws Exception {
! var latch = new CountDownLatch(1);
Object lock = new Object();
var thread = Thread.ofVirtual().unstarted(() -> {
! latch.countDown();
synchronized (lock) { }
});
try {
synchronized (lock) {
// start thread and wait for it to start execution
thread.start();
! latch.await();
// thread should block on monitor enter
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
await(thread, expected);
/**
* Test state of thread waiting to enter a monitor.
*/
@Test
void testMonitorEnter() throws Exception {
! var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().unstarted(() -> {
! started.set(true);
synchronized (lock) { }
});
try {
synchronized (lock) {
// start thread and wait for it to start execution
thread.start();
! awaitTrue(started);
// thread should block on monitor enter
int expected = JVMTI_THREAD_STATE_ALIVE | JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
await(thread, expected);
/**
* Test state of thread waiting in Object.wait().
*/
@Test
void testObjectWait() throws Exception {
! var latch = new CountDownLatch(1);
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
! latch.countDown();
try {
lock.wait();
} catch (InterruptedException e) { }
}
});
try {
! // wait for thread to own monitor
! latch.await();
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread waiting in Object.wait().
*/
@Test
void testObjectWait() throws Exception {
! var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
! started.set(true);
try {
lock.wait();
} catch (InterruptedException e) { }
}
});
try {
! // wait for thread to start execution
! awaitTrue(started);
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread waiting in Object.wait(millis).
*/
@Test
void testObjectWaitMillis() throws Exception {
! var latch = new CountDownLatch(1);
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
! latch.countDown();
try {
lock.wait(Long.MAX_VALUE);
} catch (InterruptedException e) { }
}
});
try {
! // wait for thread to own monitor
! latch.await();
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
/**
* Test state of thread waiting in Object.wait(millis).
*/
@Test
void testObjectWaitMillis() throws Exception {
! var started = new AtomicBoolean();
Object lock = new Object();
var thread = Thread.ofVirtual().start(() -> {
synchronized (lock) {
! started.set(true);
try {
lock.wait(Long.MAX_VALUE);
} catch (InterruptedException e) { }
}
});
try {
! // wait for thread to start execution
! awaitTrue(started);
// thread should wait
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
/**
* Test state of thread parked with LockSupport.park.
*/
@Test
void testPark() throws Exception {
! var latch = new CountDownLatch(1);
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! latch.countDown();
while (!done.get()) {
LockSupport.park();
}
});
try {
// wait for thread to start execution
! latch.await();
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread parked with LockSupport.park.
*/
@Test
void testPark() throws Exception {
! var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! started.set(true);
while (!done.get()) {
LockSupport.park();
}
});
try {
// wait for thread to start execution
! awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread parked with LockSupport.parkNanos.
*/
@Test
void testParkNanos() throws Exception {
! var latch = new CountDownLatch(1);
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! latch.countDown();
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
});
try {
// wait for thread to start execution
! latch.await();
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
/**
* Test state of thread parked with LockSupport.parkNanos.
*/
@Test
void testParkNanos() throws Exception {
! var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! started.set(true);
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
});
try {
// wait for thread to start execution
! awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
/**
* Test state of thread parked with LockSupport.park while holding a monitor.
*/
@Test
void testParkWhenPinned() throws Exception {
! var latch = new CountDownLatch(1);
- Object lock = new Object();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! synchronized (lock) {
! latch.countDown();
while (!done.get()) {
LockSupport.park();
}
! }
});
try {
! // wait for thread to own monitor
! latch.await();
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread parked with LockSupport.park while holding a monitor.
*/
@Test
void testParkWhenPinned() throws Exception {
! var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! VThreadPinner.runPinned(() -> {
! started.set(true);
while (!done.get()) {
LockSupport.park();
}
! });
});
try {
! // wait for thread to start execution
! awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_INDEFINITELY |
/**
* Test state of thread parked with LockSupport.parkNanos while holding a monitor.
*/
@Test
void testParkNanosWhenPinned() throws Exception {
! var latch = new CountDownLatch(1);
- Object lock = new Object();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! synchronized (lock) {
! latch.countDown();
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
! }
});
try {
! // wait for thread to own monitor
! latch.await();
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
/**
* Test state of thread parked with LockSupport.parkNanos while holding a monitor.
*/
@Test
void testParkNanosWhenPinned() throws Exception {
! var started = new AtomicBoolean();
var done = new AtomicBoolean();
var thread = Thread.ofVirtual().start(() -> {
! VThreadPinner.runPinned(() -> {
! started.set(true);
while (!done.get()) {
LockSupport.parkNanos(Long.MAX_VALUE);
}
! });
});
try {
! // wait for thread to start execution
! awaitTrue(started);
// thread should park
int expected = JVMTI_THREAD_STATE_ALIVE |
JVMTI_THREAD_STATE_WAITING |
JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT |
LockSupport.unpark(thread);
thread.join();
}
}
+ /**
+ * Waits for the boolean value to become true.
+ */
+ private static void awaitTrue(AtomicBoolean ref) throws Exception {
+ while (!ref.get()) {
+ Thread.sleep(20);
+ }
+ }
+
/**
* Asserts that the given thread has the expected JVMTI state.
*/
private static void check(Thread thread, int expected) {
System.err.format(" expect state=0x%x (%s) ...%n", expected, jvmtiStateToString(expected));
< prev index next >