changeset 73:e4bf3cd3108c

Re-phrase and format command line options.
author shade
date Mon, 03 Feb 2014 14:04:29 +0400
parents c0c94345c955
children e906859b74e6
files jcstress-core/src/main/java/org/openjdk/jcstress/Options.java jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java
diffstat 2 files changed, 147 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java	Fri Jan 24 22:01:08 2014 +0400
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java	Mon Feb 03 14:04:29 2014 +0400
@@ -28,6 +28,7 @@
 import joptsimple.OptionParser;
 import joptsimple.OptionSet;
 import joptsimple.OptionSpec;
+import org.openjdk.jcstress.util.OptionFormatter;
 
 import java.io.IOException;
 import java.io.PrintStream;
@@ -77,48 +78,55 @@
 
     public boolean parse() throws IOException {
         OptionParser parser = new OptionParser();
+        parser.formatHelpWith(new OptionFormatter());
 
-        OptionSpec<String> result = parser.accepts("r", "Destination to put the report into.")
+        OptionSpec<String> result = parser.accepts("r", "Target destination to put the report into.")
                 .withRequiredArg().ofType(String.class).describedAs("dir");
 
-        OptionSpec<String> parse = parser.accepts("p", "Re-run parser on the result file, skip running tests.")
-                .withOptionalArg().ofType(String.class);
+        OptionSpec<String> parse = parser.accepts("p", "Re-run parser on the result file. This will not run any tests.")
+                .withRequiredArg().ofType(String.class).describedAs("result file");
 
         OptionSpec<Boolean> list = parser.accepts("l", "List the available tests matching the requested settings.")
-                .withOptionalArg().ofType(Boolean.class);
+                .withOptionalArg().ofType(Boolean.class).describedAs("bool");
 
-        OptionSpec<String> testFilter = parser.accepts("t", "Regexp selector for tests")
+        OptionSpec<String> testFilter = parser.accepts("t", "Regexp selector for tests.")
                 .withRequiredArg().ofType(String.class).describedAs("regexp");
 
-        OptionSpec<Integer> minStride = parser.accepts("minStride", "Min internal stride size: balances the synchronization overhead vs. accuracy.")
+        OptionSpec<Integer> minStride = parser.accepts("minStride", "Minimum internal stride size. Larger value decreases " +
+                "the synchronization overhead, but also reduces accuracy.")
                 .withRequiredArg().ofType(Integer.class).describedAs("N");
 
-        OptionSpec<Integer> maxStride = parser.accepts("maxStride", "Max internal stride size: balances the synchronization overhead vs. accuracy.")
+        OptionSpec<Integer> maxStride = parser.accepts("maxStride", "Maximum internal stride size. Larger value decreases " +
+                "the synchronization overhead, but also reduces accuracy.")
                 .withRequiredArg().ofType(Integer.class).describedAs("N");
 
-        OptionSpec<Integer> time = parser.accepts("time", "Time per iteration.")
+        OptionSpec<Integer> time = parser.accepts("time", "Time to spend in single test iteration. Larger value improves " +
+                "test reliability, since schedulers do better job in the long run.")
                 .withRequiredArg().ofType(Integer.class).describedAs("ms");
 
         OptionSpec<Integer> iters = parser.accepts("iters", "Iterations per test.")
                 .withRequiredArg().ofType(Integer.class).describedAs("N");
 
-        OptionSpec<Integer> cpus = parser.accepts("c", "Number of CPUs to use. This value can exceed real CPU count.")
+        OptionSpec<Integer> cpus = parser.accepts("c", "Concurrency level for tests. This value can be greater " +
+                "than number of CPUs available.")
                 .withRequiredArg().ofType(Integer.class).describedAs("N");
 
-        OptionSpec<Integer> sysCpus = parser.accepts("sc", "Number of CPUs in the system. Overrides auto-detection.")
+        OptionSpec<Integer> sysCpus = parser.accepts("sc", "Number of CPUs in the system. Setting this value overrides " +
+                "the autodetection.")
                 .withRequiredArg().ofType(Integer.class).describedAs("N");
 
-        OptionSpec<Boolean> shouldYield = parser.accepts("yield", "Call Thread.yield() in busy-loops.")
-                .withOptionalArg().ofType(Boolean.class);
+        OptionSpec<Boolean> shouldYield = parser.accepts("yield", "Call Thread.yield() in busy loops.")
+                .withOptionalArg().ofType(Boolean.class).describedAs("bool");
 
-        OptionSpec<Integer> forks = parser.accepts("f", "Should fork each test N times. (\"0\" to run in the embedded mode, \"-1\" to never fork)")
-                .withOptionalArg().ofType(Integer.class);
+        OptionSpec<Integer> forks = parser.accepts("f", "Should fork each test N times. \"0\" to run in the embedded mode " +
+                "with occasional forking, \"-1\" to never ever fork.")
+                .withOptionalArg().ofType(Integer.class).describedAs("count");
 
-        OptionSpec<String> appendJvmArgs = parser.accepts("appendJvmArgs", "Append these arguments to the forked JVM.")
-                .withRequiredArg().ofType(String.class);
+        OptionSpec<String> appendJvmArgs = parser.accepts("jvmArgs", "Append these JVM arguments for the forked runs.")
+                .withRequiredArg().ofType(String.class).describedAs("opts");
 
-        OptionSpec<String> modeStr = parser.accepts("m", "Test mode preset (available options: sanity, quick, default, tough, stress)")
-                .withRequiredArg().ofType(String.class);
+        OptionSpec<String> modeStr = parser.accepts("m", "Test mode preset: sanity, quick, default, tough, stress.")
+                .withRequiredArg().ofType(String.class).describedAs("mode");
 
         OptionSpec<String> hostName = parser.accepts("hostName", "(internal) Host VM address")
                 .withRequiredArg().ofType(String.class);
@@ -126,8 +134,9 @@
         OptionSpec<Integer> hostPort = parser.accepts("hostPort", "(internal) Host VM port")
                 .withRequiredArg().ofType(Integer.class);
 
-        OptionSpec<Integer> deoptRatio = parser.accepts("deoptRatio", "Deoptimize (roughly) every N-th iteration")
-                .withRequiredArg().ofType(Integer.class);
+        OptionSpec<Integer> deoptRatio = parser.accepts("deoptRatio", "De-optimize (roughly) every N-th iteration. Larger " +
+                "value improves test performance, but decreases the chance we hit unlucky compilation.")
+                .withRequiredArg().ofType(Integer.class).describedAs("N");
 
         parser.accepts("v", "Be extra verbose.");
         parser.accepts("h", "Print this help.");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/OptionFormatter.java	Mon Feb 03 14:04:29 2014 +0400
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jcstress.util;
+
+import joptsimple.HelpFormatter;
+import joptsimple.OptionDescriptor;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+public class OptionFormatter implements HelpFormatter {
+
+    public String format(Map<String, ? extends OptionDescriptor> options) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Usage: java -jar jcstress.jar [options]");
+        sb.append("\n");
+        sb.append(" [opt] means optional argument.\n");
+        sb.append(" <opt> means required argument.\n");
+        sb.append(" \"+\" means comma-separated list of values.\n");
+        sb.append(" \"time\" arguments accept time suffixes, like \"100ms\".\n");
+        sb.append("\n");
+        for (OptionDescriptor each : options.values()) {
+            if (each.options().contains("hostName")) continue;
+            if (each.options().contains("hostPort")) continue;
+            sb.append(lineFor(each));
+        }
+
+        return sb.toString();
+    }
+
+    private Collection<String> rewrap(String lines) {
+        Collection<String> result = new ArrayList<String>();
+        String[] words = lines.split("[ \n]");
+        String line = "";
+        int cols = 0;
+        for (String w : words) {
+            if (cols + w.length() > 50) {
+                result.add(line);
+                line = w + " ";
+                cols = w.length();
+            } else {
+                cols += w.length();
+                line += w + " ";
+            }
+        }
+        result.add(line);
+        return result;
+    }
+
+    private String lineFor(OptionDescriptor d) {
+        StringBuilder line = new StringBuilder();
+
+        StringBuilder o = new StringBuilder();
+        o.append("  ");
+        for (String str : d.options()) {
+            if (!d.representsNonOptions()) {
+                o.append("-");
+            }
+            o.append(str);
+            if (d.acceptsArguments()) {
+                o.append(" ");
+                if (d.requiresArgument()) {
+                    o.append("<");
+                } else {
+                    o.append("[");
+                }
+                o.append(d.argumentDescription());
+                if (d.requiresArgument()) {
+                    o.append(">");
+                } else {
+                    o.append("]");
+                }
+            }
+        }
+
+        line.append(String.format("%-30s", o.toString()));
+        boolean first = true;
+        for (String l : rewrap(d.description())) {
+            if (first) {
+                first = false;
+            } else {
+                line.append("\n");
+                line.append(String.format("%-30s", ""));
+            }
+            if (!l.trim().isEmpty()) {
+                line.append(l);
+            }
+        }
+
+        line.append(System.getProperty("line.separator"));
+        line.append(System.getProperty("line.separator"));
+        return line.toString();
+    }
+
+}
\ No newline at end of file