1 /* 2 * Copyright (c) 2007, 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 stress randomness 28 * 29 * @summary converted from VM testbase nsk/stress/jni/gclocker/gcl001. 30 * VM testbase keywords: [stress, quick, feature_283, nonconcurrent] 31 * VM testbase readme: 32 * DESCRIPTION 33 * Check compatibility of GC Locker improvements with JNI CS 34 * Two types of concurrent threads are present: 35 * A) Create N 'JNI CS' threads. Each of them will: 36 * 1. Create primitive array and string with random data 37 * 2. Pass it to native method 38 * 3. Sort/Hash data in JNI CS mixing string and array critical sections 39 * 4. Return from native 40 * 5. Check data to be processed correctly 41 * B) Create M ' Garbage producer/memory allocation' threads. Each of them will: 42 * 1. Allocate memory blocks and make them garbage. 43 * 2. Check for OOM errors. 44 * 45 * @library /vmTestbase 46 * /test/lib 47 * @run main/othervm/native/timeout=480 48 * -XX:-UseGCOverheadLimit 49 * nsk.stress.jni.gclocker.gcl001 50 * -stressThreadsFactor 8 51 */ 52 53 package nsk.stress.jni.gclocker; 54 55 import nsk.share.gc.DefaultProducer; 56 import nsk.share.gc.GC; 57 import nsk.share.gc.ThreadedGCTest; 58 import nsk.share.gc.gp.array.BooleanArrayProducer; 59 import nsk.share.gc.gp.array.ByteArrayProducer; 60 import nsk.share.gc.gp.array.CharArrayProducer; 61 import nsk.share.gc.gp.array.DoubleArrayProducer; 62 import nsk.share.gc.gp.array.FloatArrayProducer; 63 import nsk.share.gc.gp.array.IntArrayProducer; 64 import nsk.share.gc.gp.array.LongArrayProducer; 65 import nsk.share.gc.gp.array.ShortArrayProducer; 66 import nsk.share.test.ExecutionController; 67 import nsk.share.test.LocalRandom; 68 69 public class gcl001 extends ThreadedGCTest { 70 71 static { 72 System.loadLibrary("gcl001"); 73 } 74 75 int maxBlockSize; 76 77 public static void main(String[] args) { 78 GC.runTest(new gcl001(), args); 79 } 80 81 @Override 82 public void run() { 83 // each thread have only one block at the time 84 // so we should occupy less then 60% of heap with live objects 85 long maxSize = runParams.getTestMemory() / runParams.getNumberOfThreads(); 86 if (maxSize > Integer.MAX_VALUE - 1) { 87 maxSize = Integer.MAX_VALUE - 1; 88 } 89 maxBlockSize = (int) maxSize; 90 log.info("Maximium block size = " + maxBlockSize); 91 super.run(); 92 } 93 94 @Override 95 protected Runnable createRunnable(int i) { 96 if (i < runParams.getNumberOfThreads() / 2) { 97 return CreateJNIWorker(i, maxBlockSize); 98 } else { 99 return new GarbageProducer(maxBlockSize); 100 } 101 } 102 103 public Runnable CreateJNIWorker(int number, int size) { 104 JNIAbstractWorker worker = null; 105 switch (number % 8) { 106 case 0: 107 worker = new JNIBooleanWorker(size); 108 break; 109 case 1: 110 worker = new JNIByteWorker(size); 111 break; 112 case 2: 113 worker = new JNICharWorker(size); 114 break; 115 case 3: 116 worker = new JNIShortWorker(size); 117 break; 118 case 4: 119 worker = new JNIIntWorker(size); 120 break; 121 case 5: 122 worker = new JNILongWorker(size); 123 break; 124 case 6: 125 worker = new JNIFloatWorker(size); 126 break; 127 case 7: 128 worker = new JNIDoubleWorker(size); 129 break; 130 } 131 return worker; 132 } 133 134 int random(int maxSize) { 135 int res = LocalRandom.nextInt(maxSize); 136 return res > 128 ? res : 128; 137 } 138 139 public static Object tmp; 140 141 class GarbageProducer implements Runnable { 142 143 private int maxSize; 144 ExecutionController stresser; 145 DefaultProducer gp; 146 147 GarbageProducer(int size) { 148 this.maxSize = size; 149 gp = new DefaultProducer(); 150 } 151 152 public void run() { 153 if (stresser == null) { 154 stresser = getExecutionController(); 155 } 156 157 while (stresser.continueExecution()) { 158 try { 159 tmp = gp.create(random(maxSize)); 160 } catch (OutOfMemoryError oome) { 161 // Do nothing. 162 } 163 } 164 } 165 } 166 167 abstract class JNIAbstractWorker extends JNIWorker implements Runnable { 168 169 ExecutionController stresser; 170 private int maxSize; 171 172 public JNIAbstractWorker(int maxSize) { 173 this.maxSize = maxSize; 174 } 175 176 public void check(boolean condition, String message) { 177 if (!condition) { 178 throw new Error(message); 179 } 180 } 181 182 abstract void doit(int size); 183 184 public void run() { 185 // create array with random elements 186 // store min and max element for further check 187 // create new string 188 // call JNI methods 189 // check min/max as sort result 190 // check string hash 191 192 if (stresser == null) { 193 stresser = getExecutionController(); 194 } 195 while (stresser.continueExecution()) { 196 // let make at least several values for long/float 197 try { 198 doit(random(maxSize)); 199 } catch (OutOfMemoryError oome) { 200 // Do nothing. 201 } 202 } 203 } 204 } 205 206 // BYTE 207 class JNIBooleanWorker extends JNIAbstractWorker { 208 209 BooleanArrayProducer gp = new BooleanArrayProducer(); 210 211 public JNIBooleanWorker(int size) { 212 super(size); 213 } 214 215 void doit(int size) { 216 217 boolean[] array = gp.create(size); 218 // just to be sure that we have true & false 219 array[0] = true; 220 array[array.length - 1] = false; 221 String str = "unsupported"; 222 int nativeHash = NativeCall(array, str); 223 int javaHash = 0; 224 for (int i = 0; i < str.length(); ++i) { 225 javaHash += (int) str.charAt(i); 226 } 227 javaHash += javaHash; 228 check(array[0] == false && array[array.length - 1] == true 229 && javaHash == nativeHash, "Data validation failure"); 230 231 } 232 } 233 234 class JNIByteWorker extends JNIAbstractWorker { 235 236 ByteArrayProducer gp = new ByteArrayProducer(); 237 238 public JNIByteWorker(int size) { 239 super(size); 240 } 241 242 void doit(int size) { 243 244 byte[] array = gp.create(size); 245 byte min = Byte.MAX_VALUE, max = Byte.MIN_VALUE; 246 for (int i = 0; i < array.length; ++i) { 247 if (array[i] > max) { 248 max = array[i]; 249 } 250 251 if (array[i] < min) { 252 min = array[i]; 253 } 254 } 255 String str = "Min: " + min + " Max: " + max; 256 int nativeHash = NativeCall(array, str); 257 int javaHash = 0; 258 for (int i = 0; i < str.length(); ++i) { 259 javaHash += (int) str.charAt(i); 260 } 261 javaHash += javaHash; 262 check(array[0] == min && array[array.length - 1] == max 263 && javaHash == nativeHash, "Data validation failure"); 264 265 } 266 } 267 268 // CHAR 269 class JNICharWorker extends JNIAbstractWorker { 270 271 CharArrayProducer gp = new CharArrayProducer(); 272 273 public JNICharWorker(int size) { 274 super(size); 275 } 276 277 void doit(int size) { 278 char[] array = gp.create(size); 279 char min = 0xffff, max = 0; 280 for (int i = 0; i < array.length; ++i) { 281 array[i] = (char) LocalRandom.nextInt(); 282 if (array[i] > max) { 283 max = array[i]; 284 } 285 286 if (array[i] < min) { 287 min = array[i]; 288 } 289 } 290 String str = "Min: " + min + " Max: " + max; 291 int nativeHash = NativeCall(array, str); 292 int javaHash = 0; 293 for (int i = 0; i < str.length(); ++i) { 294 javaHash += (int) str.charAt(i); 295 } 296 javaHash += javaHash; 297 check(array[0] == min && array[array.length - 1] == max 298 && javaHash == nativeHash, "Data validation failure"); 299 300 } 301 } 302 303 // SHORT 304 class JNIShortWorker extends JNIAbstractWorker { 305 306 ShortArrayProducer gp = new ShortArrayProducer(); 307 308 public JNIShortWorker(int size) { 309 super(size); 310 } 311 312 void doit(int size) { 313 314 short[] array = gp.create(size); 315 short min = Short.MAX_VALUE, max = Short.MIN_VALUE; 316 for (int i = 0; i < array.length; ++i) { 317 if (array[i] > max) { 318 max = array[i]; 319 } 320 321 if (array[i] < min) { 322 min = array[i]; 323 } 324 } 325 String str = "Min: " + min + " Max: " + max; 326 int nativeHash = NativeCall(array, str); 327 int javaHash = 0; 328 for (int i = 0; i < str.length(); ++i) { 329 javaHash += (int) str.charAt(i); 330 } 331 javaHash += javaHash; 332 check(array[0] == min && array[array.length - 1] == max 333 && javaHash == nativeHash, "Data validation failure"); 334 } 335 } 336 337 // INT 338 class JNIIntWorker extends JNIAbstractWorker { 339 340 IntArrayProducer gp = new IntArrayProducer(); 341 342 public JNIIntWorker(int size) { 343 super(size); 344 } 345 346 void doit(int size) { 347 int[] array = gp.create(size); 348 int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; 349 for (int i = 0; i < array.length; ++i) { 350 if (array[i] > max) { 351 max = array[i]; 352 } 353 354 if (array[i] < min) { 355 min = array[i]; 356 } 357 } 358 String str = "Min: " + min + " Max: " + max; 359 int nativeHash = NativeCall(array, str); 360 int javaHash = 0; 361 for (int i = 0; i < str.length(); ++i) { 362 javaHash += (int) str.charAt(i); 363 } 364 javaHash += javaHash; 365 check(array[0] == min && array[array.length - 1] == max 366 && javaHash == nativeHash, "Data validation failure"); 367 368 } 369 } 370 371 // LONG 372 class JNILongWorker extends JNIAbstractWorker { 373 374 LongArrayProducer gp = new LongArrayProducer(); 375 376 public JNILongWorker(int size) { 377 super(size); 378 } 379 380 void doit(int size) { 381 382 long[] array = gp.create(size); 383 long min = Long.MAX_VALUE, max = Long.MIN_VALUE; 384 for (int i = 0; i < array.length; ++i) { 385 if (array[i] > max) { 386 max = array[i]; 387 } 388 389 if (array[i] < min) { 390 min = array[i]; 391 } 392 } 393 String str = "Min: " + min + " Max: " + max; 394 int nativeHash = NativeCall(array, str); 395 int javaHash = 0; 396 for (int i = 0; i < str.length(); ++i) { 397 javaHash += (int) str.charAt(i); 398 } 399 javaHash += javaHash; 400 check(array[0] == min && array[array.length - 1] == max 401 && javaHash == nativeHash, "Data validation failure"); 402 403 } 404 } 405 406 // FLOAT 407 class JNIFloatWorker extends JNIAbstractWorker { 408 409 FloatArrayProducer gp = new FloatArrayProducer(); 410 411 public JNIFloatWorker(int size) { 412 super(size); 413 } 414 415 void doit(int size) { 416 417 float[] array = gp.create(size); 418 float min = Float.MAX_VALUE, max = Float.MIN_VALUE; 419 for (int i = 0; i < array.length; ++i) { 420 if (array[i] > max) { 421 max = array[i]; 422 } 423 424 if (array[i] < min) { 425 min = array[i]; 426 } 427 } 428 String str = "Min: " + min + " Max: " + max; 429 int nativeHash = NativeCall(array, str); 430 int javaHash = 0; 431 for (int i = 0; i < str.length(); ++i) { 432 javaHash += (int) str.charAt(i); 433 } 434 javaHash += javaHash; 435 check(array[0] == min && array[array.length - 1] == max 436 && javaHash == nativeHash, "Data validation failure"); 437 } 438 } 439 440 // DOUBLE 441 class JNIDoubleWorker extends JNIAbstractWorker { 442 443 DoubleArrayProducer gp = new DoubleArrayProducer(); 444 445 public JNIDoubleWorker(int size) { 446 super(size); 447 } 448 449 void doit(int size) { 450 451 double[] array = gp.create(size); 452 double min = Double.MAX_VALUE, max = Double.MIN_VALUE; 453 for (int i = 0; i < array.length; ++i) { 454 if (array[i] > max) { 455 max = array[i]; 456 } 457 458 if (array[i] < min) { 459 min = array[i]; 460 } 461 } 462 String str = "Min: " + min + " Max: " + max; 463 int nativeHash = NativeCall(array, str); 464 int javaHash = 0; 465 for (int i = 0; i < str.length(); ++i) { 466 javaHash += (int) str.charAt(i); 467 } 468 javaHash += javaHash; 469 check(array[0] == min && array[array.length - 1] == max 470 && javaHash == nativeHash, "Data validation failure"); 471 } 472 } 473 } 474 475 class JNIWorker { 476 477 protected native int NativeCall(boolean[] array, String str); 478 479 protected native int NativeCall(byte[] array, String str); 480 481 protected native int NativeCall(char[] array, String str); 482 483 protected native int NativeCall(short[] array, String str); 484 485 protected native int NativeCall(int[] array, String str); 486 487 protected native int NativeCall(long[] array, String str); 488 489 protected native int NativeCall(float[] array, String str); 490 491 protected native int NativeCall(double[] array, String str); 492 } --- EOF ---