For example, ControlStopTest intermittently times out in GHA when executed with executor-virtual. It looks like resource starvation.
Reproducible with current JDK 21-ea and dropping to 2 CPUs:
```
% taskset -c 0,1 mvn clean install -pl jmh-core-it -am -P executor-virtual -Dtest=ControlStopTest -DfailIfNoTests=false
```
jstack shows one FJP thread is carrying a virtual thread, while another thread is not picking the other one up:
```
"ForkJoinPool-1-worker-1" #21 [6122] daemon prio=5 os_prio=0 cpu=188404.34ms elapsed=188.43s tid=0x00007f312437cb70 [0x00007f30fd2c9000
]
Carrying virtual thread #20
at jdk.internal.vm.Continuation.run(java.base@21-internal/Continuation.java:251)
at java.lang.VirtualThread.runContinuation(java.base@21-internal/VirtualThread.java:223)
at java.lang.VirtualThread$$Lambda/0x000000080107e418.run(java.base@21-internal/Unknown Source)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(java.base@21-internal/ForkJoinTask.java:1423)
at java.util.concurrent.ForkJoinTask.doExec(java.base@21-internal/ForkJoinTask.java:387)
at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(java.base@21-internal/ForkJoinPool.java:1312)
at java.util.concurrent.ForkJoinPool.scan(java.base@21-internal/ForkJoinPool.java:1843)
at java.util.concurrent.ForkJoinPool.runWorker(java.base@21-internal/ForkJoinPool.java:1808)
at java.util.concurrent.ForkJoinWorkerThread.run(java.base@21-internal/ForkJoinWorkerThread.java:188)
"ForkJoinPool-1-worker-2" #23 [6123] daemon prio=5 os_prio=0 cpu=102.03ms elapsed=188.43s tid=0x00007f30bc000e80 nid=6123 waiting on condition [0x00007f30fd1c9000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21-internal/Native Method)
- parking to wait for <0x00000000ff773a18> (a java.util.concurrent.ForkJoinPool)
at java.util.concurrent.locks.LockSupport.park(java.base@21-internal/LockSupport.java:371)
at java.util.concurrent.ForkJoinPool.awaitWork(java.base@21-internal/ForkJoinPool.java:1893)
at java.util.concurrent.ForkJoinPool.runWorker(java.base@21-internal/ForkJoinPool.java:1809)
at java.util.concurrent.ForkJoinWorkerThread.run(java.base@21-internal/ForkJoinWorkerThread.java:188)
```
The infrastructure waits when warmup is ready, which never ends:
```
"main" #1 [6101] prio=5 os_prio=0 cpu=200.59ms elapsed=188.66s tid=0x00007f3124027f50 nid=6101 waiting on condition [0x00007f312c758000
]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21-internal/Native Method)
- parking to wait for <0x00000000ff6421d0> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(java.base@21-internal/LockSupport.java:221)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21-internal/AbstractQueuedSynchronizer.java:754)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base@21-internal/AbstractQueuedSynchron
izer.java:1099)
at java.util.concurrent.CountDownLatch.await(java.base@21-internal/CountDownLatch.java:230)
at org.openjdk.jmh.runner.InfraControlL2.awaitWarmupReady(InfraControl.java:236)
at org.openjdk.jmh.runner.InfraControl.awaitWarmupReady(InfraControl.java:40)
at org.openjdk.jmh.runner.BenchmarkHandler.runIteration(BenchmarkHandler.java:334)
at org.openjdk.jmh.runner.BaseRunner.runBenchmark(BaseRunner.java:262)
at org.openjdk.jmh.runner.BaseRunner.runBenchmark(BaseRunner.java:233)
at org.openjdk.jmh.runner.BaseRunner.doSingle(BaseRunner.java:138)
at org.openjdk.jmh.runner.BaseRunner.runBenchmarksForked(BaseRunner.java:75)
at org.openjdk.jmh.runner.ForkedRunner.run(ForkedRunner.java:72)
at org.openjdk.jmh.runner.ForkedMain.main(ForkedMain.java:86)
```
Reproducible with current JDK 21-ea and dropping to 2 CPUs:
```
% taskset -c 0,1 mvn clean install -pl jmh-core-it -am -P executor-virtual -Dtest=ControlStopTest -DfailIfNoTests=false
```
jstack shows one FJP thread is carrying a virtual thread, while another thread is not picking the other one up:
```
"ForkJoinPool-1-worker-1" #21 [6122] daemon prio=5 os_prio=0 cpu=188404.34ms elapsed=188.43s tid=0x00007f312437cb70 [0x00007f30fd2c9000
]
Carrying virtual thread #20
at jdk.internal.vm.Continuation.run(java.base@21-internal/Continuation.java:251)
at java.lang.VirtualThread.runContinuation(java.base@21-internal/VirtualThread.java:223)
at java.lang.VirtualThread$$Lambda/0x000000080107e418.run(java.base@21-internal/Unknown Source)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(java.base@21-internal/ForkJoinTask.java:1423)
at java.util.concurrent.ForkJoinTask.doExec(java.base@21-internal/ForkJoinTask.java:387)
at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(java.base@21-internal/ForkJoinPool.java:1312)
at java.util.concurrent.ForkJoinPool.scan(java.base@21-internal/ForkJoinPool.java:1843)
at java.util.concurrent.ForkJoinPool.runWorker(java.base@21-internal/ForkJoinPool.java:1808)
at java.util.concurrent.ForkJoinWorkerThread.run(java.base@21-internal/ForkJoinWorkerThread.java:188)
"ForkJoinPool-1-worker-2" #23 [6123] daemon prio=5 os_prio=0 cpu=102.03ms elapsed=188.43s tid=0x00007f30bc000e80 nid=6123 waiting on condition [0x00007f30fd1c9000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21-internal/Native Method)
- parking to wait for <0x00000000ff773a18> (a java.util.concurrent.ForkJoinPool)
at java.util.concurrent.locks.LockSupport.park(java.base@21-internal/LockSupport.java:371)
at java.util.concurrent.ForkJoinPool.awaitWork(java.base@21-internal/ForkJoinPool.java:1893)
at java.util.concurrent.ForkJoinPool.runWorker(java.base@21-internal/ForkJoinPool.java:1809)
at java.util.concurrent.ForkJoinWorkerThread.run(java.base@21-internal/ForkJoinWorkerThread.java:188)
```
The infrastructure waits when warmup is ready, which never ends:
```
"main" #1 [6101] prio=5 os_prio=0 cpu=200.59ms elapsed=188.66s tid=0x00007f3124027f50 nid=6101 waiting on condition [0x00007f312c758000
]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@21-internal/Native Method)
- parking to wait for <0x00000000ff6421d0> (a java.util.concurrent.CountDownLatch$Sync)
at java.util.concurrent.locks.LockSupport.park(java.base@21-internal/LockSupport.java:221)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21-internal/AbstractQueuedSynchronizer.java:754)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base@21-internal/AbstractQueuedSynchron
izer.java:1099)
at java.util.concurrent.CountDownLatch.await(java.base@21-internal/CountDownLatch.java:230)
at org.openjdk.jmh.runner.InfraControlL2.awaitWarmupReady(InfraControl.java:236)
at org.openjdk.jmh.runner.InfraControl.awaitWarmupReady(InfraControl.java:40)
at org.openjdk.jmh.runner.BenchmarkHandler.runIteration(BenchmarkHandler.java:334)
at org.openjdk.jmh.runner.BaseRunner.runBenchmark(BaseRunner.java:262)
at org.openjdk.jmh.runner.BaseRunner.runBenchmark(BaseRunner.java:233)
at org.openjdk.jmh.runner.BaseRunner.doSingle(BaseRunner.java:138)
at org.openjdk.jmh.runner.BaseRunner.runBenchmarksForked(BaseRunner.java:75)
at org.openjdk.jmh.runner.ForkedRunner.run(ForkedRunner.java:72)
at org.openjdk.jmh.runner.ForkedMain.main(ForkedMain.java:86)
```
- links to
-
Review(master) openjdk/jmh/111