changeset 1436:fbe1b55eadf8

7902088: External profilers should be called with before/afterTrial during warmup forks
author shade
date Thu, 21 Dec 2017 08:21:17 +0100
parents 335dfeac13dc
children a0c4f5e23278
files jmh-core-it/src/test/java/org/openjdk/jmh/it/profilers/CountingExternalProfiler.java jmh-core-it/src/test/java/org/openjdk/jmh/it/profilers/CountingExternalProfilerTest.java jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java
diffstat 3 files changed, 180 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core-it/src/test/java/org/openjdk/jmh/it/profilers/CountingExternalProfiler.java	Thu Dec 21 08:21:17 2017 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017, Red Hat Inc. 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.jmh.it.profilers;
+
+import org.openjdk.jmh.infra.BenchmarkParams;
+import org.openjdk.jmh.profile.ExternalProfiler;
+import org.openjdk.jmh.results.BenchmarkResult;
+import org.openjdk.jmh.results.Result;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CountingExternalProfiler implements ExternalProfiler {
+
+    static final AtomicInteger jvmOpts = new AtomicInteger();
+    static final AtomicInteger jvmInvokeOpts = new AtomicInteger();
+    static final AtomicInteger beforeTrial = new AtomicInteger();
+    static final AtomicInteger afterTrial = new AtomicInteger();
+
+    public static void reset() {
+        jvmOpts.set(0);
+        jvmInvokeOpts.set(0);
+        beforeTrial.set(0);
+        afterTrial.set(0);
+    }
+
+    @Override
+    public boolean allowPrintErr() {
+        return true;
+    }
+
+    @Override
+    public boolean allowPrintOut() {
+        return true;
+    }
+
+    @Override
+    public Collection<String> addJVMOptions(BenchmarkParams params) {
+        jvmOpts.incrementAndGet();
+        return Collections.emptyList();
+    }
+
+    @Override
+    public Collection<String> addJVMInvokeOptions(BenchmarkParams params) {
+        jvmInvokeOpts.incrementAndGet();
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void beforeTrial(BenchmarkParams benchmarkParams) {
+        beforeTrial.incrementAndGet();
+    }
+
+    @Override
+    public Collection<? extends Result> afterTrial(BenchmarkResult br, long pid, File stdOut, File stdErr) {
+        afterTrial.incrementAndGet();
+        return Collections.emptyList();
+    }
+
+    @Override
+    public String getDescription() {
+        return "Integration Test External Profiler with Stage Counting";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core-it/src/test/java/org/openjdk/jmh/it/profilers/CountingExternalProfilerTest.java	Thu Dec 21 08:21:17 2017 +0100
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017, Red Hat Inc. 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.jmh.it.profilers;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.it.Fixtures;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+import java.util.concurrent.TimeUnit;
+
+public class CountingExternalProfilerTest {
+
+    @Benchmark
+    @Warmup(iterations = 0)
+    @Measurement(iterations = 1, time = 1, timeUnit = TimeUnit.MILLISECONDS)
+    @Fork(1)
+    public void bench() {
+      // intentionally left blank
+    }
+
+    @Test
+    public void test() throws RunnerException {
+        for (int warmupForks : new int[]{0, 1, 5}) {
+            for (int forks : new int[]{1, 5}) {
+                CountingExternalProfiler.reset();
+
+                Options opts = new OptionsBuilder()
+                        .include(Fixtures.getTestMask(this.getClass()))
+                        .addProfiler(CountingExternalProfiler.class)
+                        .forks(forks)
+                        .warmupForks(warmupForks)
+                        .build();
+                new Runner(opts).run();
+
+                Assert.assertEquals("jvmOpts count is correct for warmupForks = " + warmupForks + ", and forks = " + forks,
+                        warmupForks + forks, CountingExternalProfiler.jvmOpts.get());
+                Assert.assertEquals("jvmInvokeOpts count is correct for warmupForks = " + warmupForks + ", and forks = " + forks,
+                        warmupForks + forks, CountingExternalProfiler.jvmInvokeOpts.get());
+                Assert.assertEquals("afterTrial count is correct for warmupForks = " + warmupForks + ", and forks = " + forks,
+                        warmupForks + forks, CountingExternalProfiler.afterTrial.get());
+                Assert.assertEquals("beforeTrial count is correct for warmupForks = " + warmupForks + ", and forks = " + forks,
+                        warmupForks + forks, CountingExternalProfiler.beforeTrial.get());
+            }
+        }
+    }
+
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Wed Dec 20 20:47:59 2017 +0100
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Thu Dec 21 08:21:17 2017 +0100
@@ -619,34 +619,21 @@
 
             int forkCount = params.getForks();
             int warmupForkCount = params.getWarmupForks();
-            if (warmupForkCount > 0) {
-                for (int i = 0; i < warmupForkCount; i++) {
-                    List<String> forkedString  = getForkedMainCommand(params, profilers, server.getHost(), server.getPort());
-                    out.verbosePrintln("Warmup forking using command: " + forkedString);
+            int totalForks = warmupForkCount + forkCount;
 
-                    etaBeforeBenchmark();
-                    out.println("# Warmup Fork: " + (i + 1) + " of " + warmupForkCount);
-
-                    TempFile stdErr = FileUtils.weakTempFile("stderr");
-                    TempFile stdOut = FileUtils.weakTempFile("stdout");
-
-                    doFork(server, forkedString, stdOut.file(), stdErr.file(), printOut, printErr);
-
-                    etaAfterBenchmark(params);
-                    out.println("");
-
-                    // we know these are not needed anymore, proactively delete
-                    stdErr.delete();
-                    stdOut.delete();
-                }
-            }
-
-            for (int i = 0; i < forkCount; i++) {
+            for (int i = 0; i < totalForks; i++) {
+                boolean warmupFork = (i < warmupForkCount);
                 List<String> forkedString  = getForkedMainCommand(params, profilers, server.getHost(), server.getPort());
-                out.verbosePrintln("Forking using command: " + forkedString);
 
                 etaBeforeBenchmark();
-                out.println("# Fork: " + (i + 1) + " of " + forkCount);
+
+                if (warmupFork) {
+                    out.verbosePrintln("Warmup forking using command: " + forkedString);
+                    out.println("# Warmup Fork: " + (i + 1) + " of " + warmupForkCount);
+                } else {
+                    out.verbosePrintln("Forking using command: " + forkedString);
+                    out.println("# Fork: " + (i + 1 - warmupForkCount) + " of " + forkCount);
+                }
 
                 TempFile stdErr = FileUtils.weakTempFile("stderr");
                 TempFile stdOut = FileUtils.weakTempFile("stdout");
@@ -691,7 +678,9 @@
                         out.println("");
                     }
 
-                    results.put(params, br);
+                    if (!warmupFork) {
+                        results.put(params, br);
+                    }
                 }
 
                 etaAfterBenchmark(params);