changeset 86:b830f2a55505

Yak shaving: move the common parts to Runner.
author shade
date Thu, 13 Mar 2014 00:53:26 +0400
parents ea405a8caf24
children 78069b93a3e4
files jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor1_Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Arbiter1_Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor3_Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor4_Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TerminationRunner.java
diffstat 7 files changed, 172 insertions(+), 285 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor1_Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor1_Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -46,64 +46,21 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class Actor1_Runner<S, R extends Result> extends Runner {
+public class Actor1_Runner<S, R extends Result> extends Runner<R> {
     private final Actor1_Test<S, R> test;
     private final String testName;
 
     public Actor1_Runner(Options opts, Actor1_Test<S, R> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
 
-    /**
-     * Run the test.
-     * This method blocks until test is complete
-     */
-    public void run() {
-        testLog.println("Running " + testName);
-
-        try {
-            R res1 = test.newResult();
-            S state = test.newState();
-            test.actor1(state, res1);
-        } catch (NoClassDefFoundError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH, e);
-            return;
-        } catch (NoSuchFieldError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH, e);
-            return;
-        } catch (NoSuchMethodError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH, e);
-            return;
-        } catch (Throwable e) {
-            testLog.println("Check test failed");
-            testLog.println();
-            dumpFailure(testName, Status.CHECK_TEST_ERROR, e);
-            return;
-        }
-
-        testLog.print("Iterations ");
-        for (int c = 0; c < control.iters; c++) {
-            try {
-                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
-            } catch (NoClassDefFoundError err) {
-                // gracefully "handle"
-            }
-
-            testLog.print(".");
-            testLog.flush();
-            Counter<R> runResult = internalRun();
-
-            dump(testName, runResult);
-        }
-        testLog.println();
+    @Override
+    public void sanityCheck() throws Throwable {
+        R res1 = test.newResult();
+        S state = test.newState();
+        test.actor1(state, res1);
     }
 
     @Override
@@ -111,8 +68,8 @@
         return 1;
     }
 
-
-    private Counter<R> internalRun() {
+    @Override
+    public Counter<R> internalRun() {
         @SuppressWarnings("unchecked")
         final S[] poison = (S[]) new Object[0];
 
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Arbiter1_Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Arbiter1_Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -46,63 +46,23 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class Actor2_Arbiter1_Runner<S, R extends Result> extends Runner {
+public class Actor2_Arbiter1_Runner<S, R extends Result> extends Runner<R> {
     private final Actor2_Arbiter1_Test<S, R> test;
     private final String testName;
 
     public Actor2_Arbiter1_Runner(Options opts, Actor2_Arbiter1_Test<S, R> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
 
-    public void run() {
-        testLog.println("Running " + testName);
-
-        try {
-            R res = test.newResult();
-            S state = test.newState();
-            test.actor1(state, res);
-            test.actor2(state, res);
-            test.arbiter1(state, res);
-        } catch (NoClassDefFoundError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchFieldError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchMethodError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (Throwable e) {
-            testLog.println("Check test failed");
-            testLog.println();
-            dumpFailure(testName, Status.CHECK_TEST_ERROR);
-            return;
-        }
-
-        testLog.print("Iterations ");
-        for (int c = 0; c < control.iters; c++) {
-            try {
-                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
-            } catch (NoClassDefFoundError err) {
-                // gracefully "handle"
-            }
-
-            testLog.print(".");
-            testLog.flush();
-            Counter<R> runResult = internalRun();
-
-            dump(testName, runResult);
-        }
-
-        testLog.println();
+    @Override
+    public void sanityCheck() throws Throwable {
+        R res = test.newResult();
+        S state = test.newState();
+        test.actor1(state, res);
+        test.actor2(state, res);
+        test.arbiter1(state, res);
     }
 
     @Override
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor2_Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -46,68 +46,23 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class Actor2_Runner<S, R extends Result> extends Runner {
+public class Actor2_Runner<S, R extends Result> extends Runner<R> {
     final Actor2_Test<S, R> test;
     final String testName;
 
     public Actor2_Runner(Options opts, Actor2_Test<S, R> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
 
-    /**
-     * Run the test.
-     * This method blocks until test is complete
-     *
-     */
-    public void run() {
-
-        testLog.println("Running " + testName);
-
-        try {
-            R res1 = test.newResult();
-            R res2 = test.newResult();
-            S state = test.newState();
-            test.actor1(state, res1);
-            test.actor2(state, res2);
-        } catch (NoClassDefFoundError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchFieldError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchMethodError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (Throwable e) {
-            testLog.println("Check test failed");
-            testLog.println();
-            dumpFailure(testName, Status.CHECK_TEST_ERROR);
-            return;
-        }
-
-        testLog.print("Iterations ");
-        for (int c = 0; c < control.iters; c++) {
-            try {
-                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
-            } catch (NoClassDefFoundError err) {
-                // gracefully "handle"
-            }
-
-            testLog.print(".");
-            testLog.flush();
-            Counter<R> runResult = run(control.time);
-
-            dump(testName, runResult);
-        }
-        testLog.println();
+    @Override
+    public void sanityCheck() throws Throwable {
+        R res1 = test.newResult();
+        R res2 = test.newResult();
+        S state = test.newState();
+        test.actor1(state, res1);
+        test.actor2(state, res2);
     }
 
     @Override
@@ -115,7 +70,8 @@
         return 2;
     }
 
-    private Counter<R> run(int time) {
+    @Override
+    public Counter<R> internalRun() {
 
         @SuppressWarnings("unchecked")
         final S[] poison = (S[]) new Object[0];
@@ -163,7 +119,7 @@
         ));
 
         try {
-            TimeUnit.MILLISECONDS.sleep(time);
+            TimeUnit.MILLISECONDS.sleep(control.time);
         } catch (InterruptedException e) {
             // do nothing
         }
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor3_Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor3_Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -46,68 +46,25 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class Actor3_Runner<S, R extends Result> extends Runner {
+public class Actor3_Runner<S, R extends Result> extends Runner<R> {
     final Actor3_Test<S, R> test;
     final String testName;
 
     public Actor3_Runner(Options opts, Actor3_Test<S, R> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
 
-    /**
-     * Run the test.
-     * This method blocks until test is complete
-     */
-    public void run() {
-        testLog.println("Running " + testName);
-
-        try {
-            R res1 = test.newResult();
-            R res2 = test.newResult();
-            R res3 = test.newResult();
-            S state = test.newState();
-            test.actor1(state, res1);
-            test.actor2(state, res2);
-            test.actor3(state, res3);
-        } catch (NoClassDefFoundError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchFieldError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchMethodError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (Throwable e) {
-            testLog.println("Check test failed");
-            testLog.println();
-            dumpFailure(testName, Status.CHECK_TEST_ERROR);
-            return;
-        }
-
-        testLog.print("Iterations ");
-        for (int c = 0; c < control.iters; c++) {
-            try {
-                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
-            } catch (NoClassDefFoundError err) {
-                // gracefully "handle"
-            }
-
-            testLog.print(".");
-            testLog.flush();
-            Counter<R> runResult = internalRun();
-
-            dump(testName, runResult);
-        }
-        testLog.println();
+    @Override
+    public void sanityCheck() throws Throwable {
+        R res1 = test.newResult();
+        R res2 = test.newResult();
+        R res3 = test.newResult();
+        S state = test.newState();
+        test.actor1(state, res1);
+        test.actor2(state, res2);
+        test.actor3(state, res3);
     }
 
     @Override
@@ -115,7 +72,8 @@
         return 3;
     }
 
-    private Counter<R> internalRun() {
+    @Override
+    public Counter<R> internalRun() {
 
         @SuppressWarnings("unchecked")
         final S[] poison = (S[]) new Object[0];
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor4_Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Actor4_Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -46,70 +46,27 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class Actor4_Runner<S, R extends Result> extends Runner {
+public class Actor4_Runner<S, R extends Result> extends Runner<R> {
     final Actor4_Test<S, R> test;
     final String testName;
 
     public Actor4_Runner(Options opts, Actor4_Test<S, R> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
 
-    /**
-     * Run the test.
-     * This method blocks until test is complete
-     */
-    public void run() {
-        testLog.println("Running " + testName);
-
-        try {
-            R res1 = test.newResult();
-            R res2 = test.newResult();
-            R res3 = test.newResult();
-            R res4 = test.newResult();
-            S state = test.newState();
-            test.actor1(state, res1);
-            test.actor2(state, res2);
-            test.actor3(state, res3);
-            test.actor4(state, res4);
-        } catch (NoClassDefFoundError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchFieldError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (NoSuchMethodError e) {
-            testLog.println("Test sanity check failed, skipping");
-            testLog.println();
-            dumpFailure(testName, Status.API_MISMATCH);
-            return;
-        } catch (Throwable e) {
-            testLog.println("Check test failed");
-            testLog.println();
-            dumpFailure(testName, Status.CHECK_TEST_ERROR);
-            return;
-        }
-
-        testLog.print("Iterations ");
-        for (int c = 0; c < control.iters; c++) {
-            try {
-                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
-            } catch (NoClassDefFoundError err) {
-                // gracefully "handle"
-            }
-
-            testLog.print(".");
-            testLog.flush();
-            Counter<R> runResult = internalRun();
-
-            dump(testName, runResult);
-        }
-        testLog.println();
+    @Override
+    public void sanityCheck() throws Throwable {
+        R res1 = test.newResult();
+        R res2 = test.newResult();
+        R res3 = test.newResult();
+        R res4 = test.newResult();
+        S state = test.newState();
+        test.actor1(state, res1);
+        test.actor2(state, res2);
+        test.actor3(state, res3);
+        test.actor4(state, res4);
     }
 
     @Override
@@ -117,7 +74,8 @@
         return 4;
     }
 
-    private Counter<R> internalRun() {
+    @Override
+    public Counter<R> internalRun() {
 
         @SuppressWarnings("unchecked")
         final S[] poison = (S[]) new Object[0];
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -25,11 +25,13 @@
 package org.openjdk.jcstress.infra.runners;
 
 import org.openjdk.jcstress.Options;
+import org.openjdk.jcstress.infra.Result;
 import org.openjdk.jcstress.infra.Status;
 import org.openjdk.jcstress.infra.collectors.TestResult;
 import org.openjdk.jcstress.infra.collectors.TestResultCollector;
 import org.openjdk.jcstress.util.Counter;
 import org.openjdk.jcstress.util.NullOutputStream;
+import org.openjdk.jcstress.util.VMSupport;
 
 import javax.xml.bind.JAXBException;
 import java.io.FileNotFoundException;
@@ -48,15 +50,17 @@
  *
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public abstract class Runner {
+public abstract class Runner<R extends Result> {
     protected final Control control;
     protected final TestResultCollector collector;
     protected final ExecutorService pool;
     protected final PrintWriter testLog;
+    protected final String testName;
 
-    public Runner(Options opts, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
+    public Runner(Options opts, TestResultCollector collector, ExecutorService pool, String testName) throws FileNotFoundException, JAXBException {
         this.collector = collector;
         this.pool = pool;
+        this.testName = testName;
         this.control = new Control(opts);
 
         if (control.verbose) {
@@ -69,6 +73,53 @@
         testLog.printf("Executing with %d threads\n", totalThreads);
     }
 
+    /**
+     * Run the test.
+     * This method blocks until test is complete
+     */
+    public void run() {
+        testLog.println("Running " + testName);
+
+        try {
+            sanityCheck();
+        } catch (NoClassDefFoundError e) {
+            testLog.println("Test sanity check failed, skipping");
+            testLog.println();
+            dumpFailure(testName, Status.API_MISMATCH, e);
+            return;
+        } catch (NoSuchFieldError e) {
+            testLog.println("Test sanity check failed, skipping");
+            testLog.println();
+            dumpFailure(testName, Status.API_MISMATCH, e);
+            return;
+        } catch (NoSuchMethodError e) {
+            testLog.println("Test sanity check failed, skipping");
+            testLog.println();
+            dumpFailure(testName, Status.API_MISMATCH, e);
+            return;
+        } catch (Throwable e) {
+            testLog.println("Check test failed");
+            testLog.println();
+            dumpFailure(testName, Status.CHECK_TEST_ERROR, e);
+            return;
+        }
+
+        testLog.print("Iterations ");
+        for (int c = 0; c < control.iters; c++) {
+            try {
+                VMSupport.tryDeoptimizeAllInfra(control.deoptRatio);
+            } catch (NoClassDefFoundError err) {
+                // gracefully "handle"
+            }
+
+            testLog.print(".");
+            testLog.flush();
+            dump(testName, internalRun());
+        }
+        testLog.println();
+    }
+
+
     protected void dumpFailure(String testName, Status status) {
         TestResult result = new TestResult(testName, status);
         collector.add(result);
@@ -84,7 +135,7 @@
         collector.add(result);
     }
 
-    protected <R> void dump(String testName, Counter<R> results) {
+    protected void dump(String testName, Counter<R> results) {
         TestResult result = new TestResult(testName, Status.NORMAL);
 
         for (R e : results.elementSet()) {
@@ -94,7 +145,9 @@
         collector.add(result);
     }
 
-    public abstract void run();
+    public abstract void sanityCheck() throws Throwable;
+
+    public abstract Counter<R> internalRun();
 
     public abstract int requiredThreads();
 
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TerminationRunner.java	Thu Mar 13 00:22:00 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TerminationRunner.java	Thu Mar 13 00:53:26 2014 +0400
@@ -25,6 +25,7 @@
 package org.openjdk.jcstress.infra.runners;
 
 import org.openjdk.jcstress.Options;
+import org.openjdk.jcstress.infra.Result;
 import org.openjdk.jcstress.infra.collectors.TestResultCollector;
 import org.openjdk.jcstress.tests.TerminationTest;
 import org.openjdk.jcstress.util.Counter;
@@ -39,12 +40,12 @@
 /**
  * @author Aleksey Shipilev (aleksey.shipilev@oracle.com)
  */
-public class TerminationRunner<S> extends Runner {
+public class TerminationRunner<S> extends Runner<TerminationRunner.OutcomeResult> {
     final TerminationTest<S> test;
     final String testName;
 
     public TerminationRunner(Options opts,  TerminationTest<S> test, TestResultCollector collector, ExecutorService pool) throws FileNotFoundException, JAXBException {
-        super(opts, collector, pool);
+        super(opts, collector, pool, test.getClass().getName());
         this.test = test;
         this.testName = test.getClass().getName();
     }
@@ -56,7 +57,7 @@
     public void run() {
         testLog.println("Running " + testName);
 
-        HashCounter<Outcome> results = new HashCounter<Outcome>();
+        Counter<OutcomeResult> results = new HashCounter<OutcomeResult>();
 
         testLog.print("Iterations ");
         for (int c = 0; c < control.iters; c++) {
@@ -72,7 +73,7 @@
 
             dump(testName, results);
 
-            if (results.count(Outcome.STALE) > 0) {
+            if (results.count(OutcomeResult.of(OutcomeResult.Outcome.STALE)) > 0) {
                 testLog.println("Have stale threads, forcing VM to exit");
                 testLog.flush();
                 testLog.close();
@@ -83,6 +84,16 @@
     }
 
     @Override
+    public void sanityCheck() throws Throwable {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Counter<OutcomeResult> internalRun() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public int requiredThreads() {
         return 2;
     }
@@ -93,13 +104,47 @@
         volatile boolean error;
     }
 
-    private enum Outcome {
-        TERMINATED,
-        STALE,
-        ERROR,
+    public static class OutcomeResult implements Result {
+        private Outcome outcome;
+
+        public OutcomeResult(Outcome outcome) {
+            this.outcome = outcome;
+        }
+
+        @Override
+        public void reset() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            OutcomeResult that = (OutcomeResult) o;
+
+            if (outcome != that.outcome) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            return outcome != null ? outcome.hashCode() : 0;
+        }
+
+        private enum Outcome {
+            TERMINATED,
+            STALE,
+            ERROR,
+        }
+
+        public static OutcomeResult of(Outcome outcome) {
+            return new OutcomeResult(outcome);
+        }
     }
 
-    private void run(Counter<Outcome> results) {
+    private void run(Counter<OutcomeResult> results) {
         long target = System.currentTimeMillis() + control.time;
         while (System.currentTimeMillis() < target) {
 
@@ -139,12 +184,12 @@
 
             if (holder.terminated) {
                 if (holder.error) {
-                    results.record(Outcome.ERROR);
+                    results.record(OutcomeResult.of(OutcomeResult.Outcome.ERROR));
                 } else {
-                    results.record(Outcome.TERMINATED);
+                    results.record(OutcomeResult.of(OutcomeResult.Outcome.TERMINATED));
                 }
             } else {
-                results.record(Outcome.STALE);
+                results.record(OutcomeResult.of(OutcomeResult.Outcome.STALE));
                 return;
             }
         }