@@ -40,6 +40,8 @@ extern "C" {
40
40
41
41
#if JAVA_SPEC_VERSION >= 19
42
42
extern J9JavaVM *BFUjavaVM;
43
+
44
+ extern IDATA (*f_threadSleep)(I_64 millis);
43
45
#endif /* JAVA_SPEC_VERSION >= 19 */
44
46
45
47
/* Define for debug
@@ -328,6 +330,27 @@ virtualThreadMountBegin(JNIEnv *env, jobject thread)
328
330
}
329
331
330
332
enterVThreadTransitionCritical (currentThread, thread);
333
+
334
+ /* Virtual thread is being mounted but it has been suspended. Spin until the
335
+ * virtual thread is resumed. The virtual thread should not be mounted until
336
+ * it is resumed.
337
+ */
338
+ J9JavaVM *vm = currentThread->javaVM ;
339
+ J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions ;
340
+ threadObj = J9_JNI_UNWRAP_REFERENCE (thread);
341
+ while (0 != J9OBJECT_U32_LOAD (currentThread, threadObj, vm->isSuspendedInternalOffset )) {
342
+ exitVThreadTransitionCritical (currentThread, threadObj);
343
+ vmFuncs->internalReleaseVMAccess (currentThread);
344
+ /* Spin is used instead of the halt flag; otherwise, the carrier thread will
345
+ * show as suspended.
346
+ *
347
+ * TODO: Dynamically increase the sleep time to a bounded maximum.
348
+ */
349
+ f_threadSleep (10 );
350
+ vmFuncs->internalAcquireVMAccess (currentThread);
351
+ enterVThreadTransitionCritical (currentThread, thread);
352
+ threadObj = J9_JNI_UNWRAP_REFERENCE (thread);
353
+ }
331
354
}
332
355
333
356
/* Caller must have VMAccess. */
@@ -354,15 +377,6 @@ virtualThreadMountEnd(JNIEnv *env, jobject thread)
354
377
J9VMJDKINTERNALVMCONTINUATION_VMREF (currentThread, continuationObj));
355
378
}
356
379
357
- /* Virtual thread is being mounted but it has been suspended. Thus,
358
- * set J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND flag. At this
359
- * point, virtual thread object is stored in targetThread->threadObject.
360
- */
361
- if (0 != J9OBJECT_U32_LOAD (currentThread, threadObj, vm->isSuspendedInternalOffset )) {
362
- Assert_SC_true (threadObj == currentThread->threadObject );
363
- vm->internalVMFunctions ->setHaltFlag (currentThread, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND);
364
- }
365
-
366
380
/* Allow thread to be inspected again. */
367
381
exitVThreadTransitionCritical (currentThread, threadObj);
368
382
@@ -396,6 +410,28 @@ virtualThreadUnmountBegin(JNIEnv *env, jobject thread)
396
410
397
411
enterVThreadTransitionCritical (currentThread, thread);
398
412
VM_VMHelpers::virtualThreadHideFrames (currentThread, JNI_TRUE);
413
+
414
+ J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions ;
415
+ j9object_t carrierThreadObject = currentThread->carrierThreadObject ;
416
+ threadObj = J9_JNI_UNWRAP_REFERENCE (thread);
417
+ /* Virtual thread is being umounted. If its carrier thread is suspended, spin until
418
+ * the carrier thread is resumed. The carrier thread should not be mounted until it
419
+ * is resumed.
420
+ */
421
+ while (0 != J9OBJECT_U32_LOAD (currentThread, carrierThreadObject, vm->isSuspendedInternalOffset )) {
422
+ exitVThreadTransitionCritical (currentThread, threadObj);
423
+ vmFuncs->internalReleaseVMAccess (currentThread);
424
+ /* Spin is used instead of the halt flag; otherwise, the virtual thread will
425
+ * show as suspended.
426
+ *
427
+ * TODO: Dynamically increase the sleep time to a bounded maximum.
428
+ */
429
+ f_threadSleep (10 );
430
+ vmFuncs->internalAcquireVMAccess (currentThread);
431
+ enterVThreadTransitionCritical (currentThread, thread);
432
+ carrierThreadObject = currentThread->carrierThreadObject ;
433
+ threadObj = J9_JNI_UNWRAP_REFERENCE (thread);
434
+ }
399
435
}
400
436
401
437
/* Caller must have VMAccess. */
@@ -429,15 +465,6 @@ virtualThreadUnmountEnd(JNIEnv *env, jobject thread)
429
465
vmFuncs->freeTLS (currentThread, threadObj);
430
466
}
431
467
432
- j9object_t carrierThreadObject = currentThread->carrierThreadObject ;
433
- /* The J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND will be set for the virtual
434
- * thread's carrier thread if it was suspended while the virtual thread was mounted.
435
- */
436
- if (0 != J9OBJECT_U32_LOAD (currentThread, carrierThreadObject, vm->isSuspendedInternalOffset )) {
437
- Assert_SC_true ((currentThread->threadObject == carrierThreadObject) && (NULL == currentThread->currentContinuation ));
438
- vmFuncs->setHaltFlag (currentThread, J9_PUBLIC_FLAGS_HALT_THREAD_JAVA_SUSPEND);
439
- }
440
-
441
468
/* Allow thread to be inspected again. */
442
469
exitVThreadTransitionCritical (currentThread, threadObj);
443
470
}
0 commit comments