aoqi@0: /* aoqi@0: * Copyright 2013 SAP AG. All Rights Reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /** aoqi@0: * @test aoqi@0: * @bug 8007898 aoqi@0: * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier(). anoll@7308: * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest anoll@7308: * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest anoll@7308: * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest aoqi@0: * @author Martin Doerr martin DOT doerr AT sap DOT com aoqi@0: * aoqi@0: * Run 3 times since the failure is intermittent. aoqi@0: */ aoqi@0: aoqi@0: public class DekkerTest { aoqi@0: aoqi@0: /* aoqi@0: Read After Write Test (basically a simple Dekker test with volatile variables) aoqi@0: Derived from the original jcstress test, available at: aoqi@0: http://hg.openjdk.java.net/code-tools/jcstress/file/6c339a5aa00d/ aoqi@0: tests-custom/src/main/java/org/openjdk/jcstress/tests/volatiles/DekkerTest.java aoqi@0: */ aoqi@0: aoqi@0: static final int ITERATIONS = 1000000; aoqi@0: aoqi@0: static class TestData { aoqi@0: public volatile int a; aoqi@0: public volatile int b; aoqi@0: } aoqi@0: aoqi@0: static class ResultData { aoqi@0: public int a; aoqi@0: public int b; aoqi@0: } aoqi@0: aoqi@0: TestData[] testDataArray; aoqi@0: ResultData[] results; aoqi@0: aoqi@0: volatile boolean start; aoqi@0: aoqi@0: public DekkerTest() { aoqi@0: testDataArray = new TestData[ITERATIONS]; aoqi@0: results = new ResultData[ITERATIONS]; aoqi@0: for (int i = 0; i < ITERATIONS; ++i) { aoqi@0: testDataArray[i] = new TestData(); aoqi@0: results[i] = new ResultData(); aoqi@0: } aoqi@0: start = false; aoqi@0: } aoqi@0: aoqi@0: public void reset() { aoqi@0: for (int i = 0; i < ITERATIONS; ++i) { aoqi@0: testDataArray[i].a = 0; aoqi@0: testDataArray[i].b = 0; aoqi@0: results[i].a = 0; aoqi@0: results[i].b = 0; aoqi@0: } aoqi@0: start = false; aoqi@0: } aoqi@0: aoqi@0: int actor1(TestData t) { aoqi@0: t.a = 1; aoqi@0: return t.b; aoqi@0: } aoqi@0: aoqi@0: int actor2(TestData t) { aoqi@0: t.b = 1; aoqi@0: return t.a; aoqi@0: } aoqi@0: aoqi@0: class Runner1 extends Thread { aoqi@0: public void run() { aoqi@0: do {} while (!start); aoqi@0: for (int i = 0; i < ITERATIONS; ++i) { aoqi@0: results[i].a = actor1(testDataArray[i]); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: class Runner2 extends Thread { aoqi@0: public void run() { aoqi@0: do {} while (!start); aoqi@0: for (int i = 0; i < ITERATIONS; ++i) { aoqi@0: results[i].b = actor2(testDataArray[i]); aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: void testRunner() { aoqi@0: Thread thread1 = new Runner1(); aoqi@0: Thread thread2 = new Runner2(); aoqi@0: thread1.start(); aoqi@0: thread2.start(); aoqi@0: do {} while (!thread1.isAlive()); aoqi@0: do {} while (!thread2.isAlive()); aoqi@0: start = true; aoqi@0: Thread.yield(); aoqi@0: try { aoqi@0: thread1.join(); aoqi@0: thread2.join(); aoqi@0: } catch (InterruptedException e) { aoqi@0: System.out.println("interrupted!"); aoqi@0: System.exit(1); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: boolean printResult() { aoqi@0: int[] count = new int[4]; aoqi@0: for (int i = 0; i < ITERATIONS; ++i) { aoqi@0: int event_kind = (results[i].a << 1) + results[i].b; aoqi@0: ++count[event_kind]; aoqi@0: } aoqi@0: if (count[0] == 0 && count[3] == 0) { aoqi@0: System.out.println("[not interesting]"); aoqi@0: return false; // not interesting aoqi@0: } aoqi@0: String error = (count[0] == 0) ? " ok" : " disallowed!"; aoqi@0: System.out.println("[0,0] " + count[0] + error); aoqi@0: System.out.println("[0,1] " + count[1]); aoqi@0: System.out.println("[1,0] " + count[2]); aoqi@0: System.out.println("[1,1] " + count[3]); aoqi@0: return (count[0] != 0); aoqi@0: } aoqi@0: aoqi@0: public static void main(String args[]) { aoqi@0: DekkerTest test = new DekkerTest(); aoqi@0: final int runs = 30; aoqi@0: int failed = 0; aoqi@0: for (int c = 0; c < runs; ++c) { aoqi@0: test.testRunner(); aoqi@0: if (test.printResult()) { aoqi@0: failed++; aoqi@0: } aoqi@0: test.reset(); aoqi@0: } aoqi@0: if (failed > 0) { aoqi@0: throw new InternalError("FAILED. Got " + failed + " failed ITERATIONS"); aoqi@0: } aoqi@0: System.out.println("PASSED."); aoqi@0: } aoqi@0: aoqi@0: }