1 /*
   2  * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @key stress gc randomness
  27  *
  28  * @summary converted from VM Testbase gc/memory/LargePagesTest.
  29  * VM Testbase keywords: [gc, stress, stressopt]
  30  *
  31  * @library /vmTestbase
  32  *          /test/lib
  33  * @run driver jdk.test.lib.FileInstaller . .
  34  * @run main/othervm gc.memory.LargePagesTest.LargePagesTest noThreads=5 duration=60
  35  */
  36 
  37 package gc.memory.LargePagesTest;
  38 
  39 import java.io.PrintStream;
  40 import nsk.share.test.LocalRandom;
  41 
  42 /*
  43  * Allocators purpose is to create pressure on the garbage collector
  44  * for a certain amount of time.
  45  * Note: this test moved from the "jr", the original name is func.vm.largepages.LargePagesTest
  46  */
  47 
  48 
  49 /**
  50  * @run main/othervm/timeout=150
  51  *      -XX:+UseLargePages
  52  *      -Xmx64m
  53  *      -Xms16m
  54  *      LargePagesTest
  55  *      noThreads=5 duration=60
  56  * @summary heap shrink/grow test
  57  */
  58 final public class LargePagesTest extends Thread {
  59 
  60     private static int cnt;
  61     private static final int SMALL_OBJECT_ALLOCATER = 1;
  62     private static final int LARGE_OBJECT_ALLOCATER = 2;
  63     private static final int ANY_OBJECT_ALLOCATER = 3;
  64     private static final int ANY_NO_MULTIARRAYS_ALLOCATER = 4;
  65     private int myType;
  66 
  67     /** Dummy thingies to update. */
  68     public LargePagesTest.Dummy[] d0;
  69     /** Dummy thingies to update. */
  70     public LargePagesTest.Dummy[] d1;
  71     /** Dummy thingies to update. */
  72     public LargePagesTest.Dummy[][] d2;
  73     /** Dummy thingies to update. */
  74     public LargePagesTest.Dummy[][] d3;
  75     /** Dummy thingies to update. */
  76     public LargePagesTest.Dummy[][][] d4;
  77     /** Dummy thingies to update. */
  78     public LargePagesTest.Dummy d5;
  79 
  80     /** Time to run execute(). */
  81     private long duration;
  82 
  83     /** Boolean of progress should be printed. */
  84     private boolean verbose;
  85 
  86     private static int noThreads = 5;
  87 
  88     /** Iterations. */
  89     public long iterations = 0L;
  90 
  91     /** Result. */
  92     public boolean result = false;
  93 
  94     private PrintStream out;
  95 
  96     /**
  97      * Creates DurAllocator.
  98      * @param name Parameter
  99      * @param duration Parameter
 100      * @param out Parameter
 101      * @param verbose Parameter
 102      */
 103     LargePagesTest(String name, long duration, PrintStream out, boolean verbose) {
 104 
 105         super(name);
 106         this.duration = duration;
 107         this.out = out;
 108         this.verbose = verbose;
 109     }
 110 
 111     /**
 112      * Print status.
 113      */
 114     void describe() {
 115         out.println("DurAllocator run: ");
 116         out.println("   test duration:     " + duration / 1000 + " seconds");
 117         out.println("   number of threads: " + noThreads + " threads");
 118     }
 119 
 120     /**
 121      * Allocates memory in a loop.
 122      */
 123     public void run() {
 124 
 125         long startTime = System.currentTimeMillis();
 126 
 127         while (System.currentTimeMillis() - startTime < duration) {
 128             try {
 129                 allocate();
 130             } catch (Throwable t) {
 131                 out.println(getName() + " FAILED: " + t.getClass().getName() + " in iteration " + iterations + ": " + t.getMessage());
 132                 return;
 133             }
 134             iterations++;
 135             if (verbose && iterations % 1000 == 0) {
 136                 out.print(".");
 137             }
 138             if (verbose && iterations % 60000 == 0) {
 139                 out.println(".");
 140             }
 141         }
 142         if (verbose) {
 143             out.println("");
 144         }
 145 
 146 
 147         long endTime = System.currentTimeMillis();
 148         long runTime = endTime - startTime;
 149         if (duration > runTime) {
 150             out.println(getName() + "  FAILED: Execution time < requested execution time.");
 151             out.println("                execution time is " + runTime);
 152             out.println("                requested time is " + duration);
 153         } else if (iterations <= 0) {
 154             out.println(getName() + "  FAILED: No executions finished");
 155         } else {
 156             result = true;
 157         }
 158     }
 159 
 160     private void allocate() {
 161         for (int j = 0; j < 1000; j++) {
 162             int i = 0;
 163 
 164             switch (myType) {
 165             case SMALL_OBJECT_ALLOCATER:
 166                 i = 5;
 167                 break;
 168             case LARGE_OBJECT_ALLOCATER:
 169                 i = 1;
 170                 break;
 171             case ANY_OBJECT_ALLOCATER:
 172                 i = LocalRandom.nextInt(100);
 173                 break;
 174             case ANY_NO_MULTIARRAYS_ALLOCATER:
 175                 i = LocalRandom.nextInt(100);
 176                 if ((i >= 2) && (i <= 4)) {
 177                     i = 5;
 178                 }
 179                 break;
 180             default:
 181                 break;
 182             }
 183 
 184             switch (i) {
 185             case 0:
 186                 d0 = new LargePagesTest.Dummy[10];
 187                 break;
 188             case 1:
 189                 d1 = new LargePagesTest.Dummy[1000];
 190                 break;
 191             case 2:
 192                 d2 = new LargePagesTest.Dummy[10][10];
 193                 break;
 194             case 3:
 195                 d3 = new LargePagesTest.Dummy[100][100];
 196                 break;
 197             case 4:
 198                 d4 = new LargePagesTest.Dummy[10][10][10];
 199                 break;
 200             default:
 201                 d5 = new LargePagesTest.Dummy();
 202                 break;
 203             }
 204         }
 205     }
 206 
 207     /**
 208      * A Dummy class.
 209      */
 210     private class Dummy {
 211         /**
 212          * Creates a dummy.
 213          */
 214         Dummy() {
 215             cnt++;
 216         }
 217     }
 218 
 219     /**
 220      * @param args Input arguments
 221      */
 222     public static void main(String[] args) {
 223 
 224         long duration = 30 * 60 * 1000;
 225         PrintStream out = System.out;
 226         boolean verbose = true;
 227 
 228         for (int i = 0; i < args.length; i++) {
 229             String noThreadsArgName = "noThreads=";
 230             String executionTimeArgName = "duration=";
 231             String verboseArgName = "verbose=";
 232             if (args[i].indexOf(noThreadsArgName) != -1) {
 233                 noThreads = Integer.parseInt(args[i].substring(noThreadsArgName.length(), args[i].length()));
 234             } else if (args[i].indexOf(executionTimeArgName) != -1) {
 235                 duration = 1000 * Long.parseLong(args[i].substring(executionTimeArgName.length(), args[i].length()));
 236             } else if (args[i].indexOf(verboseArgName) != -1) {
 237                 verbose = Boolean.parseBoolean(args[i].substring(verboseArgName.length(), args[i].length()));
 238             } else {
 239                 System.out.println("ERROR: Unknown argument string: " + args[i]);
 240                 System.exit(-1);
 241             }
 242         }
 243 
 244         // Please don't...
 245         if (noThreads <= 0) {
 246             noThreads = 1;
 247         }
 248 
 249         LargePagesTest[] runners = new LargePagesTest[noThreads];
 250 
 251         for (int i = 0; i < noThreads; i++) {
 252             runners[i] = new LargePagesTest("DurAllocator " + i, duration, out, verbose);
 253         }
 254 
 255         runners[0].describe();
 256 
 257         for (int i = 0; i < noThreads; i++) {
 258             runners[i].start();
 259         }
 260 
 261         for (int i = 0; i < noThreads; i++) {
 262             try {
 263                 runners[i].join(duration + 10 * 60 * 1000);
 264             } catch (InterruptedException e) {
 265                 out.println(runners[i].getName() + " FAILED: " + e.getClass().getName() + " " + e.getMessage());
 266                 System.exit(-1);
 267             }
 268         }
 269 
 270         for (int i = 0; i < noThreads; i++) {
 271             if (!runners[i].result) {
 272                 out.println(runners[i].getName() + " FAILED: status=" + runners[i].result);
 273                 System.exit(-1);
 274             }
 275         }
 276 
 277         if (verbose) {
 278             out.println();
 279         }
 280 
 281         out.print("DurAllocator PASSED with (");
 282         for (int i = 0; i < noThreads; i++) {
 283             out.print("" + runners[i].iterations + (i + 1 < noThreads ? "+" : ""));
 284         }
 285         out.println(") iterations.");
 286         // System.exit(90); // use to return 90 as indication of success
 287     }
 288 
 289 }