changeset 417:64f2cf32fa0a

7902110: jcstress should cap the stride sizes by time spent in sanity tests
author shade
date Fri, 26 Jan 2018 18:57:29 +0100
parents 32d7d4da95be
children ff7cf32e6950
files jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TestConfig.java
diffstat 1 files changed, 42 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TestConfig.java	Thu Jan 25 12:35:51 2018 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/TestConfig.java	Fri Jan 26 18:57:29 2018 +0100
@@ -30,6 +30,7 @@
 
 import java.io.Serializable;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 
 public class TestConfig implements Serializable {
@@ -48,12 +49,19 @@
     public final int maxFootprintMB;
     public int minStride;
     public int maxStride;
+    public StrideCap strideCap;
 
     public enum RunMode {
         EMBEDDED,
         FORKED,
     }
 
+    public enum StrideCap {
+        NONE,
+        FOOTPRINT,
+        TIME,
+    }
+
     public TestConfig(Options opts, TestInfo info, RunMode runMode, int forkId, List<String> jvmArgs) {
         this.runMode = runMode;
         this.forkId = forkId;
@@ -69,23 +77,16 @@
         threads = info.threads();
         name = info.name();
         generatedRunnerName = info.generatedRunner();
+        strideCap = StrideCap.NONE;
     }
 
     public void adjustStrides(Consumer<Integer> tryAllocate) {
         int count = 1;
         int succCount = count;
         while (true) {
-            long start = AllocProfileSupport.getAllocatedBytes();
-            try {
-                tryAllocate.accept(count);
-                long footprint = AllocProfileSupport.getAllocatedBytes() - start;
-
-                if (footprint > maxFootprintMB * 1024 * 1024) {
-                    // blown the footprint estimate
-                    break;
-                }
-            } catch (OutOfMemoryError err) {
-                // blown the heap size
+            StrideCap cap = tryWith(tryAllocate, count);
+            if (cap != StrideCap.NONE) {
+                strideCap = cap;
                 break;
             }
 
@@ -105,6 +106,34 @@
         minStride = Math.min(minStride, succCount);
     }
 
+    private StrideCap tryWith(Consumer<Integer> tryAllocate, int count) {
+        final int TRIES = 10;
+        for (int tries = 0; tries < TRIES; tries++) {
+            long startFoot = AllocProfileSupport.getAllocatedBytes();
+            long startTime = System.nanoTime();
+            try {
+                tryAllocate.accept(count);
+                long usedTime = System.nanoTime() - startTime;
+                long footprint = AllocProfileSupport.getAllocatedBytes() - startFoot;
+
+                if (footprint > maxFootprintMB * 1024 * 1024) {
+                    // blown the footprint estimate
+                    return StrideCap.FOOTPRINT;
+                }
+
+                if (TimeUnit.NANOSECONDS.toMillis(usedTime) > time) {
+                    // blown the time estimate
+                    return StrideCap.TIME;
+                }
+
+            } catch (OutOfMemoryError err) {
+                // blown the heap size
+                return StrideCap.FOOTPRINT;
+            }
+        }
+        return StrideCap.NONE;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -144,6 +173,7 @@
     public String toString() {
         return "JVM options: " + jvmArgs + "\n" +
                 "Iterations: " + iters + "\n" +
-                "Time: " + time;
+                "Time: " + time + "\n" +
+                "Stride: [" + minStride + ", " + maxStride + "] (capped by " + strideCap + ")";
     }
 }