changeset 5:b064dcacc1f0

generator: bind the first batch of volatile tests.
author shade
date Mon, 08 Jul 2013 18:23:29 +0400
parents 8b63b057274d
children 13ead0bffb25
files generator/src/main/java/org/openjdk/jcstress/tracer/TraceGen.java tests-generated/pom.xml
diffstat 2 files changed, 181 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/generator/src/main/java/org/openjdk/jcstress/tracer/TraceGen.java	Mon Jul 08 17:41:48 2013 +0400
+++ b/generator/src/main/java/org/openjdk/jcstress/tracer/TraceGen.java	Mon Jul 08 18:23:29 2013 +0400
@@ -26,7 +26,9 @@
 
 import org.openjdk.jcstress.generator.ResultGenerator;
 import org.openjdk.jcstress.generator.TestGenerator;
+import org.openjdk.jcstress.generator.Utils;
 
+import java.io.FileNotFoundException;
 import java.io.PrintWriter;
 import java.util.*;
 
@@ -36,6 +38,7 @@
     private final String srcDir;
     private final String resDir;
     private final ResultGenerator resultGenerator;
+    private PrintWriter resourceWriter;
 
     public TraceGen(int vars, String srcDir, String resDir) {
         this.vars = vars;
@@ -45,6 +48,13 @@
     }
 
     public void generate() {
+        try {
+            resourceWriter = new PrintWriter(Utils.ensureDir(resDir + "/org/openjdk/jcstress/desc/") + "/seqcst-volatiles.xml");
+        } catch (FileNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+        resourceWriter.println("<testsuite>");
+
         List<Op> possibleOps = new ArrayList<Op>();
         for (int v = 0; v < vars; v++) {
             for (Op.Type t : Op.Type.values()) {
@@ -91,35 +101,155 @@
 
         for (MultiTrace mt : multiTraces) {
             List<Trace> linearTraces = mt.linearize();
-            Set<Map<Integer, String>> resultSet = new HashSet<Map<Integer, String>>();
+            Set<Map<Integer, Integer>> resultSet = new HashSet<Map<Integer, Integer>>();
 
             for (Trace linear : linearTraces) {
-                Map<Integer, String> results = linear.interpret();
+                Map<Integer, Integer> results = linear.interpret();
                 resultSet.add(results);
             }
 
-            emit(mt, resultSet);
+            List<String> scResults = new ArrayList<String>();
+            for (Map<Integer, Integer> m : resultSet) {
+                List<String> mappedValues = new ArrayList<String>();
+                for (int v : m.values()) {
+                    mappedValues.add(mapConst(v));
+                }
+                scResults.add(mappedValues.toString());
+            }
+
+            emit(mt, scResults);
         }
+
+        resourceWriter.println("</testsuite>");
+        resourceWriter.close();
     }
 
-    private void emit(MultiTrace mt, Set<Map<Integer, String>> results) {
+    private int klassId = 0;
 
-        PrintWriter pw = new PrintWriter(System.out, true);
+    private void emit(MultiTrace mt, List<String> results) {
 
-        System.out.println("Processing " + mt);
-        for (Map<Integer, String> o : results) {
-            System.out.println(o);
+        final String pkg = "org.openjdk.jcstress.tests.seqconsistency.volatiles";
+
+        String pathname = Utils.ensureDir(srcDir + "/" + pkg.replaceAll("\\.", "/"));
+
+        String klass = "Auto" + klassId++;
+
+        resourceWriter.println("    <test name=\"" + pkg + "." + klass + "\">\n" +
+                "        <contributed-by>Aleksey Shipilev (aleksey.shipilev@oracle.com)</contributed-by>\n" +
+                "        <description>Generated test</description>\n");
+
+        for (String r : results) {
+                resourceWriter.println(
+                "        <case>\n" +
+                "            <match>" + r + "</match>\n" +
+                "            <expect>ACCEPTABLE</expect>\n" +
+                "            <description>Autogenerated match</description>\n" +
+                "        </case>\n"
+            );
         }
 
-        String resultName = resultGenerator.generateResult(new TestGenerator.Types(int.class));
+        resourceWriter.println(
+                "        <unmatched>\n" +
+                "            <expect>FORBIDDEN</expect>\n" +
+                "            <description>Other cases are not expected.</description>\n" +
+                "        </unmatched>\n" +
+                "    </test>");
+
+
+        Class[] klasses = new Class[mt.original.getLoadCount()];
+        for (int c = 0; c < klasses.length; c++) {
+            klasses[c] = int.class;
+        }
+
+        String resultName = resultGenerator.generateResult(new TestGenerator.Types(klasses));
+
+        PrintWriter pw = null;
+        try {
+            pw = new PrintWriter(pathname + "/" + klass + ".java");
+        } catch (FileNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+
+        pw.println("package " + pkg + ";\n" +
+                "\n" +
+                "import java.util.concurrent.*;\n" +
+                "import java.util.concurrent.atomic.*;\n" +
+                "import org.openjdk.jcstress.infra.results." + resultName + ";\n" +
+                "import org.openjdk.jcstress.tests.Actor2_Test;\n" +
+                "\n" +
+                "public class " + klass + " implements Actor2_Test<" + klass + ".State, " + resultName + "> {\n" +
+                "\n" +
+                "    @Override\n" +
+                "    public State newState() {\n" +
+                "        return new State();\n" +
+                "    }\n" +
+                "\n" +
+                "    @Override\n" +
+                "    public void actor1(State s, " + resultName + " r) {");
+
+        for (Op op : mt.traces.get(0).ops) {
+            switch (op.getType()) {
+                case LOAD:
+                    pw.println("        r.r" + (op.getResId() + 1) + " = s.x" + op.getVarId() + ";");
+                    break;
+                case STORE:
+                    pw.println("        s.x" + op.getVarId() + " = " + mapConst(op.getResId()) + ";");
+                    break;
+            }
+        }
+
+        pw.println(
+                "    }\n" +
+                        "\n" +
+                        "    @Override\n" +
+                        "    public void actor2(State s, " + resultName + " r) {");
+
+        for (Op op : mt.traces.get(1).ops) {
+            switch (op.getType()) {
+                case LOAD:
+                    pw.println("        r.r" + (op.getResId() + 1) + " = s.x" + op.getVarId() + ";");
+                    break;
+                case STORE:
+                    pw.println("        s.x" + op.getVarId() + " = " + mapConst(op.getResId()) + ";");
+                    break;
+            }
+        }
+
+        pw.println(
+                "    }\n" +
+                        "\n" +
+                        "    @Override\n" +
+                        "    public " + resultName + " newResult() {\n" +
+                        "        return new " + resultName + "();\n" +
+                        "    }\n" +
+                        "\n" +
+                        "    public static class State {");
+
+        Set<Integer> exist = new HashSet<Integer>();
+        for (Op op : mt.traces.get(0).ops) {
+            if (exist.add(op.getVarId()))
+                pw.println("        public volatile int x" + op.getVarId() + ";");
+        }
+        for (Op op : mt.traces.get(1).ops) {
+            if (exist.add(op.getVarId()))
+                pw.println("        public volatile int x" + op.getVarId() + ";");
+        }
+        pw.println("    }");
+        pw.println("}");
+
+        pw.close();
 
         System.out.println();
     }
 
+    private String mapConst(int resId) {
+        return String.valueOf(resId + 1);
+    }
+
     private MultiTrace split(Trace trace, int sentinel) {
         Trace left = trace.sub(0, sentinel);
         Trace right = trace.sub(sentinel, trace.getLength());
-        return new MultiTrace(left, right);
+        return new MultiTrace(trace, left, right);
     }
 
     private List<Trace> product(List<Trace> traces, List<Op> ops) {
@@ -169,22 +299,22 @@
             return nT;
         }
 
-        public SortedMap<Integer, String> interpret() {
-            Map<Integer, String> values = new HashMap<Integer, String>();
+        public SortedMap<Integer, Integer> interpret() {
+            Map<Integer, Integer> values = new HashMap<Integer, Integer>();
             for (int v = 0; v < vars; v++) {
-                values.put(v, "DEF");
+                values.put(v, -1);
             }
 
-            SortedMap<Integer, String> resValues = new TreeMap<Integer, String>();
+            SortedMap<Integer, Integer> resValues = new TreeMap<Integer, Integer>();
 
             for (Op op : ops) {
                 switch (op.getType()) {
                     case LOAD:
-                        String v = values.get(op.getVarId());
+                        int v = values.get(op.getVarId());
                         resValues.put(op.getResId(), v);
                         break;
                     case STORE:
-                        values.put(op.getVarId(), "C" + op.getResId());
+                        values.put(op.getVarId(), op.getResId());
                         break;
                     default:
                         throw new IllegalStateException();
@@ -214,16 +344,27 @@
             }
             return false;
         }
+
+        public int getLoadCount() {
+            int count = 0;
+            for (Op op : ops) {
+                if (op.getType() == Op.Type.LOAD) count++;
+            }
+            return count;
+        }
     }
 
     public class MultiTrace {
+        private final Trace original;
         private final List<Trace> traces;
 
-        public MultiTrace(Trace... traces) {
+        public MultiTrace(Trace original, Trace... traces) {
+            this.original = original;
             this.traces = Arrays.asList(traces);
         }
 
-        public MultiTrace(List<Trace> copy) {
+        public MultiTrace(Trace original, List<Trace> copy) {
+            this.original = original;
             this.traces = copy;
         }
 
@@ -241,7 +382,7 @@
                 Trace cT = copy.get(t);
                 if (cT.ops.isEmpty()) {
                     copy.remove(t);
-                    for (Trace trace : new MultiTrace(copy).linearize()) {
+                    for (Trace trace : new MultiTrace(original, copy).linearize()) {
                         newTraces.add(trace);
                     }
                 } else {
@@ -252,7 +393,7 @@
                         copy.remove(t);
                     }
 
-                    for (Trace trace : new MultiTrace(copy).linearize()) {
+                    for (Trace trace : new MultiTrace(original, copy).linearize()) {
                         newTraces.add(trace.pushHead(op));
                     }
                 }
--- a/tests-generated/pom.xml	Mon Jul 08 17:41:48 2013 +0400
+++ b/tests-generated/pom.xml	Mon Jul 08 18:23:29 2013 +0400
@@ -60,6 +60,7 @@
                 <version>1.2.1</version>
                 <executions>
                     <execution>
+                        <id>memeffects</id>
                         <goals>
                             <goal>exec</goal>
                         </goals>
@@ -77,6 +78,25 @@
                             </arguments>
                         </configuration>
                     </execution>
+                    <execution>
+                        <id>volatiles</id>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <phase>
+                            generate-sources
+                        </phase>
+                        <configuration>
+                            <!--<skip>true</skip>-->
+                            <executable>java</executable>
+                            <arguments>
+                                <argument>-jar</argument>
+                                <argument>../generator/target/volatile-tracegen.jar</argument>
+                                <argument>${project.build.directory}/generated-sources/tests/</argument>
+                                <argument>${project.build.directory}/generated-resources/</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
                 </executions>
             </plugin>
             <plugin>