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