[aarch64-port-dev ] RFR: [8u] 8209835: Aarch64: elide barriers on all volatile operations

Yangfei (Felix) felix.yang at huawei.com
Fri Oct 11 03:41:07 UTC 2019


> On 8/28/19 11:39 AM, Yangfei (Felix) wrote:
> >> Having said that, I can sort-of imagine a jcstress failure if we had a test that
> was doing compareAndSwap in one thread and getAndSet in another. That
> would be a seriously compelling reason for a backport!
> > Can you elaborate more please? especially the possible code sequence.
> >
> > Currently, we have C2 JIT for getAndSet like this:
> >
> >  33   ;; membar_release
> >  34   0x0000ffffa416ae74: dmb       ish
> >  35   ;; 0x40000000000
> >  36   0x0000ffffa416ae78: orr       x11, xzr, #0x40000000000
> >  37   0x0000ffffa416ae7c: add       x10, x1, #0x10
> >  38   0x0000ffffa416ae80: prfm      pstl1strm, [x10]
> >  39   0x0000ffffa416ae84: ldxr      x9, [x10]
> >  40   0x0000ffffa416ae88: stxr      w8, x11, [x10]
> >  41   0x0000ffffa416ae8c: cbnz      w8, 0x0000ffffa416ae84
> >  42   0x0000ffffa416ae90: mov       x10, x9
> >  43   ;; membar_acquire
> >  44   0x0000ffffa416ae94: dmb       ishld           ;*invokevirtual
> getAndSetLong
> 
> The important thing is that there should be a StoreLoad barrier between a
> volatile store and a volatile load. If we have a getAndSet followed by a
> CompareAndExchange that might not happen.
> 

Hi, 

  Sorry for the late reply.  
  After some searching in jcstress code, I think the following test might be the test you wanted to see. 

  org.openjdk.jcstress.tests.atomics.longs.AtomicLongArrayPairwiseTests.GetAndSet_CAS

 43     @State
 44     public static class S {
 45         public final int SIZE = 256; // double the maximum cache line
 46         public final AtomicLongArray a = new AtomicLongArray(SIZE);
 47         public final int idx = ThreadLocalRandom.current().nextInt(SIZE);
 48     }

445     @JCStressTest
446     @JCStressMeta(G.class)
447     @Outcome(id = "0, 10",  expect = Expect.ACCEPTABLE, desc = "T1 -> T2 execution")
448     @Outcome(id = "20, 20", expect = Expect.ACCEPTABLE, desc = "T2 -> T1 execution")
449     public static class GetAndSet_CAS {
450         @Actor public void actor1(S s, LongResult2 r) { r.r1 = s.a.getAndSet(s.idx, 5); }
451         @Actor public void actor2(S s, LongResult2 r) { r.r2 = s.a.compareAndSet(s.idx, 0, 20) ? 20 : 10; }
452     }

  AtomicLongArray.getAndSet calls unsafe.getAndSetLong and AtomicLongArray.compareAndSet calls compareAndSetRaw which calls unsafe.compareAndSwapLong. 
  For this test, one thread will do actor1 method. And another thread will do actor2 method concurrently. 

Thanks,
Felix


More information about the aarch64-port-dev mailing list