On Wed, 23 Oct 2024 20:22:26 GMT, Patricio Chilano Mateo 
<pchilanom...@openjdk.org> wrote:

>> This is the implementation of JEP 491: Synchronize Virtual Threads without 
>> Pinning. See [JEP 491](https://bugs.openjdk.org/browse/JDK-8337395) for 
>> further details.
>> 
>> In order to make the code review easier the changes have been split into the 
>> following initial 4 commits:
>> 
>> - Changes to allow unmounting a virtual thread that is currently holding 
>> monitors.
>> - Changes to allow unmounting a virtual thread blocked on synchronized 
>> trying to acquire the monitor.
>> - Changes to allow unmounting a virtual thread blocked in `Object.wait()` 
>> and its timed-wait variants.
>> - Changes to tests, JFR pinned event, and other changes in the JDK libraries.
>> 
>> The changes fix pinning issues for all 4 ports that currently implement 
>> continuations: x64, aarch64, riscv and ppc. Note: ppc changes were added 
>> recently and stand in its own commit after the initial ones.
>> 
>> The changes fix pinning issues when using `LM_LIGHTWEIGHT`, i.e. the default 
>> locking mode, (and `LM_MONITOR` which comes for free), but not when using 
>> `LM_LEGACY` mode. Note that the `LockingMode` flag has already been 
>> deprecated ([JDK-8334299](https://bugs.openjdk.org/browse/JDK-8334299)), 
>> with the intention to remove `LM_LEGACY` code in future releases.
>> 
>> 
>> ## Summary of changes
>> 
>> ### Unmount virtual thread while holding monitors
>> 
>> As stated in the JEP, currently when a virtual thread enters a synchronized 
>> method or block, the JVM records the virtual thread's carrier platform 
>> thread as holding the monitor, not the virtual thread itself. This prevents 
>> the virtual thread from being unmounted from its carrier, as ownership 
>> information would otherwise go wrong. In order to fix this limitation we 
>> will do two things:
>> 
>> - We copy the oops stored in the LockStack of the carrier to the stackChunk 
>> when freezing (and clear the LockStack). We copy the oops back to the 
>> LockStack of the next carrier when thawing for the first time (and clear 
>> them from the stackChunk). Note that we currently assume carriers don't hold 
>> monitors while mounting virtual threads.
>> 
>> - For inflated monitors we now record the `java.lang.Thread.tid` of the 
>> owner in the ObjectMonitor's `_owner` field instead of a JavaThread*. This 
>> allows us to tie the owner of the monitor to a `java.lang.Thread` instance, 
>> rather than to a JavaThread which is only created per platform thread. The 
>> tid is already a 64 bit field so we can ignore issues of the counter 
>> wrapping around.
>> 
>> #### General notes about this part:
>> 
>> - Since virtual th...
>
> Patricio Chilano Mateo has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   Minor fixes in inc/dec_held_monitor_count on aarch64 and riscv

src/java.base/share/classes/java/lang/Thread.java line 654:

> 652:      * {@link Thread#PRIMORDIAL_TID}&nbsp;+1 as this class cannot be 
> used during
> 653:      * early startup to generate the identifier for the primordial 
> thread. The
> 654:      * counter is off-heap and shared with the VM to allow it assign 
> thread

Suggestion:

     * counter is off-heap and shared with the VM to allow it to assign thread

src/java.base/share/classes/java/lang/Thread.java line 655:

> 653:      * early startup to generate the identifier for the primordial 
> thread. The
> 654:      * counter is off-heap and shared with the VM to allow it assign 
> thread
> 655:      * identifiers to non-Java threads.

Why do non-JavaThreads need an identifier of this kind?

src/java.base/share/classes/java/lang/VirtualThread.java line 631:

> 629:         // Object.wait
> 630:         if (s == WAITING || s == TIMED_WAITING) {
> 631:             byte nonce;

Suggestion:

            byte seqNo;

src/java.base/share/classes/java/lang/VirtualThread.java line 948:

> 946:      * This method does nothing if the thread has been woken by notify 
> or interrupt.
> 947:      */
> 948:     private void waitTimeoutExpired(byte nounce) {

I assume you meant `nonce` here, but please change to `seqNo`.

src/java.base/share/classes/java/lang/VirtualThread.java line 952:

> 950:         for (;;) {
> 951:             boolean unblocked = false;
> 952:             synchronized (timedWaitLock()) {

Where is the overall design of the timed-wait protocol and it use of 
synchronization described?

src/java.base/share/classes/java/lang/VirtualThread.java line 1397:

> 1395: 
> 1396:     /**
> 1397:      * Returns a lock object to coordinating timed-wait setup and 
> timeout handling.

Suggestion:

     * Returns a lock object for coordinating timed-wait setup and timeout 
handling.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814158735
PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814159210
PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814169150
PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814170953
PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814171503
PR Review Comment: https://git.openjdk.org/jdk/pull/21565#discussion_r1814172621

Reply via email to