Skip to content

Commit c3c851f

Browse files
authored
Merge pull request #22144 from tajila/vt
Add pending notify to compensate for missed notify
2 parents b9c60ce + d46ebf0 commit c3c851f

File tree

6 files changed

+29
-10
lines changed

6 files changed

+29
-10
lines changed

runtime/oti/ContinuationHelpers.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ class VM_ContinuationHelpers {
121121
#endif /* JAVA_SPEC_VERSION >= 24 */
122122
}
123123

124+
static VMINLINE void
125+
sendUnblockerThreadSignal(J9JavaVM *vm)
126+
{
127+
J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL(vm);
128+
}
129+
124130
static VMINLINE ContinuationState volatile *
125131
getContinuationStateAddress(J9VMThread *vmThread , j9object_t object)
126132
{
@@ -410,7 +416,7 @@ class VM_ContinuationHelpers {
410416
current->nextWaitingContinuation = vm->blockedContinuations;
411417
vm->blockedContinuations = current;
412418
}
413-
omrthread_monitor_notify(vm->blockedVirtualThreadsMutex);
419+
VM_ContinuationHelpers::sendUnblockerThreadSignal(vm);
414420
}
415421

416422
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);

runtime/oti/j9.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,14 @@ static_assert((LITERAL_STRLEN(J9_UNMODIFIABLE_CLASS_ANNOTATION) < (size_t)'/'),
438438
#define J9VM_SHOULD_CLEAR_JNIIDS_FOR_ASGCT(vm, classLoader) (J9_ARE_NO_BITS_SET((vm)->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_NEVER_KEEP_JNI_IDS) \
439439
&& ((classLoader)->asyncGetCallTraceUsed || J9_ARE_ANY_BITS_SET((vm)->extendedRuntimeFlags2, J9_EXTENDED_RUNTIME2_ALWAYS_KEEP_JNI_IDS)))
440440

441+
#define J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL(vm) \
442+
do { \
443+
omrthread_monitor_enter((vm)->blockedVirtualThreadsMutex); \
444+
omrthread_monitor_notify((vm)->blockedVirtualThreadsMutex); \
445+
(vm)->pendingBlockedVirtualThreadsNotify = TRUE; \
446+
omrthread_monitor_exit((vm)->blockedVirtualThreadsMutex); \
447+
} while (0)
448+
441449
#define DIR_LIB_STR "lib"
442450

443451
#if defined(J9VM_OPT_JFR)

runtime/oti/j9nonbuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6476,6 +6476,7 @@ typedef struct J9JavaVM {
64766476
#if JAVA_SPEC_VERSION >= 24
64776477
J9VMContinuation *blockedContinuations;
64786478
omrthread_monitor_t blockedVirtualThreadsMutex;
6479+
BOOLEAN pendingBlockedVirtualThreadsNotify;
64796480
#endif /* JAVA_SPEC_VERSION >= 24 */
64806481
} J9JavaVM;
64816482

runtime/vm/BytecodeInterpreter.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ class INTERPRETER_CLASS
15781578
/* Notify unblocker if the blocking monitor is unlocked or
15791579
* if a platform thread is currently waiting on the monitor.
15801580
*/
1581-
omrthread_monitor_notify(_vm->blockedVirtualThreadsMutex);
1581+
VM_ContinuationHelpers::sendUnblockerThreadSignal(_vm);
15821582
}
15831583
omrthread_monitor_exit(_vm->blockedVirtualThreadsMutex);
15841584
}

runtime/vm/ContinuationHelpers.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,8 +1177,17 @@ waitForSignal(J9VMThread *currentThread)
11771177
*/
11781178
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);
11791179
vmFuncs->internalExitVMToJNI(currentThread);
1180+
1181+
/* There is a timing hole right here and after the next monitor exit where a notify
1182+
* can be sent and it will not be responded to because the unblocker thread is not
1183+
* waiting yet. To address this a check for a pending notify is done and if there
1184+
* is one the wait is skipped.
1185+
*/
11801186
omrthread_monitor_enter(vm->blockedVirtualThreadsMutex);
1181-
omrthread_monitor_wait_interruptable(vm->blockedVirtualThreadsMutex, 0, 0);
1187+
if (!vm->pendingBlockedVirtualThreadsNotify) {
1188+
omrthread_monitor_wait_interruptable(vm->blockedVirtualThreadsMutex, 0, 0);
1189+
}
1190+
vm->pendingBlockedVirtualThreadsNotify = FALSE;
11821191
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);
11831192
vmFuncs->internalEnterVMFromJNI(currentThread);
11841193
omrthread_monitor_enter(vm->blockedVirtualThreadsMutex);
@@ -1311,7 +1320,6 @@ takeVirtualThreadListToUnblock(J9VMThread *currentThread)
13111320
current = next;
13121321
}
13131322
if ((NULL == unblockedList) && !hasPlatformThreadWaiting) {
1314-
13151323
waitForSignal(currentThread);
13161324
goto restart;
13171325
} else {

runtime/vm/monhelpers.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ objectMonitorExit(J9VMThread* vmStruct, j9object_t object)
103103
if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION)
104104
&& (0 != objectMonitor->virtualThreadWaitCount)
105105
) {
106-
omrthread_monitor_enter(vm->blockedVirtualThreadsMutex);
107-
omrthread_monitor_notify(vm->blockedVirtualThreadsMutex);
108-
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);
106+
J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL(vm);
109107
}
110108
}
111109
} else {
@@ -301,9 +299,7 @@ objectMonitorExit(J9VMThread* vmStruct, j9object_t object)
301299
if (J9_ARE_ANY_BITS_SET(vm->extendedRuntimeFlags3, J9_EXTENDED_RUNTIME3_YIELD_PINNED_CONTINUATION)
302300
&& (0 != objectMonitor->virtualThreadWaitCount)
303301
) {
304-
omrthread_monitor_enter(vm->blockedVirtualThreadsMutex);
305-
omrthread_monitor_notify(vm->blockedVirtualThreadsMutex);
306-
omrthread_monitor_exit(vm->blockedVirtualThreadsMutex);
302+
J9VM_SEND_VIRTUAL_UNBLOCKER_THREAD_SIGNAL(vm);
307303
}
308304
#endif /* JAVA_SPEC_VERSION >= 24 */
309305
Trc_VM_objectMonitorExit_Exit_InflatedLock(vmStruct, rc);

0 commit comments

Comments
 (0)