8328083: degrade virtual thread support for GetObjectMonitorUsage
Reviewed-by: cjplummer, alanb
This commit is contained in:
parent
4e6d851f3f
commit
b890336e11
@ -8249,37 +8249,42 @@ class C2 extends C1 implements I2 {
|
||||
<field id="owner">
|
||||
<jthread/>
|
||||
<description>
|
||||
The thread owning this monitor, or <code>nullptr</code> if unused
|
||||
The platform thread owning this monitor, or <code>nullptr</code> if owned
|
||||
by a virtual thread or not owned
|
||||
</description>
|
||||
</field>
|
||||
<field id="entry_count">
|
||||
<jint/>
|
||||
<description>
|
||||
The number of times the owning thread has entered the monitor
|
||||
The number of times the platform thread owning this monitor has entered it,
|
||||
or <code>0</code> if owned by a virtual thread or not owned
|
||||
</description>
|
||||
</field>
|
||||
<field id="waiter_count">
|
||||
<jint/>
|
||||
<description>
|
||||
The number of threads waiting to own this monitor
|
||||
The number of platform threads waiting to own this monitor, or <code>0</code>
|
||||
if only virtual threads are waiting or no threads are waiting
|
||||
</description>
|
||||
</field>
|
||||
<field id="waiters">
|
||||
<allocfieldbuf><jthread/></allocfieldbuf>
|
||||
<description>
|
||||
The <code>waiter_count</code> waiting threads
|
||||
The <code>waiter_count</code> waiting platform threads
|
||||
</description>
|
||||
</field>
|
||||
<field id="notify_waiter_count">
|
||||
<jint/>
|
||||
<description>
|
||||
The number of threads waiting to be notified by this monitor
|
||||
The number of platform threads waiting to own this monitor, or <code>0</code>
|
||||
if only virtual threads are waiting to be notified or no threads are waiting
|
||||
to be notified
|
||||
</description>
|
||||
</field>
|
||||
<field id="notify_waiters">
|
||||
<allocfieldbuf><jthread/></allocfieldbuf>
|
||||
<description>
|
||||
The <code>notify_waiter_count</code> threads waiting to be notified
|
||||
The <code>notify_waiter_count</code> platform threads waiting to be notified
|
||||
</description>
|
||||
</field>
|
||||
</typedef>
|
||||
@ -8287,6 +8292,12 @@ class C2 extends C1 implements I2 {
|
||||
Get information about the object's monitor.
|
||||
The fields of the <functionlink id="jvmtiMonitorUsage"></functionlink> structure
|
||||
are filled in with information about usage of the monitor.
|
||||
<p/>
|
||||
<b> This function does not support getting information about an object's monitor
|
||||
when it is owned by a virtual thread. It also does not support returning a
|
||||
reference to virtual threads that are waiting to own a monitor or waiting to
|
||||
be notified.
|
||||
</b>
|
||||
<todo>
|
||||
Decide and then clarify suspend requirements.
|
||||
</todo>
|
||||
|
@ -1482,14 +1482,19 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||
// first derive the object's owner and entry_count (if any)
|
||||
owning_thread = ObjectSynchronizer::get_lock_owner(tlh.list(), hobj);
|
||||
if (owning_thread != nullptr) {
|
||||
Handle th(current_thread, get_vthread_or_thread_oop(owning_thread));
|
||||
oop thread_oop = get_vthread_or_thread_oop(owning_thread);
|
||||
bool is_virtual = java_lang_VirtualThread::is_instance(thread_oop);
|
||||
if (is_virtual) {
|
||||
thread_oop = nullptr;
|
||||
}
|
||||
Handle th(current_thread, thread_oop);
|
||||
ret.owner = (jthread)jni_reference(calling_thread, th);
|
||||
|
||||
// The recursions field of a monitor does not reflect recursions
|
||||
// as lightweight locks before inflating the monitor are not included.
|
||||
// We have to count the number of recursive monitor entries the hard way.
|
||||
// We pass a handle to survive any GCs along the way.
|
||||
ret.entry_count = count_locked_objects(owning_thread, hobj);
|
||||
ret.entry_count = is_virtual ? 0 : count_locked_objects(owning_thread, hobj);
|
||||
}
|
||||
// implied else: entry_count == 0
|
||||
|
||||
@ -1513,6 +1518,7 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||
// this object has a lightweight monitor
|
||||
}
|
||||
|
||||
jint skipped = 0;
|
||||
if (mon != nullptr) {
|
||||
// Robustness: the actual waiting list can be smaller.
|
||||
// The nWait count we got from the mon->waiters() may include the re-entering
|
||||
@ -1522,11 +1528,16 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||
for (ObjectWaiter* waiter = mon->first_waiter();
|
||||
waiter != nullptr && (nWait == 0 || waiter != mon->first_waiter());
|
||||
waiter = mon->next_waiter(waiter)) {
|
||||
JavaThread *w = mon->thread_of_waiter(waiter);
|
||||
oop thread_oop = get_vthread_or_thread_oop(w);
|
||||
if (java_lang_VirtualThread::is_instance(thread_oop)) {
|
||||
skipped++;
|
||||
}
|
||||
nWait++;
|
||||
}
|
||||
}
|
||||
ret.waiter_count = nWant;
|
||||
ret.notify_waiter_count = nWait;
|
||||
ret.notify_waiter_count = nWait - skipped;
|
||||
|
||||
// Allocate memory for heavyweight and lightweight monitor.
|
||||
jvmtiError err;
|
||||
@ -1561,13 +1572,20 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
|
||||
}
|
||||
if (ret.notify_waiter_count > 0) { // we have threads waiting to be notified in Object.wait()
|
||||
ObjectWaiter *waiter = mon->first_waiter();
|
||||
jint skipped = 0;
|
||||
for (int i = 0; i < nWait; i++) {
|
||||
JavaThread *w = mon->thread_of_waiter(waiter);
|
||||
oop thread_oop = get_vthread_or_thread_oop(w);
|
||||
bool is_virtual = java_lang_VirtualThread::is_instance(thread_oop);
|
||||
assert(w != nullptr, "sanity check");
|
||||
// If the thread was found on the ObjectWaiter list, then
|
||||
// it has not been notified.
|
||||
Handle th(current_thread, get_vthread_or_thread_oop(w));
|
||||
ret.notify_waiters[i] = (jthread)jni_reference(calling_thread, th);
|
||||
if (java_lang_VirtualThread::is_instance(thread_oop)) {
|
||||
skipped++;
|
||||
} else {
|
||||
// If the thread was found on the ObjectWaiter list, then
|
||||
// it has not been notified.
|
||||
Handle th(current_thread, get_vthread_or_thread_oop(w));
|
||||
ret.notify_waiters[i - skipped] = (jthread)jni_reference(calling_thread, th);
|
||||
}
|
||||
waiter = mon->next_waiter(waiter);
|
||||
}
|
||||
}
|
||||
|
@ -1183,7 +1183,8 @@ void Threads::metadata_handles_do(void f(Metadata*)) {
|
||||
}
|
||||
|
||||
#if INCLUDE_JVMTI
|
||||
// Get count of Java threads that are waiting to enter or re-enter the specified monitor.
|
||||
// Get Java threads that are waiting to enter or re-enter the specified monitor.
|
||||
// Java threads that are executing mounted virtual threads are not included.
|
||||
GrowableArray<JavaThread*>* Threads::get_pending_threads(ThreadsList * t_list,
|
||||
int count,
|
||||
address monitor) {
|
||||
@ -1194,14 +1195,16 @@ GrowableArray<JavaThread*>* Threads::get_pending_threads(ThreadsList * t_list,
|
||||
for (JavaThread* p : *t_list) {
|
||||
if (!p->can_call_java()) continue;
|
||||
|
||||
oop thread_oop = JvmtiEnvBase::get_vthread_or_thread_oop(p);
|
||||
if (java_lang_VirtualThread::is_instance(thread_oop)) {
|
||||
continue;
|
||||
}
|
||||
// The first stage of async deflation does not affect any field
|
||||
// used by this comparison so the ObjectMonitor* is usable here.
|
||||
address pending = (address)p->current_pending_monitor();
|
||||
address waiting = (address)p->current_waiting_monitor();
|
||||
oop thread_oop = JvmtiEnvBase::get_vthread_or_thread_oop(p);
|
||||
bool is_virtual = java_lang_VirtualThread::is_instance(thread_oop);
|
||||
jint state = is_virtual ? JvmtiEnvBase::get_vthread_state(thread_oop, p)
|
||||
: JvmtiEnvBase::get_thread_state(thread_oop, p);
|
||||
// do not include virtual threads to the list
|
||||
jint state = JvmtiEnvBase::get_thread_state(thread_oop, p);
|
||||
if (pending == monitor || (waiting == monitor &&
|
||||
(state & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER))
|
||||
) { // found a match
|
||||
|
@ -129,7 +129,8 @@ public:
|
||||
// Print threads busy compiling, and returns the number of printed threads.
|
||||
static unsigned print_threads_compiling(outputStream* st, char* buf, int buflen, bool short_form = false);
|
||||
|
||||
// Get count of Java threads that are waiting to enter or re-enter the specified monitor.
|
||||
// Get Java threads that are waiting to enter or re-enter the specified monitor.
|
||||
// Java threads that are executing mounted virtual threads are not included.
|
||||
static GrowableArray<JavaThread*>* get_pending_threads(ThreadsList * t_list,
|
||||
int count, address monitor);
|
||||
|
||||
|
@ -1617,11 +1617,14 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
(object object "The object ID")
|
||||
)
|
||||
(Reply
|
||||
(threadObject owner "The monitor owner, or null if it is not currently owned.")
|
||||
(int entryCount "The number of times the monitor has been entered.")
|
||||
(Repeat waiters "The total number of threads that are waiting to enter or re-enter "
|
||||
"the monitor, or waiting to be notified by the monitor."
|
||||
(threadObject thread "A thread waiting for this monitor.")
|
||||
(threadObject owner "The platform thread owning this monitor, or null "
|
||||
"if owned by a virtual thread or not owned.")
|
||||
(int entryCount "The number of times the owning platform thread has entered the monitor, "
|
||||
"or 0 if owned by a virtual thread or not owned.")
|
||||
(Repeat waiters "The total number of platform threads that are waiting to enter or re-enter "
|
||||
"the monitor, or waiting to be notified by the monitor, or 0 if "
|
||||
"only virtual threads are waiting or no threads are waiting."
|
||||
(threadObject thread "A platform thread waiting for this monitor.")
|
||||
)
|
||||
)
|
||||
(ErrorSet
|
||||
@ -2871,7 +2874,7 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
"if not explicitly requested."
|
||||
|
||||
(int requestID
|
||||
"Request that generated event (or 0 if this "
|
||||
"Request that generated event, or 0 if this "
|
||||
"event is automatically generated.")
|
||||
(threadObject thread "Initial thread")
|
||||
)
|
||||
|
@ -345,7 +345,7 @@ public interface ObjectReference extends Value {
|
||||
|
||||
/**
|
||||
* Returns a List containing a {@link ThreadReference} for
|
||||
* each thread currently waiting for this object's monitor.
|
||||
* each platform thread currently waiting for this object's monitor.
|
||||
* See {@link ThreadReference#currentContendedMonitor} for
|
||||
* information about when a thread is considered to be waiting
|
||||
* for a monitor.
|
||||
@ -355,7 +355,8 @@ public interface ObjectReference extends Value {
|
||||
* operation is supported.
|
||||
*
|
||||
* @return a List of {@link ThreadReference} objects. The list
|
||||
* has zero length if no threads are waiting for the monitor.
|
||||
* has zero length if no threads are waiting for the monitor,
|
||||
* or only virtual threads are waiting for the monitor.
|
||||
* @throws java.lang.UnsupportedOperationException if the
|
||||
* target VM does not support this operation.
|
||||
* @throws IncompatibleThreadStateException if any
|
||||
@ -366,7 +367,7 @@ public interface ObjectReference extends Value {
|
||||
throws IncompatibleThreadStateException;
|
||||
|
||||
/**
|
||||
* Returns an {@link ThreadReference} for the thread, if any,
|
||||
* Returns a {@link ThreadReference} for the platform thread, if any,
|
||||
* which currently owns this object's monitor.
|
||||
* See {@link ThreadReference#ownedMonitors} for a definition
|
||||
* of ownership.
|
||||
@ -375,8 +376,9 @@ public interface ObjectReference extends Value {
|
||||
* {@link VirtualMachine#canGetMonitorInfo} to determine if the
|
||||
* operation is supported.
|
||||
*
|
||||
* @return the {@link ThreadReference} which currently owns the
|
||||
* monitor, or null if it is unowned.
|
||||
* @return the {@link ThreadReference} of the platform thread which
|
||||
* currently owns the monitor, or null if the monitor is owned
|
||||
* by a virtual thread or not owned.
|
||||
*
|
||||
* @throws java.lang.UnsupportedOperationException if the
|
||||
* target VM does not support this operation.
|
||||
@ -386,8 +388,9 @@ public interface ObjectReference extends Value {
|
||||
ThreadReference owningThread() throws IncompatibleThreadStateException;
|
||||
|
||||
/**
|
||||
* Returns the number times this object's monitor has been
|
||||
* entered by the current owning thread.
|
||||
* Returns the number of times this object's monitor has been entered by
|
||||
* the current owning thread if the owning thread is platform thread;
|
||||
* Returns 0 if not owned by a platform thread.
|
||||
* See {@link ThreadReference#ownedMonitors} for a definition
|
||||
* of ownership.
|
||||
* <p>
|
||||
|
@ -114,6 +114,13 @@ public class ObjectMonitorUsage {
|
||||
throw new Error("Unexpected " + e);
|
||||
}
|
||||
}
|
||||
static Thread expOwnerThread() {
|
||||
return Thread.currentThread().isVirtual() ? null : Thread.currentThread();
|
||||
}
|
||||
|
||||
static int expEntryCount() {
|
||||
return Thread.currentThread().isVirtual() ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Scenario #0:
|
||||
* - owning: 0
|
||||
@ -127,14 +134,18 @@ public class ObjectMonitorUsage {
|
||||
|
||||
setTestedMonitor(lockCheck);
|
||||
Thread[] wThreads = startWaitingThreads(isVirtual);
|
||||
final int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS;
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 0
|
||||
// count of threads waiting to enter: 0
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS
|
||||
check(lockCheck, null, 0, // no owner thread
|
||||
0, // count of threads waiting to enter: 0
|
||||
NUMBER_OF_WAITING_THREADS);
|
||||
expWaitingCount);
|
||||
|
||||
synchronized (lockCheck) {
|
||||
lockCheck.notifyAll();
|
||||
@ -158,20 +169,30 @@ public class ObjectMonitorUsage {
|
||||
Thread[] eThreads = null;
|
||||
|
||||
synchronized (lockCheck) {
|
||||
// Virtual threads are not supported by GetObjectMonitorUsage.
|
||||
// Correct the expected values for the virtual thread case.
|
||||
int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS;
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: 0
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: 0
|
||||
check(lockCheck, Thread.currentThread(), 1, 0, 0);
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(), 0, 0);
|
||||
|
||||
eThreads = startEnteringThreads(isVirtual);
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: 0
|
||||
check(lockCheck, Thread.currentThread(), 1,
|
||||
NUMBER_OF_ENTERING_THREADS,
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(),
|
||||
expEnteringCount,
|
||||
0 /* count of threads waiting to be notified: 0 */);
|
||||
|
||||
}
|
||||
@ -195,15 +216,23 @@ public class ObjectMonitorUsage {
|
||||
Thread[] eThreads = null;
|
||||
|
||||
synchronized (lockCheck) {
|
||||
// Virtual threads are not supported by the GetObjectMonitorUsage.
|
||||
// Correct the expected values for the virtual thread case.
|
||||
int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS;
|
||||
int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS;
|
||||
|
||||
eThreads = startEnteringThreads(isVirtual);
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS
|
||||
check(lockCheck, Thread.currentThread(), 1,
|
||||
NUMBER_OF_ENTERING_THREADS,
|
||||
NUMBER_OF_WAITING_THREADS);
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(),
|
||||
expEnteringCount,
|
||||
expWaitingCount);
|
||||
|
||||
lockCheck.notifyAll();
|
||||
}
|
||||
@ -234,35 +263,51 @@ public class ObjectMonitorUsage {
|
||||
Thread[] eThreads = null;
|
||||
|
||||
synchronized (lockCheck) {
|
||||
// Virtual threads are not supported by GetObjectMonitorUsage.
|
||||
// Correct the expected values for the virtual thread case.
|
||||
int expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS;
|
||||
int expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS;
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: 0
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS
|
||||
check(lockCheck, Thread.currentThread(), 1,
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(),
|
||||
0, // number of threads waiting to enter or re-enter
|
||||
NUMBER_OF_WAITING_THREADS);
|
||||
expWaitingCount);
|
||||
|
||||
eThreads = startEnteringThreads(isVirtual);
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS
|
||||
// count of threads waiting to re-enter: 0
|
||||
// count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS
|
||||
check(lockCheck, Thread.currentThread(), 1,
|
||||
NUMBER_OF_ENTERING_THREADS,
|
||||
NUMBER_OF_WAITING_THREADS);
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(),
|
||||
expEnteringCount,
|
||||
expWaitingCount);
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_WAITING_THREADS; i++) {
|
||||
expEnteringCount = isVirtual ? 0 : NUMBER_OF_ENTERING_THREADS + i + 1;
|
||||
expWaitingCount = isVirtual ? 0 : NUMBER_OF_WAITING_THREADS - i - 1;
|
||||
lockCheck.notify(); // notify waiting threads one by one
|
||||
// now the notified WaitingTask has to be blocked on the lockCheck re-enter
|
||||
|
||||
// The numbers below describe the testing scenario, not the expected results.
|
||||
// The expected numbers are different for virtual threads because
|
||||
// they are not supported by JVMTI GetObjectMonitorUsage.
|
||||
// entry count: 1
|
||||
// count of threads waiting to enter: NUMBER_OF_ENTERING_THREADS
|
||||
// count of threads waiting to re-enter: i + 1
|
||||
// count of threads waiting to be notified: NUMBER_OF_WAITING_THREADS - i - 1
|
||||
check(lockCheck, Thread.currentThread(), 1,
|
||||
NUMBER_OF_ENTERING_THREADS + i + 1,
|
||||
NUMBER_OF_WAITING_THREADS - i - 1);
|
||||
check(lockCheck, expOwnerThread(), expEntryCount(),
|
||||
expEnteringCount,
|
||||
expWaitingCount);
|
||||
}
|
||||
}
|
||||
joinThreads(wThreads);
|
||||
|
@ -197,8 +197,11 @@ public class entrycount002 {
|
||||
|
||||
display("Checking entryCount for iteration : " + i);
|
||||
try {
|
||||
// The lockRef.entryCount() is expected to return 0 if the owner thread is virtual.
|
||||
int expEntryCount = mainThread.isVirtual() ? 0 : i;
|
||||
int entryCount = lockRef.entryCount();
|
||||
if (entryCount != i) {
|
||||
|
||||
if (entryCount != expEntryCount) {
|
||||
exitCode = Consts.TEST_FAILED;
|
||||
complain("entry count method returned unexpected value : " + entryCount +
|
||||
"\n\t expected one : " + i);
|
||||
|
@ -200,6 +200,15 @@ public class owningthread002 {
|
||||
try {
|
||||
ThreadReference thread = lockRef.owningThread();
|
||||
|
||||
// The lockRef.owningThread() is expected to return null if tested threads are virtual.
|
||||
if (eventThread.isVirtual()) {
|
||||
if (thread == null) {
|
||||
display("expected null is returned` by owningThread method on virtual thread: " + eventThread.name());
|
||||
} else {
|
||||
complain("owningThread returned ThreadReference of virtual thread instead of null: " + thread.name());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (thread.name().indexOf(owningthread002a.threadNamePrefix) < 0) {
|
||||
exitCode = Consts.TEST_FAILED;
|
||||
complain("owningThread returned ThreadReference with unexpected name: " + thread.name());
|
||||
|
@ -122,6 +122,9 @@ public class waitingthreads002 {
|
||||
if (thread.name().indexOf(waitingthreads002a.threadNamePrefix) >= 0 &&
|
||||
thread.status() == ThreadReference.THREAD_STATUS_MONITOR ) {
|
||||
waitingCount++;
|
||||
// Virtual threads are not present in result returned by objRef.waitingThreads().
|
||||
if (!thread.isVirtual()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,7 +162,9 @@ public class waitingthreads002 {
|
||||
objRef = (ObjectReference) debuggeeClass.getValue(debuggeeClass.fieldByName(fieldName));
|
||||
try {
|
||||
List waitingThreads = objRef.waitingThreads();
|
||||
if (waitingThreads.size() != waitingthreads002a.threadCount) {
|
||||
final boolean vthreadMode = "Virtual".equals(System.getProperty("test.thread.factory"));
|
||||
final int expWaitingCount = vthreadMode ? 0 : waitingthreads002a.threadCount;
|
||||
if (waitingThreads.size() != expWaitingCount) {
|
||||
exitStatus = Consts.TEST_FAILED;
|
||||
complain("waitingThreads method returned list with unexpected size for " + fieldName +
|
||||
"\n\t expected value : " + waitingthreads002a.threadCount + "; got one : " + waitingThreads.size());
|
||||
|
@ -61,8 +61,16 @@ public class objmonusage001 {
|
||||
syncObject[i] = new Object();
|
||||
runn[i] = new objmonusage001a(mainThread, i, syncObject[i]);
|
||||
}
|
||||
// Virtual threads are not supported by GetObjectMonitorUsage.
|
||||
// Correct the expected values if the test is executed with
|
||||
// JTREG_TEST_THREAD_FACTORY=Virtual.
|
||||
Thread expOwner = mainThread.isVirtual() ? null : mainThread;
|
||||
int expEntryCount = mainThread.isVirtual() ? 0 : 1;
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||
Thread expNotifyWaiter = runn[i].isVirtual() ? null : runn[i];
|
||||
int expNotifyWaitingCount = runn[i].isVirtual() ? 0 : 1;
|
||||
|
||||
synchronized (syncObject[i]) {
|
||||
runn[i].start();
|
||||
try {
|
||||
@ -92,8 +100,8 @@ public class objmonusage001 {
|
||||
// This is a stable verification point because the worker thread is in wait()
|
||||
// and is not notified and the main thread is doing the verification.
|
||||
//
|
||||
check(NUMBER_OF_THREADS + i, syncObject[i], mainThread, 1,
|
||||
null, 0, runn[i], 1);
|
||||
check(NUMBER_OF_THREADS + i, syncObject[i], expOwner, expEntryCount,
|
||||
null, 0, expNotifyWaiter, expNotifyWaitingCount);
|
||||
}
|
||||
|
||||
// Check #3:
|
||||
@ -117,7 +125,7 @@ public class objmonusage001 {
|
||||
// and is not notified and the main thread is doing the verification.
|
||||
//
|
||||
check((NUMBER_OF_THREADS * 2) + i, syncObject[i], null, 0,
|
||||
null, 0, runn[i], 1);
|
||||
null, 0, expNotifyWaiter, expNotifyWaitingCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||
@ -147,6 +155,14 @@ class objmonusage001a extends Thread {
|
||||
}
|
||||
|
||||
public void run() {
|
||||
// Virtual threads are not supported by GetObjectMonitorUsage.
|
||||
// Correct the expected values if the test is executed with
|
||||
// JTREG_TEST_THREAD_FACTORY=Virtual.
|
||||
Thread expOwner = this.isVirtual() ? null : this;
|
||||
Thread expNotifyWaiter = mainThread.isVirtual() ? null : mainThread;
|
||||
int expEntryCount = this.isVirtual() ? 0 : 1;
|
||||
int expNotifyWaitingCount = mainThread.isVirtual() ? 0 : 1;
|
||||
|
||||
synchronized (syncObject) {
|
||||
// Check #1:
|
||||
// - owner == this_thread:
|
||||
@ -166,8 +182,8 @@ class objmonusage001a extends Thread {
|
||||
// This is a stable verification point because the main thread is in wait()
|
||||
// and is not notified and this worker thread is doing the verification.
|
||||
//
|
||||
objmonusage001.check(index, syncObject, this, 1,
|
||||
null, 0, mainThread, 1);
|
||||
objmonusage001.check(index, syncObject, expOwner, expEntryCount,
|
||||
null, 0, expNotifyWaiter, expNotifyWaitingCount);
|
||||
syncObject.notify();
|
||||
|
||||
try {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2024, 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
|
||||
@ -60,11 +60,23 @@ public class objmonusage004 {
|
||||
Thread currThread = Thread.currentThread();
|
||||
ContendThread thr[] = new ContendThread[NUMBER_OF_THREADS];
|
||||
synchronized (lockCheck) {
|
||||
// Virtual threads are not supported by GetObjectMonitorUsage.
|
||||
// Correct the expected values if the test is executed with
|
||||
// JTREG_TEST_THREAD_FACTORY=Virtual.
|
||||
Thread expOwner = currThread.isVirtual() ? null : currThread;
|
||||
int expEntryCount = currThread.isVirtual() ? 0 : 2;
|
||||
|
||||
synchronized (lockCheck) {
|
||||
check(lockCheck, currThread, 2, 0);
|
||||
check(lockCheck, expOwner, expEntryCount, 0);
|
||||
}
|
||||
expEntryCount = currThread.isVirtual() ? 0 : 1;
|
||||
int expWaiterCount = 0;
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_THREADS; i++) {
|
||||
thr[i] = new ContendThread();
|
||||
if (!thr[i].isVirtual()) {
|
||||
expWaiterCount++;
|
||||
}
|
||||
synchronized (lockStart) {
|
||||
thr[i].start();
|
||||
try {
|
||||
@ -74,7 +86,7 @@ public class objmonusage004 {
|
||||
throw new Error("Unexpected " + e);
|
||||
}
|
||||
}
|
||||
check(lockCheck, currThread, 1, i + 1);
|
||||
check(lockCheck, expOwner, expEntryCount, expWaiterCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user