Uploaded image for project: 'Code Tools'
  1. Code Tools
  2. CODETOOLS-7903492

JMH: Infrastructure code should yield occasionally for virtual executor to make progress

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • None
    • None
    • tools
    • None
    • jmh

      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)
      ```

            shade Aleksey Shipilev
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: