RFR: Update running count of ForkJoinPool when thread pinned [v3]

Miao Zheng duke at openjdk.java.net
Thu Dec 23 02:48:33 UTC 2021


On Wed, 22 Dec 2021 02:01:43 GMT, Miao Zheng <duke at openjdk.java.net> wrote:

>> 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 :
>> 
>> at java.base/java.util.concurrent.ForkJoinPool.tryCompensate(ForkJoinPool.java:1789)
>>         at java.base/java.util.concurrent.ForkJoinPool.compensatedBlock(ForkJoinPool.java:3448)
>>         at java.base/jdk.internal.misc.Blocker.managedBlock(Blocker.java:185)
>>         at java.base/java.io.FileOutputStream.write(FileOutputStream.java:365)
>>         at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:126)
>>         at java.base/java.io.BufferedOutputStream.lockedFlush(BufferedOutputStream.java:251)
>>         at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:239)
>>         at java.base/java.io.PrintStream.lockedWrite(PrintStream.java:655)
>>         at java.base/java.io.PrintStream.write(PrintStream.java:633)
>>         at java.base/sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:308)
>>         at java.base/sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:404)
>>         at java.base/sun.nio.cs.StreamEncoder.lockedFlushBuffer(StreamEncoder.java:126)
>>         at java.base/sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:113)
>>         at java.base/java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:176)
>>         at java.base/java.io.PrintStream.lockedWriteln(PrintStream.java:859)
>>         at java.base/java.io.PrintStream.writeln(PrintStream.java:836)
>>         at java.base/java.io.PrintStream.println(PrintStream.java:1178)
>>         at VTCompensate$1.run(VTCompensate.java:45)
>>         at java.base/java.lang.VirtualThread.run(VirtualThread.java:270)
>>         at java.base/java.lang.VirtualThread$VThreadContinuation.lambda$new$0(VirtualThread.java:155)
>>         at java.base/jdk.internal.vm.Continuation.enter0(Continuation.java:377)
>>         at 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 re-submit vt-0 to ForkJoinPool, it will call signalWork() of ForkJoinPool and signalWork() do nothing because current c > 0L and the judgement of c < 0L will jump over the loop(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.
>
> Miao Zheng has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR.

Thanks for your response.

Eliminating pin is absolutely better. Except supporting Java monitors, I still have a question that how to support native frame or what the plan is with native frame?

I have another question that we should think a bit of pin is tolerable or not?If a bit of pin is tolerable, then maybe we should make pin work better with scheduler.

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

PR: https://git.openjdk.java.net/loom/pull/83


More information about the loom-dev mailing list