[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