1 /*
   2  * Copyright (c) 2002, 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 /*
  26  * @test
  27  * @key gc randomness
  28  *
  29  * @summary converted from VM Testbase gc/gctests/gctest01.
  30  * VM Testbase keywords: [gc]
  31  *
  32  * @library /vmTestbase
  33  *          /test/lib
  34  * @run driver jdk.test.lib.FileInstaller . .
  35  * @run main/othervm gc.gctests.gctest01.gctest01 100 10
  36  */
  37 
  38 package gc.gctests.gctest01;
  39 
  40 import nsk.share.test.*;
  41 import nsk.share.log.*;
  42 import nsk.share.gc.*;
  43 import nsk.share.TestBug;
  44 
  45 //import RusageStruct;
  46 
  47 /*  -- stress testing
  48  create 20 memory evil threads requesting to allocate
  49  the object of sizes from 8 to ( 2 ^ 19).
  50  The live time of objects is very short.
  51  Memory evil thread exits the first time memory allocation fails.
  52  */
  53 
  54 class ThreadTracker {
  55         static int threadCount = 0;
  56 
  57         static synchronized int getThreadCount() {
  58                 return threadCount;
  59         }
  60 
  61         static synchronized void setThreadCount(int count) {
  62                 threadCount = count;
  63         }
  64 
  65         static synchronized void incr() {
  66                 threadCount++;
  67         }
  68 
  69         static synchronized void decr() {
  70                 threadCount--;
  71         }
  72 }
  73 
  74 class PopulationException extends Exception {
  75 }
  76 
  77 class Person {
  78         String name;
  79         int  ssid;
  80         int  age;
  81         int  buf[];
  82         int  bufsz;
  83         static int populationLimit;
  84         static int currentPopulation;
  85 
  86         public Person(String n, int ssid, int age, int bufsz) throws PopulationException {
  87                 this.incr();
  88                 if (this.getPopulation() > this.getPopulationLimit()) {
  89                         throw new PopulationException();
  90                 }
  91                 name = n;
  92                 this.ssid = ssid;
  93                 this.age = age;
  94                 if ( bufsz > 0 ) {
  95                         this.bufsz = bufsz;
  96                         this.buf = new int[bufsz];
  97                 }
  98         }
  99 
 100         static synchronized void incr() {
 101                 currentPopulation++;
 102         }
 103 
 104         static synchronized int getPopulation() {
 105                 return currentPopulation;
 106         }
 107 
 108         static synchronized void setPopulation(int census) {
 109                 currentPopulation = census;
 110         }
 111 
 112         static synchronized void setPopulationLimit(int limit) {
 113                 populationLimit = limit;
 114         }
 115 
 116         static synchronized int getPopulationLimit() {
 117                 return populationLimit;
 118         }
 119 }
 120 
 121 
 122 
 123 // create 20 memory evil threads requesting to allocate
 124 // the object of sizes from 8 to ( 2 ^ 19).
 125 // The live time of objects is very short.
 126 public class gctest01 extends TestBase {
 127         private String[] args;
 128 
 129         public gctest01(String[] args) {
 130                 setArgs(args);
 131         }
 132 
 133         class memevil extends Thread {
 134                 int sum;
 135                 int bufsz = 64;
 136 
 137                 public memevil(int bufsz) {
 138                         ThreadTracker.incr();
 139                         sum = 0;
 140                         this.bufsz = bufsz;
 141 
 142                 }
 143 
 144                 /* Person object is live short, it will be garbage after
 145                    control returns
 146                    */
 147                 private boolean doit() {
 148                         try {
 149                                 Person p = new Person("Duke", 100, 100, bufsz);
 150                         } catch (OutOfMemoryError e ) {
 151                                 log.info(getName() + ": Out of Memory");
 152                                 return false; //should free up some memory
 153                         } catch (PopulationException e) {
 154                                 //we've reached the limit, so stop
 155                                 return false;
 156                         }
 157                         return true;
 158                 }
 159 
 160                 public void run() {
 161                         while ( doit() ) {
 162                                 if ( LocalRandom.random() > 0.6668) {
 163                                         try {
 164                                                 sleep(10);   // to be nice
 165                                         }
 166                                         catch (InterruptedException e) {}
 167                                 }
 168                         }
 169                         //must be done, decrement the thread count
 170                         ThreadTracker.decr();
 171                 }
 172         }
 173 
 174         class escaper extends Thread {
 175                 public void run() {
 176                         while ( ThreadTracker.getThreadCount() > 0 ) {
 177                                 int buf[] = new int[32];
 178                                 try
 179                                 {
 180                                         Thread.currentThread().sleep(1000);
 181                                 } catch (InterruptedException e) {
 182                                 }
 183                                 // log.info("Is the sun rising?");
 184                         }
 185                 }
 186         }
 187 
 188 
 189         public void run() {
 190                 int bufsz = 8;
 191                 int i = 3;
 192                 int peopleLimit = 1000;
 193                 String usage = "usage: gctest01 [NumberOfObjects [Iterations] ] ]";
 194                 int loops;
 195                 int LOOPCOUNT = 10;
 196 
 197                 if (args.length > 0) {
 198                         try {
 199                                 peopleLimit = new Integer(args[0]).intValue();
 200                         } catch (NumberFormatException e) {
 201                                 log.info(usage);
 202                                 throw new TestBug("Bad input to gctest01." +
 203                                                 " Expected integer, got: ->" + args[0] + "<-", e);
 204                         }
 205                 }
 206 
 207                 if (args.length > 1 ) {
 208                         try {
 209                                 LOOPCOUNT = new Integer(args[1]).intValue();
 210                         } catch (NumberFormatException e) {
 211                                 log.error(usage);
 212                                 throw new TestBug("Bad input to gctest01." +
 213                                                 " Expected int, got: ->" + args[1] + "<-", e);
 214                         }
 215 
 216                 }
 217 
 218                 double before = 0.0;
 219                 double after;
 220 
 221                 Person.setPopulationLimit(peopleLimit);
 222 
 223                 for (loops = 0; loops < LOOPCOUNT; loops++) {
 224                         Person.setPopulation(0);
 225                         escaper you = new escaper();
 226                         you.setName("Escaper");
 227                         you.start();
 228                         i = 3;
 229                         bufsz = 8;
 230                         while ( i < 20  )
 231                         {
 232                                 memevil me = new memevil(bufsz);
 233                                 me.setName("Memevil" + bufsz);
 234                                 bufsz = 2*bufsz;
 235                                 me.start();
 236                                 i++;
 237                                 Thread.currentThread().yield();
 238                         }
 239                         try
 240                         {
 241                                 you.join();
 242                         }
 243                         catch (InterruptedException e)
 244                         {
 245                                 e.printStackTrace();
 246                         }
 247                 } // end of loops
 248                 log.info("Test passed.");
 249 
 250         }
 251 
 252         public void setArgs(String[] args) {
 253                 this.args = args;
 254         }
 255 
 256         public static void main(String args[]) {
 257                 GC.runTest(new gctest01(args), args);
 258         }
 259 }