1 /* 2 * Copyright (c) 2013 SAP SE. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 8007898 27 * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier(). 28 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest 29 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest 30 * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest 31 * @author Martin Doerr martin DOT doerr AT sap DOT com 32 * 33 * Run 3 times since the failure is intermittent. 34 */ 35 36 public class DekkerTest { 37 38 /* 39 Read After Write Test (basically a simple Dekker test with volatile variables) 40 Derived from the original jcstress test, available at: 41 http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/ 42 tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java 43 */ 44 45 static final int ITERATIONS = 1000000; 46 47 static class TestData { 48 public volatile int a; 49 public volatile int b; 50 } 51 52 static class ResultData { 53 public int a; 54 public int b; 55 } 56 57 TestData[] testDataArray; 58 ResultData[] results; 59 60 volatile boolean start; 61 62 public DekkerTest() { 63 testDataArray = new TestData[ITERATIONS]; 64 results = new ResultData[ITERATIONS]; 65 for (int i = 0; i < ITERATIONS; ++i) { 66 testDataArray[i] = new TestData(); 67 results[i] = new ResultData(); 68 } 69 start = false; 70 } 71 72 public void reset() { 73 for (int i = 0; i < ITERATIONS; ++i) { 74 testDataArray[i].a = 0; 75 testDataArray[i].b = 0; 76 results[i].a = 0; 77 results[i].b = 0; 78 } 79 start = false; 80 } 81 82 int actor1(TestData t) { 83 t.a = 1; 84 return t.b; 85 } 86 87 int actor2(TestData t) { 88 t.b = 1; 89 return t.a; 90 } 91 92 class Runner1 extends Thread { 93 public void run() { 94 do {} while (!start); 95 for (int i = 0; i < ITERATIONS; ++i) { 96 results[i].a = actor1(testDataArray[i]); 97 } 98 } 99 } 100 101 class Runner2 extends Thread { 102 public void run() { 103 do {} while (!start); 104 for (int i = 0; i < ITERATIONS; ++i) { 105 results[i].b = actor2(testDataArray[i]); 106 } 107 } 108 } 109 110 void testRunner() { 111 Thread thread1 = new Runner1(); 112 Thread thread2 = new Runner2(); 113 thread1.start(); 114 thread2.start(); 115 do {} while (!thread1.isAlive()); 116 do {} while (!thread2.isAlive()); 117 start = true; 118 Thread.yield(); 119 try { 120 thread1.join(); 121 thread2.join(); 122 } catch (InterruptedException e) { 123 System.out.println("interrupted!"); 124 System.exit(1); 125 } 126 } 127 128 boolean printResult() { 129 int[] count = new int[4]; 130 for (int i = 0; i < ITERATIONS; ++i) { 131 int event_kind = (results[i].a << 1) + results[i].b; 132 ++count[event_kind]; 133 } 134 if (count[0] == 0 && count[3] == 0) { 135 System.out.println("[not interesting]"); 136 return false; // not interesting 137 } 138 String error = (count[0] == 0) ? " ok" : " disallowed!"; 139 System.out.println("[0,0] " + count[0] + error); 140 System.out.println("[0,1] " + count[1]); 141 System.out.println("[1,0] " + count[2]); 142 System.out.println("[1,1] " + count[3]); 143 return (count[0] != 0); 144 } 145 146 public static void main(String args[]) { 147 DekkerTest test = new DekkerTest(); 148 final int runs = 30; 149 int failed = 0; 150 for (int c = 0; c < runs; ++c) { 151 test.testRunner(); 152 if (test.printResult()) { 153 failed++; 154 } 155 test.reset(); 156 } 157 if (failed > 0) { 158 throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS"); 159 } 160 System.out.println("PASSED."); 161 } 162 163 }