Skip to content

Commit 87e3b7a

Browse files
authored
Merge pull request eclipse-openj9#21384 from babsingh/vt
JEP491: Never Deflate Monitors and Synchronize virtualThreadWaitCount
2 parents 946e97f + 305e12b commit 87e3b7a

File tree

3 files changed

+31
-15
lines changed

3 files changed

+31
-15
lines changed

runtime/vm/ContinuationHelpers.cpp

+13-8
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ preparePinnedVirtualThreadForUnmount(J9VMThread *currentThread, j9object_t syncO
10241024
currentThread->currentContinuation->objectWaitMonitor = syncObjectMonitor;
10251025
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);
10261026
} else {
1027-
syncObjectMonitor->virtualThreadWaitCount += 1;
1027+
VM_AtomicSupport::addU32(&syncObjectMonitor->virtualThreadWaitCount, 1);
10281028
}
10291029

10301030
/* Clear the blocking object on the carrier thread. */
@@ -1096,15 +1096,20 @@ takeVirtualThreadListToUnblock(J9VMThread *currentThread)
10961096
}
10971097
} else {
10981098
lock = J9OBJECT_MONITOR(currentThread, syncObject);
1099-
syncObjectMonitor = J9_INFLLOCK_OBJECT_MONITOR(lock);
1099+
if (J9_LOCK_IS_INFLATED(lock)) {
1100+
syncObjectMonitor = J9_INFLLOCK_OBJECT_MONITOR(lock);
1101+
}
11001102
}
1101-
omrthread_monitor_t monitor = syncObjectMonitor->monitor;
1102-
if (0 == monitor->count) {
1103-
unblocked = true;
1104-
if (syncObjectMonitor->virtualThreadWaitCount >= 1) {
1105-
syncObjectMonitor->virtualThreadWaitCount -= 1;
1103+
/* Only perform the below operations for inflated monitors. */
1104+
if (NULL != syncObjectMonitor) {
1105+
omrthread_monitor_t monitor = syncObjectMonitor->monitor;
1106+
if (0 == monitor->count) {
1107+
unblocked = true;
1108+
if (syncObjectMonitor->virtualThreadWaitCount >= 1) {
1109+
VM_AtomicSupport::subtractU32(&syncObjectMonitor->virtualThreadWaitCount, 1);
1110+
}
1111+
J9VMJAVALANGVIRTUALTHREAD_SET_ONWAITINGLIST(currentThread, current->vthread, JNI_TRUE);
11061112
}
1107-
J9VMJAVALANGVIRTUALTHREAD_SET_ONWAITINGLIST(currentThread, current->vthread, JNI_TRUE);
11081113
}
11091114
}
11101115

runtime/vm/monhelpers.c

+1-6
Original file line numberDiff line numberDiff line change
@@ -178,12 +178,7 @@ objectMonitorExit(J9VMThread* vmStruct, j9object_t object)
178178
* iff the deflation policy in effect decides it's ok.
179179
*/
180180
if (monitor->count == 1) {
181-
if ((0 == monitor->pinCount)
182-
#if JAVA_SPEC_VERSION >= 24
183-
&& (0 == objectMonitor->virtualThreadWaitCount)
184-
&& (NULL == objectMonitor->waitingContinuations)
185-
#endif /* JAVA_SPEC_VERSION >= 24 */
186-
) {
181+
if (0 == monitor->pinCount) {
187182
if (deflate) {
188183
deflate = 0;
189184
switch (vmStruct->javaVM->thrDeflationPolicy) {

runtime/vm/vmthread.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,23 @@ threadParseArguments(J9JavaVM *vm, char *optArg)
574574
vm->thrMaxTryEnterYieldsBeforeBlocking = 45;
575575
vm->thrNestedSpinning = 1;
576576
vm->thrTryEnterNestedSpinning = 1;
577-
vm->thrDeflationPolicy = J9VM_DEFLATION_POLICY_ASAP;
577+
578+
#if JAVA_SPEC_VERSION >= 24
579+
/* Currently, there are timing holes between JVM_TakeVirtualThreadListToUnblock and monitor deflation.
580+
* A monitor can be deflated while it is being accessed in JVM_TakeVirtualThreadListToUnblock. This
581+
* leads to a NULL dereference causing a segfault. Adding more synchronization will cause a significant
582+
* overhead in the object monitor exit path. Until an efficient solution is developed, the policy to never
583+
* deflate will be employed in order to support Synchronize Virtual Threads without Pinning (JEP491).
584+
* Since the current JEP491 implementation always inflates monitors before usage, deflating will be
585+
* counter-productive.
586+
*/
587+
if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION)) {
588+
vm->thrDeflationPolicy = J9VM_DEFLATION_POLICY_NEVER;
589+
} else
590+
#endif /* JAVA_SPEC_VERSION >= 24 */
591+
{
592+
vm->thrDeflationPolicy = J9VM_DEFLATION_POLICY_ASAP;
593+
}
578594

579595
if (cpus > 1) {
580596
#if (defined(LINUXPPC)) && !defined(J9VM_ENV_LITTLE_ENDIAN)

0 commit comments

Comments
 (0)