1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Field; 18*795d594fSAndroid Build Coastguard Worker import java.util.concurrent.atomic.AtomicBoolean; 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker import sun.misc.Unsafe; 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker /** 23*795d594fSAndroid Build Coastguard Worker * Checker test on the 1.8 unsafe operations. Note, this is by no means an 24*795d594fSAndroid Build Coastguard Worker * exhaustive unit test for these CAS (compare-and-swap) and fence operations. 25*795d594fSAndroid Build Coastguard Worker * Instead, this test ensures the methods are recognized as intrinsic and behave 26*795d594fSAndroid Build Coastguard Worker * as expected. 27*795d594fSAndroid Build Coastguard Worker */ 28*795d594fSAndroid Build Coastguard Worker public class Main { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker private static final Unsafe unsafe = getUnsafe(); 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker private static Thread[] sThreads = new Thread[10]; 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker // 35*795d594fSAndroid Build Coastguard Worker // Fields accessed by setters and adders, and by memory fence tests. 36*795d594fSAndroid Build Coastguard Worker // 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker public int i = 0; 39*795d594fSAndroid Build Coastguard Worker public long l = 0; 40*795d594fSAndroid Build Coastguard Worker public Object o = null; 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker public int x_value; 43*795d594fSAndroid Build Coastguard Worker public int y_value; 44*795d594fSAndroid Build Coastguard Worker public volatile boolean running; 45*795d594fSAndroid Build Coastguard Worker 46*795d594fSAndroid Build Coastguard Worker // 47*795d594fSAndroid Build Coastguard Worker // Setters. 48*795d594fSAndroid Build Coastguard Worker // 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.set32(java.lang.Object, long, int) builder (after) 51*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeVirtual intrinsic:UnsafeGetAndSetInt 52*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] set32(Object o, long offset, int newValue)53*795d594fSAndroid Build Coastguard Worker private static int set32(Object o, long offset, int newValue) { 54*795d594fSAndroid Build Coastguard Worker return unsafe.getAndSetInt(o, offset, newValue); 55*795d594fSAndroid Build Coastguard Worker } 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.set64(java.lang.Object, long, long) builder (after) 58*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:j\d+>> InvokeVirtual intrinsic:UnsafeGetAndSetLong 59*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] set64(Object o, long offset, long newValue)60*795d594fSAndroid Build Coastguard Worker private static long set64(Object o, long offset, long newValue) { 61*795d594fSAndroid Build Coastguard Worker return unsafe.getAndSetLong(o, offset, newValue); 62*795d594fSAndroid Build Coastguard Worker } 63*795d594fSAndroid Build Coastguard Worker 64*795d594fSAndroid Build Coastguard Worker /// CHECK-START: java.lang.Object Main.setObj(java.lang.Object, long, java.lang.Object) builder (after) 65*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:l\d+>> InvokeVirtual intrinsic:UnsafeGetAndSetObject 66*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] setObj(Object o, long offset, Object newValue)67*795d594fSAndroid Build Coastguard Worker private static Object setObj(Object o, long offset, Object newValue) { 68*795d594fSAndroid Build Coastguard Worker return unsafe.getAndSetObject(o, offset, newValue); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker // 72*795d594fSAndroid Build Coastguard Worker // Adders. 73*795d594fSAndroid Build Coastguard Worker // 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker /// CHECK-START: int Main.add32(java.lang.Object, long, int) builder (after) 76*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:i\d+>> InvokeVirtual intrinsic:UnsafeGetAndAddInt 77*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] add32(Object o, long offset, int delta)78*795d594fSAndroid Build Coastguard Worker private static int add32(Object o, long offset, int delta) { 79*795d594fSAndroid Build Coastguard Worker return unsafe.getAndAddInt(o, offset, delta); 80*795d594fSAndroid Build Coastguard Worker } 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker /// CHECK-START: long Main.add64(java.lang.Object, long, long) builder (after) 83*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: <<Result:j\d+>> InvokeVirtual intrinsic:UnsafeGetAndAddLong 84*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: Return [<<Result>>] add64(Object o, long offset, long delta)85*795d594fSAndroid Build Coastguard Worker private static long add64(Object o, long offset, long delta) { 86*795d594fSAndroid Build Coastguard Worker return unsafe.getAndAddLong(o, offset, delta); 87*795d594fSAndroid Build Coastguard Worker } 88*795d594fSAndroid Build Coastguard Worker 89*795d594fSAndroid Build Coastguard Worker // 90*795d594fSAndroid Build Coastguard Worker // Fences (native). 91*795d594fSAndroid Build Coastguard Worker // 92*795d594fSAndroid Build Coastguard Worker 93*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.load() builder (after) 94*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual 95*795d594fSAndroid Build Coastguard Worker // 96*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.load() builder (after) 97*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: MemoryBarrier kind:LoadAny load()98*795d594fSAndroid Build Coastguard Worker private static void load() { 99*795d594fSAndroid Build Coastguard Worker unsafe.loadFence(); 100*795d594fSAndroid Build Coastguard Worker } 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.store() builder (after) 103*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual 104*795d594fSAndroid Build Coastguard Worker // 105*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.store() builder (after) 106*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: MemoryBarrier kind:AnyStore store()107*795d594fSAndroid Build Coastguard Worker private static void store() { 108*795d594fSAndroid Build Coastguard Worker unsafe.storeFence(); 109*795d594fSAndroid Build Coastguard Worker } 110*795d594fSAndroid Build Coastguard Worker 111*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.full() builder (after) 112*795d594fSAndroid Build Coastguard Worker /// CHECK-NOT: InvokeVirtual 113*795d594fSAndroid Build Coastguard Worker // 114*795d594fSAndroid Build Coastguard Worker /// CHECK-START: void Main.full() builder (after) 115*795d594fSAndroid Build Coastguard Worker /// CHECK-DAG: MemoryBarrier kind:AnyAny full()116*795d594fSAndroid Build Coastguard Worker private static void full() { 117*795d594fSAndroid Build Coastguard Worker unsafe.fullFence(); 118*795d594fSAndroid Build Coastguard Worker } 119*795d594fSAndroid Build Coastguard Worker 120*795d594fSAndroid Build Coastguard Worker // 121*795d594fSAndroid Build Coastguard Worker // Thread fork/join. 122*795d594fSAndroid Build Coastguard Worker // 123*795d594fSAndroid Build Coastguard Worker fork(Runnable r)124*795d594fSAndroid Build Coastguard Worker private static void fork(Runnable r) { 125*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 126*795d594fSAndroid Build Coastguard Worker sThreads[i] = new Thread(r); 127*795d594fSAndroid Build Coastguard Worker } 128*795d594fSAndroid Build Coastguard Worker // Start the threads only after the full array has been written with new threads, 129*795d594fSAndroid Build Coastguard Worker // because one test relies on the contents of this array to be consistent. 130*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 131*795d594fSAndroid Build Coastguard Worker sThreads[i].start(); 132*795d594fSAndroid Build Coastguard Worker } 133*795d594fSAndroid Build Coastguard Worker } 134*795d594fSAndroid Build Coastguard Worker join()135*795d594fSAndroid Build Coastguard Worker private static void join() { 136*795d594fSAndroid Build Coastguard Worker try { 137*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) { 138*795d594fSAndroid Build Coastguard Worker sThreads[i].join(); 139*795d594fSAndroid Build Coastguard Worker } 140*795d594fSAndroid Build Coastguard Worker } catch (InterruptedException e) { 141*795d594fSAndroid Build Coastguard Worker throw new Error("Failed join: " + e); 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker } 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker // 146*795d594fSAndroid Build Coastguard Worker // Driver. 147*795d594fSAndroid Build Coastguard Worker // 148*795d594fSAndroid Build Coastguard Worker main(String[] args)149*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 150*795d594fSAndroid Build Coastguard Worker System.out.println("starting"); 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker final Main m = new Main(); 153*795d594fSAndroid Build Coastguard Worker 154*795d594fSAndroid Build Coastguard Worker // Get the offsets. 155*795d594fSAndroid Build Coastguard Worker 156*795d594fSAndroid Build Coastguard Worker final long intOffset, longOffset, objOffset; 157*795d594fSAndroid Build Coastguard Worker try { 158*795d594fSAndroid Build Coastguard Worker Field intField = Main.class.getDeclaredField("i"); 159*795d594fSAndroid Build Coastguard Worker Field longField = Main.class.getDeclaredField("l"); 160*795d594fSAndroid Build Coastguard Worker Field objField = Main.class.getDeclaredField("o"); 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker intOffset = unsafe.objectFieldOffset(intField); 163*795d594fSAndroid Build Coastguard Worker longOffset = unsafe.objectFieldOffset(longField); 164*795d594fSAndroid Build Coastguard Worker objOffset = unsafe.objectFieldOffset(objField); 165*795d594fSAndroid Build Coastguard Worker 166*795d594fSAndroid Build Coastguard Worker } catch (NoSuchFieldException e) { 167*795d594fSAndroid Build Coastguard Worker throw new Error("No offset: " + e); 168*795d594fSAndroid Build Coastguard Worker } 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker // Some checks on setters and adders within same thread. 171*795d594fSAndroid Build Coastguard Worker 172*795d594fSAndroid Build Coastguard Worker set32(m, intOffset, 3); 173*795d594fSAndroid Build Coastguard Worker expectEqual32(3, m.i); 174*795d594fSAndroid Build Coastguard Worker 175*795d594fSAndroid Build Coastguard Worker set64(m, longOffset, 7L); 176*795d594fSAndroid Build Coastguard Worker expectEqual64(7L, m.l); 177*795d594fSAndroid Build Coastguard Worker 178*795d594fSAndroid Build Coastguard Worker setObj(m, objOffset, m); 179*795d594fSAndroid Build Coastguard Worker expectEqualObj(m, m.o); 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker add32(m, intOffset, 11); 182*795d594fSAndroid Build Coastguard Worker expectEqual32(14, m.i); 183*795d594fSAndroid Build Coastguard Worker 184*795d594fSAndroid Build Coastguard Worker add64(m, longOffset, 13L); 185*795d594fSAndroid Build Coastguard Worker expectEqual64(20L, m.l); 186*795d594fSAndroid Build Coastguard Worker 187*795d594fSAndroid Build Coastguard Worker // Some checks on setters within different threads. 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 190*795d594fSAndroid Build Coastguard Worker public void run() { 191*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) 192*795d594fSAndroid Build Coastguard Worker set32(m, intOffset, i); 193*795d594fSAndroid Build Coastguard Worker } 194*795d594fSAndroid Build Coastguard Worker }); 195*795d594fSAndroid Build Coastguard Worker join(); 196*795d594fSAndroid Build Coastguard Worker expectEqual32(9, m.i); // one thread's last value wins 197*795d594fSAndroid Build Coastguard Worker 198*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 199*795d594fSAndroid Build Coastguard Worker public void run() { 200*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) 201*795d594fSAndroid Build Coastguard Worker set64(m, longOffset, (long) (100 + i)); 202*795d594fSAndroid Build Coastguard Worker } 203*795d594fSAndroid Build Coastguard Worker }); 204*795d594fSAndroid Build Coastguard Worker join(); 205*795d594fSAndroid Build Coastguard Worker expectEqual64(109L, m.l); // one thread's last value wins 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 208*795d594fSAndroid Build Coastguard Worker public void run() { 209*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) 210*795d594fSAndroid Build Coastguard Worker setObj(m, objOffset, sThreads[i]); 211*795d594fSAndroid Build Coastguard Worker } 212*795d594fSAndroid Build Coastguard Worker }); 213*795d594fSAndroid Build Coastguard Worker join(); 214*795d594fSAndroid Build Coastguard Worker expectEqualObj(sThreads[9], m.o); // one thread's last value wins 215*795d594fSAndroid Build Coastguard Worker 216*795d594fSAndroid Build Coastguard Worker // Some checks on adders within different threads. 217*795d594fSAndroid Build Coastguard Worker 218*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 219*795d594fSAndroid Build Coastguard Worker public void run() { 220*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) 221*795d594fSAndroid Build Coastguard Worker add32(m, intOffset, i + 1); 222*795d594fSAndroid Build Coastguard Worker } 223*795d594fSAndroid Build Coastguard Worker }); 224*795d594fSAndroid Build Coastguard Worker join(); 225*795d594fSAndroid Build Coastguard Worker expectEqual32(559, m.i); // all values accounted for 226*795d594fSAndroid Build Coastguard Worker 227*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 228*795d594fSAndroid Build Coastguard Worker public void run() { 229*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < 10; i++) 230*795d594fSAndroid Build Coastguard Worker add64(m, longOffset, (long) (i + 1)); 231*795d594fSAndroid Build Coastguard Worker } 232*795d594fSAndroid Build Coastguard Worker }); 233*795d594fSAndroid Build Coastguard Worker join(); 234*795d594fSAndroid Build Coastguard Worker expectEqual64(659L, m.l); // all values accounted for 235*795d594fSAndroid Build Coastguard Worker 236*795d594fSAndroid Build Coastguard Worker // Some checks on fences within same thread. Note that memory fences within one 237*795d594fSAndroid Build Coastguard Worker // thread make little sense, but the assertion ensures nothing bad happens. 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker m.i = -1; 240*795d594fSAndroid Build Coastguard Worker m.l = -2L; 241*795d594fSAndroid Build Coastguard Worker m.o = null; 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker load(); 244*795d594fSAndroid Build Coastguard Worker store(); 245*795d594fSAndroid Build Coastguard Worker full(); 246*795d594fSAndroid Build Coastguard Worker 247*795d594fSAndroid Build Coastguard Worker expectEqual32(-1, m.i); 248*795d594fSAndroid Build Coastguard Worker expectEqual64(-2L, m.l); 249*795d594fSAndroid Build Coastguard Worker expectEqualObj(null, m.o); 250*795d594fSAndroid Build Coastguard Worker 251*795d594fSAndroid Build Coastguard Worker // Some checks on full fence within different threads. We write the non-volatile m.l after 252*795d594fSAndroid Build Coastguard Worker // the fork(), which means there is no happens-before relation in the Java memory model 253*795d594fSAndroid Build Coastguard Worker // with respect to the read in the threads. This relation is enforced by the memory fences 254*795d594fSAndroid Build Coastguard Worker // and the weak-set() -> get() guard. Note that the guard semantics used here are actually 255*795d594fSAndroid Build Coastguard Worker // too strong and already enforce total memory visibility, but this test illustrates what 256*795d594fSAndroid Build Coastguard Worker // should still happen if Java had a true relaxed memory guard. 257*795d594fSAndroid Build Coastguard Worker 258*795d594fSAndroid Build Coastguard Worker final AtomicBoolean guard1 = new AtomicBoolean(); 259*795d594fSAndroid Build Coastguard Worker m.l = 0L; 260*795d594fSAndroid Build Coastguard Worker 261*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 262*795d594fSAndroid Build Coastguard Worker public void run() { 263*795d594fSAndroid Build Coastguard Worker while (!guard1.get()); // busy-waiting 264*795d594fSAndroid Build Coastguard Worker full(); 265*795d594fSAndroid Build Coastguard Worker expectEqual64(-123456789L, m.l); 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker }); 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker m.l = -123456789L; 270*795d594fSAndroid Build Coastguard Worker full(); 271*795d594fSAndroid Build Coastguard Worker while (!guard1.weakCompareAndSet(false, true)); // relaxed memory order 272*795d594fSAndroid Build Coastguard Worker join(); 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker // Some checks on release/acquire fences within different threads. We write the non-volatile 275*795d594fSAndroid Build Coastguard Worker // m.l after the fork(), which means there is no happens-before relation in the Java memory 276*795d594fSAndroid Build Coastguard Worker // model with respect to the read in the threads. This relation is enforced by the memory fences 277*795d594fSAndroid Build Coastguard Worker // and the weak-set() -> get() guard. Note that the guard semantics used here are actually 278*795d594fSAndroid Build Coastguard Worker // too strong and already enforce total memory visibility, but this test illustrates what 279*795d594fSAndroid Build Coastguard Worker // should still happen if Java had a true relaxed memory guard. 280*795d594fSAndroid Build Coastguard Worker 281*795d594fSAndroid Build Coastguard Worker final AtomicBoolean guard2 = new AtomicBoolean(); 282*795d594fSAndroid Build Coastguard Worker m.l = 0L; 283*795d594fSAndroid Build Coastguard Worker 284*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 285*795d594fSAndroid Build Coastguard Worker public void run() { 286*795d594fSAndroid Build Coastguard Worker while (!guard2.get()); // busy-waiting 287*795d594fSAndroid Build Coastguard Worker load(); 288*795d594fSAndroid Build Coastguard Worker expectEqual64(-987654321L, m.l); 289*795d594fSAndroid Build Coastguard Worker } 290*795d594fSAndroid Build Coastguard Worker }); 291*795d594fSAndroid Build Coastguard Worker 292*795d594fSAndroid Build Coastguard Worker m.l = -987654321L; 293*795d594fSAndroid Build Coastguard Worker store(); 294*795d594fSAndroid Build Coastguard Worker while (!guard2.weakCompareAndSet(false, true)); // relaxed memory order 295*795d594fSAndroid Build Coastguard Worker join(); 296*795d594fSAndroid Build Coastguard Worker 297*795d594fSAndroid Build Coastguard Worker // Some checks on release/acquire fences within different threads using a test suggested by 298*795d594fSAndroid Build Coastguard Worker // Hans Boehm. Even this test remains with the realm of soundness checking only, since having 299*795d594fSAndroid Build Coastguard Worker // the threads read the same value consistently would be a valid outcome. 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker m.x_value = -1; 302*795d594fSAndroid Build Coastguard Worker m.y_value = -1; 303*795d594fSAndroid Build Coastguard Worker m.running = true; 304*795d594fSAndroid Build Coastguard Worker 305*795d594fSAndroid Build Coastguard Worker fork(new Runnable() { 306*795d594fSAndroid Build Coastguard Worker public void run() { 307*795d594fSAndroid Build Coastguard Worker while (m.running) { 308*795d594fSAndroid Build Coastguard Worker for (int few_times = 0; few_times < 1000; few_times++) { 309*795d594fSAndroid Build Coastguard Worker // Read y first, then load fence, then read x. 310*795d594fSAndroid Build Coastguard Worker // They should appear in order, if seen at all. 311*795d594fSAndroid Build Coastguard Worker int local_y = m.y_value; 312*795d594fSAndroid Build Coastguard Worker load(); 313*795d594fSAndroid Build Coastguard Worker int local_x = m.x_value; 314*795d594fSAndroid Build Coastguard Worker expectLessThanOrEqual32(local_y, local_x); 315*795d594fSAndroid Build Coastguard Worker } 316*795d594fSAndroid Build Coastguard Worker } 317*795d594fSAndroid Build Coastguard Worker } 318*795d594fSAndroid Build Coastguard Worker }); 319*795d594fSAndroid Build Coastguard Worker 320*795d594fSAndroid Build Coastguard Worker for (int many_times = 0; many_times < 100000; many_times++) { 321*795d594fSAndroid Build Coastguard Worker m.x_value = many_times; 322*795d594fSAndroid Build Coastguard Worker store(); 323*795d594fSAndroid Build Coastguard Worker m.y_value = many_times; 324*795d594fSAndroid Build Coastguard Worker } 325*795d594fSAndroid Build Coastguard Worker m.running = false; 326*795d594fSAndroid Build Coastguard Worker join(); 327*795d594fSAndroid Build Coastguard Worker 328*795d594fSAndroid Build Coastguard Worker // All done! 329*795d594fSAndroid Build Coastguard Worker 330*795d594fSAndroid Build Coastguard Worker System.out.println("passed"); 331*795d594fSAndroid Build Coastguard Worker } 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker // Use reflection to implement "Unsafe.getUnsafe()"; getUnsafe()334*795d594fSAndroid Build Coastguard Worker private static Unsafe getUnsafe() { 335*795d594fSAndroid Build Coastguard Worker try { 336*795d594fSAndroid Build Coastguard Worker Class<?> unsafeClass = Unsafe.class; 337*795d594fSAndroid Build Coastguard Worker Field f = unsafeClass.getDeclaredField("theUnsafe"); 338*795d594fSAndroid Build Coastguard Worker f.setAccessible(true); 339*795d594fSAndroid Build Coastguard Worker return (Unsafe) f.get(null); 340*795d594fSAndroid Build Coastguard Worker } catch (Exception e) { 341*795d594fSAndroid Build Coastguard Worker throw new Error("Cannot get Unsafe instance"); 342*795d594fSAndroid Build Coastguard Worker } 343*795d594fSAndroid Build Coastguard Worker } 344*795d594fSAndroid Build Coastguard Worker expectEqual32(int expected, int result)345*795d594fSAndroid Build Coastguard Worker private static void expectEqual32(int expected, int result) { 346*795d594fSAndroid Build Coastguard Worker if (expected != result) { 347*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 348*795d594fSAndroid Build Coastguard Worker } 349*795d594fSAndroid Build Coastguard Worker } 350*795d594fSAndroid Build Coastguard Worker expectLessThanOrEqual32(int val1, int val2)351*795d594fSAndroid Build Coastguard Worker private static void expectLessThanOrEqual32(int val1, int val2) { 352*795d594fSAndroid Build Coastguard Worker if (val1 > val2) { 353*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + val1 + " <= " + val2); 354*795d594fSAndroid Build Coastguard Worker } 355*795d594fSAndroid Build Coastguard Worker } 356*795d594fSAndroid Build Coastguard Worker expectEqual64(long expected, long result)357*795d594fSAndroid Build Coastguard Worker private static void expectEqual64(long expected, long result) { 358*795d594fSAndroid Build Coastguard Worker if (expected != result) { 359*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 360*795d594fSAndroid Build Coastguard Worker } 361*795d594fSAndroid Build Coastguard Worker } 362*795d594fSAndroid Build Coastguard Worker expectEqualObj(Object expected, Object result)363*795d594fSAndroid Build Coastguard Worker private static void expectEqualObj(Object expected, Object result) { 364*795d594fSAndroid Build Coastguard Worker if (expected != result) { 365*795d594fSAndroid Build Coastguard Worker throw new Error("Expected: " + expected + ", found: " + result); 366*795d594fSAndroid Build Coastguard Worker } 367*795d594fSAndroid Build Coastguard Worker } 368*795d594fSAndroid Build Coastguard Worker } 369