RFR: Update running count of ForkJoinPool when thread pinned
Miao Zheng
duke at openjdk.java.net
Mon Dec 20 07:14:11 UTC 2021
In the test case of this PR, when vt0 invoke System.out.println(), it will invoke managedBlock eventually, and create a new ForkJoinWorkerThread. The call stack is :
Thread[#17,ForkJoinPool-1-worker-1,5,CarrierThreads]
java.base/java.lang.VirtualThread$VThreadContinuation.onPinned(VirtualThread.java:161)
java.base/jdk.internal.vm.Continuation.onPinned0(Continuation.java:462)
java.base/jdk.internal.vm.Continuation.yield0(Continuation.java:447)
java.base/jdk.internal.vm.Continuation.yield(Continuation.java:407)
java.base/java.lang.VirtualThread.yieldContinuation(VirtualThread.java:351)
java.base/java.lang.VirtualThread.park(VirtualThread.java:509)
java.base/java.lang.System$2.parkVirtualThread(System.java:2570)
java.base/jdk.internal.misc.VirtualThreads.park(VirtualThreads.java:60)
java.base/java.util.concurrent.locks.LockSupport.park(LockSupport.java:219)
java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:715)
java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:938)
java.base/java.util.concurrent.locks.ReentrantLock$Sync.lock(ReentrantLock.java:153)
java.base/java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:322)
VTCompensate$2.run(VTCompensate.java:55) <== monitors:1
java.base/java.lang.VirtualThread.run(VirtualThread.java:270)
java.base/java.lang.VirtualThread$VThreadContinuation.lambda$new$0(VirtualThread.java:155)
java.base/jdk.internal.vm.Continuation.enter0(Continuation.java:377)
java.base/jdk.internal.vm.Continuation.enter(Continuation.java:370)
After create a new ForkJoinWorkerThread, we have two ForkJoinWorkerThread(use -Djdk.defaultScheduler.parallelism=1 for initialization), and vt1 pinned a ForkJoinWorkerThread.
When main thread unlock Reentrantlock, vt0 will re-submit to ForkJoinPool and we have an extra working thread to run vt0.
But we find the extra compensate working thread not work, it is parked. The call stack is :
"ForkJoinPool-1-worker-2" #18 [31814] daemon prio=5 os_prio=0 cpu=0.42ms elapsed=119.94s tid=0x00007f8cf8005050 nid=31814 waiting on condition [0x00007f8d4012c000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base at 19-internal/Native Method)
at java.util.concurrent.locks.LockSupport.park(java.base at 19-internal/LockSupport.java:371)
at java.util.concurrent.ForkJoinPool.awaitWork(java.base at 19-internal/ForkJoinPool.java:1706)
at java.util.concurrent.ForkJoinPool.runWorker(java.base at 19-internal/ForkJoinPool.java:1603)
at java.util.concurrent.ForkJoinWorkerThread.run(java.base at 19-internal/ForkJoinWorkerThread.java:165)
The problem is when submit vt-0 to ForkJoinPool, it will called signalWork() of ForkJoinPool and signalWork() do nothing because c < 0L(c < 0L means RC < parallelism, in our test case, parallelism is 1 and current running count is 1)
Actually, current running count should be 0 now because pinned thread can not running other task, so we think should update running count of ForkJoinPool before and after pin.
-------------
Commit messages:
- Update running count of ForkJoinPool when thread pinned
Changes: https://git.openjdk.java.net/loom/pull/83/files
Webrev: https://webrevs.openjdk.java.net/?repo=loom&pr=83&range=00
Stats: 90 lines in 3 files changed: 90 ins; 0 del; 0 mod
Patch: https://git.openjdk.java.net/loom/pull/83.diff
Fetch: git fetch https://git.openjdk.java.net/loom pull/83/head:pull/83
PR: https://git.openjdk.java.net/loom/pull/83
More information about the loom-dev
mailing list