[aarch64-port-dev ] RFR: Fix for jtreg test case TestIntAtomicCAS

Edward Nevill edward.nevill at linaro.org
Thu Dec 19 08:29:13 PST 2013


Hi,

The patch below fixes the failures I am seeing in the jtreg test case TestIntAtomicCAS with the C1 compiler.

The patch is based on the code from aarch64.ad

    Label retry_load, done;
    __ bind(retry_load);
    __ ldaxr(rscratch1, addr_reg);
    __ cmp(rscratch1, old_reg);
    __ br(Assembler::NE, done);
    // if we store+flush with no intervening write tmp will be zero
    __ stlxr(rscratch1, new_reg, addr_reg);
    __ cmpw(rscratch1, zr);       // cannot use cbzw as must set flag
    __ br(Assembler::EQ, done);
    // retry so we only ever return after a load fails to compare
    // ensures we don't return a stale value after a failed write.
    __ b(retry_load);
    __ bind(done);

whereas the equivalent code in C1 does

  Label nope;
  // flush and load exclusive from the memory location
  // and fail if it is not what we expect
  __ ldaxr(rscratch1, addr);
  __ cmp(rscratch1, cmpval);
  __ cset(rscratch1, Assembler::NE);
  __ br(Assembler::NE, nope);
  // if we store+flush with no intervening write rscratch1 wil be zero
  __ stlxr(rscratch1, newval, addr);
  __ bind(nope);

IE. it does not do the branch to retry_load, but just fails if the stlxr fails, so I have modified the C1 code in the patch below to replicate the C2 behavior.

Below is a much reduced reproducer of the test case. I have also added a 'loop until fail' so that the test will continue executing until it fails (this may take several minutes).

Ok to push this patch?
Ed.

---- CUT HERE -------
/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */
import java.util.concurrent.atomic.AtomicIntegerArray;

public class TestIntAtomicCAS {
  private static final int ARRLEN = 97;

  public static void main(String args[]) {
    int errn = test(false);
  }

  static int test(boolean test_only) {
    AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN);
    AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN);
    // Initialize

    int errn = 0;

 while (errn == 0) {
    // Initialize
    for (int i=0; i<ARRLEN; i++) {
      a1.set(i, -1);
      a2.set(i, -1);
    }
    // Test and verify results
    {
      test_ci(a1);
      for (int i=0; i<ARRLEN; i++) {
        errn += verify("test_ci: a1", i, a1.get(i), -123);
      }

    }
  }

      return errn;

  }

  static void test_ci(AtomicIntegerArray a) {
    for (int i = 0; i < ARRLEN; i+=1) {
      a.compareAndSet(i, -1, -123);
    }
  }

  static int verify(String text, int i, int elem, int val) {
    if (elem != val) {
      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
      return 1;
    }
    return 0;
  }
}
--- CUT HERE ----

And here is the patch

--- CUT HERE ---
# HG changeset patch
# User Edward Nevill edward.nevill at linaro.org
# Date 1387469288 0
#      Thu Dec 19 16:08:08 2013 +0000
# Node ID a1f632c91185437aaac51531a184cde461fd89b7
# Parent  8f7ab4f357559285bd7db4c20e35bd8853778cf5
Fix jtreg test case TestIntAtomicCAS

diff -r 8f7ab4f35755 -r a1f632c91185
src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Tue Dec 17 05:47:59
2013 -0500
+++ b/src/cpu/aarch64/vm/c1_LIRAssembler_aarch64.cpp	Thu Dec 19 16:08:08
2013 +0000
@@ -1567,28 +1567,36 @@
 }
 
 void LIR_Assembler::casw(Register addr, Register newval, Register
cmpval) {
-  Label nope;
+  Label retry_load, nope;
   // flush and load exclusive from the memory location
   // and fail if it is not what we expect
+  __ bind(retry_load);
   __ ldaxrw(rscratch1, addr);
   __ cmpw(rscratch1, cmpval);
   __ cset(rscratch1, Assembler::NE);
   __ br(Assembler::NE, nope);
   // if we store+flush with no intervening write rscratch1 wil be zero
   __ stlxrw(rscratch1, newval, addr);
+  // retry so we only ever return after a load fails to compare
+  // ensures we don't return a stale value after a failed write.
+  __ cbnz(rscratch1, retry_load);
   __ bind(nope);
 }
 
 void LIR_Assembler::casl(Register addr, Register newval, Register
cmpval) {
-  Label nope;
+  Label retry_load, nope;
   // flush and load exclusive from the memory location
   // and fail if it is not what we expect
+  __ bind(retry_load);
   __ ldaxr(rscratch1, addr);
   __ cmp(rscratch1, cmpval);
   __ cset(rscratch1, Assembler::NE);
   __ br(Assembler::NE, nope);
   // if we store+flush with no intervening write rscratch1 wil be zero
   __ stlxr(rscratch1, newval, addr);
+  // retry so we only ever return after a load fails to compare
+  // ensures we don't return a stale value after a failed write.
+  __ cbnz(rscratch1, retry_load);
   __ bind(nope);
 }
 
--- CUT HERE ---





More information about the aarch64-port-dev mailing list