JDK-8259800 : timeout in tck test testForkJoin(ForkJoinPool8Test)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.concurrent
  • Affected Version: 17
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: aarch64
  • Submitted: 2021-01-14
  • Updated: 2021-08-05
  • Resolved: 2021-02-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17
17 b11Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
The following test timed out in the JDK17 CI:

java/util/concurrent/tck/JSR166TestCase.java

Here's a snippet from the log file:

#section:junit
----------messages:(7/682)----------
command: junit --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -Djsr166.testImplementationDetails=true -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 JSR166TestCase
reason: User specified action: run junit/othervm/timeout=1000 --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED -Djsr166.testImplementationDetails=true -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 JSR166TestCase 
Mode: othervm [/othervm specified]
Additional options from @modules: --add-modules java.management
Timeout information:
--- Timeout information end.
elapsed time (seconds): 4019.897
----------configuration:(5/175)----------
Boot Layer
  add modules: java.management                
  add opens:   java.base/java.lang            ALL-UNNAMED
               java.base/java.util.concurrent ALL-UNNAMED

----------System.out:(1/27)----------
Timeout refired 4000 times
----------System.err:(36/2438)----------
Looks like we're stuck running test: testForkJoin(ForkJoinPool8Test)
------ stacktrace dump start ------
"main" prio=5 Id=1 WAITING on java.lang.Thread@7d9c9aee
	at java.base@17-ea/java.lang.Object.wait(Native Method)
	-  waiting on java.lang.Thread@7d9c9aee
	at java.base@17-ea/java.lang.Thread.join(Thread.java:1301)
	at java.base@17-ea/java.lang.Thread.join(Thread.java:1369)
	at app//com.sun.javatest.regtest.agent.MainWrapper.main(MainWrapper.java:74)

"Notification Thread" daemon prio=9 Id=12 RUNNABLE

"MainThread" prio=5 Id=14 WAITING on ForkJoinPool8Test$FibAction@32666116
	at java.base@17-ea/jdk.internal.misc.Unsafe.park(Native Method)
	-  waiting on ForkJoinPool8Test$FibAction@32666116
	at java.base@17-ea/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
	at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:327)
	at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitJoin(ForkJoinTask.java:511)
	at java.base@17-ea/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:718)
	at app//ForkJoinPool8Test$FibAction.realCompute(ForkJoinPool8Test.java:222)
	at app//JSR166TestCase$CheckedRecursiveAction.compute(JSR166TestCase.java:1770)
	at java.base@17-ea/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194)
	...

"CompletableFutureDelayScheduler" daemon prio=5 Id=1739 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2bb4d65e
	at java.base@17-ea/jdk.internal.misc.Unsafe.park(Native Method)
	-  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2bb4d65e
	at java.base@17-ea/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
	at java.base@17-ea/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
	at java.base@17-ea/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
	at java.base@17-ea/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
	at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1061)
	at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121)
	at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	...

------ stacktrace dump end ------
----------rerun:(42/6337)*----------

<snip>

result: Error. Program `/scratch/opt/mach5/mesos/work_dir/jib-master/install/jdk-17+6-289/linux-aarch64.jdk/jdk-17/bin/java' timed out (timeout set to 4000000ms, elapsed time including timeout handling was 4019890ms).

Starting this bug off as a P2 since this is a Tier1 failure.
Comments
Changeset: 5b7b18c5 Author: Doug Lea <dl@openjdk.org> Date: 2021-02-22 12:42:40 +0000 URL: https://git.openjdk.java.net/jdk/commit/5b7b18c5
22-02-2021

Thanks to David for testing version that combined fixes. The main problem was that a submission queue could move in parallelism-0 mode. I'm trying to set up PR with the already-tested changes, but adding a few lines of internal documentation and cleanup.
20-02-2021

Still fails. One example - MainThread is here: "MainThread" #14 prio=5 os_prio=0 cpu=4792.98ms elapsed=4008.65s allocated=175M defined_classes=3210 tid=0x0000fffcac3d39e0 nid=0x376c waiting on condition [0x0000fffc9458c000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@17-internal/Native Method) - parking to wait for <0x00000000e106a090> (a java.util.stream.ForEachOps$ForEachTask) at java.util.concurrent.locks.LockSupport.park(java.base@17-internal/LockSupport.java:341) at java.util.concurrent.ForkJoinTask.awaitDone(java.base@17-internal/ForkJoinTask.java:468) at java.util.concurrent.ForkJoinTask.invoke(java.base@17-internal/ForkJoinTask.java:687) at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(java.base@17-internal/ForEachOps.java:159) at java.util.stream.ForEachOps$ForEachOp$OfInt.evaluateParallel(java.base@17-internal/ForEachOps.java:188) at java.util.stream.AbstractPipeline.evaluate(java.base@17-internal/AbstractPipeline.java:233) at java.util.stream.IntPipeline.forEach(java.base@17-internal/IntPipeline.java:463) at java.util.stream.IntPipeline$Head.forEach(java.base@17-internal/IntPipeline.java:620) at SplittableRandomTest.testIntsCount(SplittableRandomTest.java:396) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(java.base@17-internal/Native Method) at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(java.base@17-internal/NativeMethodAccessorImpl.java:78) at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(java.base@17-internal/DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(java.base@17-internal/Method.java:566) at junit.framework.TestCase.runTest(TestCase.java:168) at JSR166TestCase.runTest(JSR166TestCase.java:380) at junit.framework.TestCase.runBare(TestCase.java:134) at JSR166TestCase.runBare(JSR166TestCase.java:371) but there are zero executor/pool threads in the dump.
19-02-2021

I will change the weak CAS locally and retry some testing. FYI the jcstress testing I did showed no issues.
18-02-2021

> But one theory is that a CAS somewhere that is statically "known" not to fail with parallelism 0 somehow does anyway. I noticed ForkJoinPool uses weakCompareAndSet in some places. The machine this is failing on, Ampere eMAG, does not have the LSE extension so C2 implements weakCompare*() as a LDREX/STREX pair with no retry so it can fail spuriously (e.g. because of contention). FWIW the interpreter, C1, and Graal all implement weakCompare*() with a retry loop around LDREX/STREX so they never have spurious failures (i.e. it's the same as the strong variant). And C2 on machines with the LSE extension use the CAS instruction which also doesn't spuriously fail. So it's just C2-no-LSE that's the outlier.
18-02-2021

weakCAS is used only when there is a possible retry anyway. But I changed the only remaining case to plain CAS. Hopefully retesting will be informative.
18-02-2021

Martin: can you slip in updated ForkJoinPool.java to 8259800? If not, I can figure out how to create new PR. Also, while further trying to replicate, I discovered that the current github jtreg doesn't seem to even build on 17 (there is a note about this (Jan 23) on jtreg mailing list) so I can't replicate running test in apparently the same way that the CI does. Which could be related?
14-02-2021

Again, note that this failure is reported to occur only with parallelism 0, so no within-pool concurrency. But one theory is that a CAS somewhere that is statically "known" not to fail with parallelism 0 somehow does anyway. I added handling for another case of this.
12-02-2021

Machine config was given above. Unfortunately there is no way to provide access (I can't even directly access). I will look into running jcstress, but am about to disappear for a week's vacation.
10-02-2021

I'm guessing the failing machines have more aggressive concurrency hardware (more processors, weaker atomic ops) that exposes a JDK bug. Or it might be the hardware itself is buggy. Another obvious thing to try on these machines is jcstress. I never run that myself.
10-02-2021

Yes, I've tried variations of this tens of thousands of times without seeing a failure.
09-02-2021

We now have a draft PR. https://github.com/openjdk/jdk/pull/2387 Neither Doug nor I have seen this failure yet - it would help if we could get temporary access to a failing machine. It is possible to run the single test repeatedly, thus: ``` $ cd test/jdk/java/util/concurrent/tck $ jtreg .... -Djsr166.tckTestClass=ForkJoinPool8Test -Djsr166.runsPerTest=1000 -Djsr166.methodFilter=testForkJoin . ``` It would be good to know if that is a more effective repro. Doug, you might try doing this inside a shell loop on a raspberry pi.
09-02-2021

I'll work on turning this into a PR.
03-02-2021

[~dl] Doug, if the fix is available as a patch I can patch a local repo and put it through testing. But as this didn't show up when I tried manually testing before that may not be very conclusive.
03-02-2021

I think I found problem, a case where it would try to create a spare thread even when parallelism zero. I committed fix (that also adds some harmlessly redundant checks) to jsr166. How can we re-test?
03-02-2021

Here's a new failure mode on Aarch64: ----------System.out:(0/0)---------- ----------System.err:(126/8194)---------- junit.framework.AssertionFailedError ------ stacktrace dump start ------ "main" prio=5 Id=1 WAITING on java.lang.Thread@1d6313bc at java.base@17-ea/java.lang.Object.wait(Native Method) - waiting on java.lang.Thread@1d6313bc at java.base@17-ea/java.lang.Thread.join(Thread.java:1301) at java.base@17-ea/java.lang.Thread.join(Thread.java:1369) at app//com.sun.javatest.regtest.agent.MainWrapper.main(MainWrapper.java:74) "Notification Thread" daemon prio=9 Id=12 RUNNABLE "MainThread" prio=5 Id=14 WAITING on RecursiveTaskTest$37@1cd674b3 at java.base@17-ea/jdk.internal.misc.Unsafe.park(Native Method) - waiting on RecursiveTaskTest$37@1cd674b3 at java.base@17-ea/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:327) at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitJoin(ForkJoinTask.java:511) at java.base@17-ea/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:667) at java.base@17-ea/java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:2596) at app//RecursiveTaskTest.testInvokeOnPool(RecursiveTaskTest.java:74) at app//RecursiveTaskTest.testTryUnfork(RecursiveTaskTest.java:910) ... "ForkJoinPool-196-worker-1" daemon prio=5 Id=560 RUNNABLE at java.management@17-ea/sun.management.ThreadImpl.dumpThreads0(Native Method) at java.management@17-ea/sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:521) at java.management@17-ea/sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:509) at app//JSR166TestCase.dumpTestThreads(JSR166TestCase.java:1179) at app//JSR166TestCase.threadRecordFailure(JSR166TestCase.java:810) at app//JSR166TestCase.threadUnexpectedException(JSR166TestCase.java:995) at app//JSR166TestCase$CheckedRecursiveTask.compute(JSR166TestCase.java:1903) at java.base@17-ea/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:100) ... ------ stacktrace dump end ------ junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:48) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertTrue(Assert.java:27) at RecursiveTaskTest$37.realCompute(RecursiveTaskTest.java:904) at RecursiveTaskTest$37.realCompute(RecursiveTaskTest.java:898) at JSR166TestCase$CheckedRecursiveTask.compute(JSR166TestCase.java:1901) at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:100) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:451) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1157) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1627) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) JavaTest Message: JUnit Failure: testTryUnfork(RecursiveTaskTest): null junit.framework.AssertionFailedError at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:498) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:479) at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:561) at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:588) at java.base/java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:669) at java.base/java.util.concurrent.ForkJoinPool.invoke(ForkJoinPool.java:2596) at RecursiveTaskTest.testInvokeOnPool(RecursiveTaskTest.java:74) at RecursiveTaskTest.testTryUnfork(RecursiveTaskTest.java:910) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at junit.framework.TestCase.runTest(TestCase.java:168) at JSR166TestCase.runTest(JSR166TestCase.java:380) at junit.framework.TestCase.runBare(TestCase.java:134) at JSR166TestCase.runBare(JSR166TestCase.java:371) at junit.framework.TestResult$1.protect(TestResult.java:110) at junit.framework.TestResult.runProtected(TestResult.java:128) at junit.framework.TestResult.run(TestResult.java:113) at junit.framework.TestCase.run(TestCase.java:124) at junit.framework.TestSuite.runTest(TestSuite.java:243) at junit.framework.TestSuite.run(TestSuite.java:238) at junit.framework.TestSuite.runTest(TestSuite.java:243) at junit.framework.TestSuite.run(TestSuite.java:238) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:24) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at org.junit.runner.JUnitCore.run(JUnitCore.java:136) at org.junit.runner.JUnitCore.run(JUnitCore.java:127) at org.junit.runner.JUnitCore.runClasses(JUnitCore.java:76) at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:76) at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:43) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127) at java.base/java.lang.Thread.run(Thread.java:831) Caused by: junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:48) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertTrue(Assert.java:27) at RecursiveTaskTest$37.realCompute(RecursiveTaskTest.java:904) at RecursiveTaskTest$37.realCompute(RecursiveTaskTest.java:898) at JSR166TestCase$CheckedRecursiveTask.compute(JSR166TestCase.java:1901) at java.base/java.util.concurrent.RecursiveTask.exec(RecursiveTask.java:100) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:451) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1157) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1627) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165) java.lang.Exception: JUnit test failure at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:92) at com.sun.javatest.regtest.agent.JUnitRunner.main(JUnitRunner.java:43) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127) at java.base/java.lang.Thread.run(Thread.java:831)
02-02-2021

Another example failure log extract: ----------System.out:(1/27)---------- Timeout refired 4000 times ----------System.err:(36/2441)---------- Looks like we're stuck running test: testQuietlyInvoke(ForkJoinPool8Test) ------ stacktrace dump start ------ "main" prio=5 Id=1 WAITING on java.lang.Thread@34799a5e at java.base@17-ea/java.lang.Object.wait(Native Method) - waiting on java.lang.Thread@34799a5e at java.base@17-ea/java.lang.Thread.join(Thread.java:1301) at java.base@17-ea/java.lang.Thread.join(Thread.java:1369) at app//com.sun.javatest.regtest.agent.MainWrapper.main(MainWrapper.java:74) "Notification Thread" daemon prio=9 Id=12 RUNNABLE "MainThread" prio=5 Id=14 WAITING on ForkJoinPool8Test$FibAction@7b83689a at java.base@17-ea/jdk.internal.misc.Unsafe.park(Native Method) - waiting on ForkJoinPool8Test$FibAction@7b83689a at java.base@17-ea/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341) at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitDone(ForkJoinTask.java:327) at java.base@17-ea/java.util.concurrent.ForkJoinTask.awaitJoin(ForkJoinTask.java:511) at java.base@17-ea/java.util.concurrent.ForkJoinTask.invokeAll(ForkJoinTask.java:718) at app//ForkJoinPool8Test$FibAction.realCompute(ForkJoinPool8Test.java:222) at app//JSR166TestCase$CheckedRecursiveAction.compute(JSR166TestCase.java:1770) at java.base@17-ea/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:194) ... "CompletableFutureDelayScheduler" daemon prio=5 Id=1914 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@3d0b6de at java.base@17-ea/jdk.internal.misc.Unsafe.park(Native Method) - waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@3d0b6de at java.base@17-ea/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252) at java.base@17-ea/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672) at java.base@17-ea/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182) at java.base@17-ea/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899) at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1061) at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1121) at java.base@17-ea/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ... ------ stacktrace dump end ------
02-02-2021

Hi Doug, [~dl] Our systems are virtualized 6 core, 48GB instances, running on: 1x Ampere eMAG CPU, 32x ARMv8 64-bit CPU cores at 3.3 GHz with Turbo, with 512GB RAM https://amperecomputing.com/wp-content/uploads/2019/04/Lenovo_ThinkSystem_HR350A_20190409.pdf Currently 5 VMs per server. Update: I was advised we are temporarily running 7 VMs per server so this could be a simple case of overloading the test machines. Update 2: I ran this through our test system a number of times and passing tests take well under 2 minutes to run. I don't think simple overloading would produce such a huge slowdown.
02-02-2021

I cannot replicate (on arm or x86). Could the reporter please provide more information about execution context (especially the processor)? Note that this version of this test does not involve Java-level concurrency since it sets Djava.util.concurrent.ForkJoinPool.common.parallelism=0, so it is unlikely a Java-level weak memory issue. With common pool parallelism==0, callers block only if they cannot find their tasks (if they do, find them, they run them). While exploring this, I noticed a case in which a retry to find task may be necessary (and will post an update), but I don't see how thia situation can arise in this test program (only when multiple submitters with parallelism 0, which is not strictly prohibited).
30-01-2021

Forkjoin Updates is most likely culprit
14-01-2021

Surely related to the recent jsr166 integration. This is our first aarch64 bug. It'd unsurprising for us to see because aarch64 is a weaker memory model than x86_64. We "should" have been testing on aarch64 for the past few years but have not been. It would help if jsr166 maintainers could get access to aarch64 machines. I have a long term plan to get personal raspberry pis for doing this sort of testing but it has not yet happened.
14-01-2021