Re: (hypothetical? bogus?) TSAN failure reported in ForkJoinPool (JDK11 and "refresh" versions)

Thomas Krieger via Concurrency-interest <[email protected]> Fri, 17 Jul 2020 00:04:32 +0200 (CEST)
Newsgroups gmane.comp.java.jsr.166-concurrency
Message-ID <[email protected]>
In JDK 8 ForkJoinPool used getObjectVolatile to get tasks from the work queue array. 
See the method scan(WorkQueue w, int r) from the class ForkJoinPool:
U.getObjectVolatile(a, i))) != null &&

In JDK 11 ForkJoinPool uses getAcquire to get a task from the array
t = (ForkJoinTask<?>)QA.getAcquire(a, k = (cap - 1) & b);



>     On 16 July 2020 20:15 Chris Povirk via Concurrency-interest <[email protected]> wrote:
> 
> 
>     Additional info:
> 
>     We have  worked around https://github.com/google/guava/commit/da93601899485518956c211e81017833071838b9 the immediate TSAN failure.
> 
>     Unfortunately, I don't have a test case packed up for you to run. What I have is entangled with Google infrastructure (which is different from some JDK infrastructure Martin discussed last year https://bugs.openjdk.java.net/browse/JDK-8232642?focusedCommentId=14295054&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14295054 ).
> 
>     But here is the code I've been running and a TSAN failure report. (TSAN gives an error maybe about half the time I run the test.) The report comes from a run against the "refresh" ForkJoinPool.
> 
>     Again, the failure is a TSAN failure only: I haven't been able to see a stale value in practice, so my assertFalse check is always succeeding.
> 
>     package com.google.common;
> 
>     import static java.util.concurrent.TimeUnit.SECONDS;
>     import static org.junit.Assert.assertFalse;
> 
>     import java.util.concurrent.ForkJoinPool;
>     import org.junit.Test;
>     import org.junit.runner.RunWith;
>     import org.junit.runners.JUnit4;
> 
>     @RunWith(JUnit4.class)
>     public class ForkJoinPoolTsanTest {
>       @Test
>       public void testHandoff() throws Exception {
>         ForkJoinPool service = new ForkJoinPool();
>         boolean[] failed = new boolean[1];
>         for (int j = 0; j < 5; j++) {
>           service.execute(new Job(failed));
>         }
>         service.shutdown();
>         service.awaitTermination(10, SECONDS);
>         assertFalse(failed[0]);
>       }
> 
>       private static final class Job implements Runnable {
>         final boolean[] failed;
>         boolean b = true;
> 
>         Job(boolean[] failed) {
>           this.failed = failed;
>         }
> 
>         @Override
>         public void run() {
>           if (!b) {
>             failed[0] = true;
>           }
>         }
>       }
>     }
> 
>     Read of size 1 at 0x0000cf6f8d54 by thread T18:
>       #0 com.google.common.ForkJoinPoolTsanTest$Job.run()V ForkJoinPoolTsanTest.java:35
>       #1 java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec()Z ForkJoinTask.java:1341
>       #2 java.util.concurrent.ForkJoinTask.doExec()I ForkJoinTask.java:435
>       #3 java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Ljava/util/concurrent/ForkJoinTask;Ljava/util/concurrent/ForkJoinPool$WorkQueue;)V ForkJoinPool.java:1128
>       #4 java.util.concurrent.ForkJoinPool.scan(Ljava/util/concurrent/ForkJoinPool$WorkQueue;II)I ForkJoinPool.java:1598
>       #5 java.util.concurrent.ForkJoinPool.runWorker(Ljava/util/concurrent/ForkJoinPool$WorkQueue;)V ForkJoinPool.java:1565
>       #6 java.util.concurrent.ForkJoinWorkerThread.run()V ForkJoinWorkerThread.java:138
> 
>     Previous write of size 1 at 0x0000cf6f8d54 by thread T5:
>       #0 com.google.common.ForkJoinPoolTsanTest$Job.<init>([Z)V ForkJoinPoolTsanTest.java:27
>       #1 com.google.common.ForkJoinPoolTsanTest.testHandoff()V ForkJoinPoolTsanTest.java:18
> 
>     Thread T18 (tid=661, running) created by thread T5 at:
>       #0 pthread_create third_party/llvm/llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:965:3 (4766092b7397d478e6abfb6f139c4adc84ae7e74c64c75064c31eca5ef3d4346_02000308b290+0x36b82a)
>       #1 os::create_thread(Thread*, os::ThreadType, unsigned long) <null> (libjvm.so+0x1148e95)
>       #2 java.lang.Thread.start()V Thread.java:803
>       #3 java.util.concurrent.ForkJoinPool.createWorker()Z ForkJoinPool.java:1408
>       #4 java.util.concurrent.ForkJoinPool.signalWork()V ForkJoinPool.java:1531
>       #5 java.util.concurrent.ForkJoinPool.externalPush(Ljava/util/concurrent/ForkJoinTask;)V ForkJoinPool.java:2128
>       #6 java.util.concurrent.ForkJoinPool.externalSubmit(Ljava/util/concurrent/ForkJoinTask;)Ljava/util/concurrent/ForkJoinTask; ForkJoinPool.java:2143
>       #7 java.util.concurrent.ForkJoinPool.execute(Ljava/lang/Runnable;)V ForkJoinPool.java:2587
>       #8 com.google.common.ForkJoinPoolTsanTest.testHandoff()V ForkJoinPoolTsanTest.java:18
>     _______________________________________________
>     Concurrency-interest mailing list
>     [email protected]
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>

_______________________________________________
Concurrency-interest mailing list
[email protected]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest