Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/jnistress002.java
41155 views
/*1* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* jnistress002 is a class that sets up classes that do the work25* for the test.26*27* The Interrupter objects send interrupts to the JNIters.28* The GarbageGenerator objects generate garbage.29*30* sync[0] synchronizes the test cycles.31* sync[1] synchronizes access to exception counters.32* sync[2] synchronizes the cycle count update. It also insures that33* the interrupts do not interfere with the cycle count updates.34* This is because cycle count updates are used to define cycles.35*/3637/*38* @test39* @key stress randomness40*41* @summary converted from VM testbase nsk/stress/jni/jnistress002.42* VM testbase keywords: [stress, quick, feature_283, nonconcurrent]43*44* @library /vmTestbase45* /test/lib46* @run main/othervm/native47* nsk.stress.jni.jnistress00248* -numTHREADer 2049* -threadInterval 20050* -numInterrupter 251* -interruptInterval 50052* -numGarbage 8053* -garbageInterval 554* -numIteration 26055*/5657package nsk.stress.jni;5859import nsk.share.Consts;60import nsk.share.Debug;61import nsk.share.test.StressOptions;62import jdk.test.lib.Utils;6364import java.lang.reflect.Field;65import java.util.Random;6667public class jnistress002 extends Thread {6869/* Maximum number of iterations. Ignored if <= 0L */70static long numIteration = 0L;71/* Timeout */72static long timeOut;73/* Number of test class objects */74static int numJNIter = 1;75/* Time between JNI stressing by the threads under test */76/* (in milliseconds) */77static int jniInterval = 10000;78/* Number of interrupting threads */79static int numInterrupter = 1;80/* Time between interrupts in milliseconds */81static int interruptInterval = 100;82/* Number of garbage generating threads */83static int numGarbage = 1;84/* Time between garbage allocations in milliseconds */85static int garbageInterval = 100;86// The number of classes for creates via JNI87static int jniStringAllocSize = 10000;8889private static StressOptions stressOptions;9091public static void main(String[] argv) {92try {93int i = 0;94int nJNISync = 10;95jnistress002 dm = null;96boolean errArg = false;9798stressOptions = new StressOptions(argv);99100/* Process arguments */101while (!errArg && i < argv.length) {102/* Number of iterations. Ignored if <= 0. */103if (i < argv.length && argv[i].equals("-numIteration")) {104++i;105if (i < argv.length) {106try {107numIteration = Long.parseLong(argv[i++]);108} catch (NumberFormatException e) {109errArg = true;110}111}112} else if (i < argv.length && argv[i].equals("-numTHREADer")) {113++i;114if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {115try {116numJNIter = Integer.parseInt(argv[i++]);117} catch (NumberFormatException e) {118errArg = true;119}120if (numJNIter <= 0) errArg = true;121}122} else if (i < argv.length && argv[i].equals("-threadInterval")) {123++i;124if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {125try {126jniInterval = Integer.parseInt(argv[i++]);127} catch (NumberFormatException e) {128errArg = true;129}130}131} else if (i < argv.length && argv[i].equals("-numInterrupter")) {132++i;133if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {134try {135numInterrupter = Integer.parseInt(argv[i++]);136} catch (NumberFormatException e) {137errArg = true;138}139}140} else if (i < argv.length && argv[i].equals("-interruptInterval")) {141++i;142if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {143try {144interruptInterval = Integer.parseInt(argv[i++]);145} catch (NumberFormatException e) {146errArg = true;147}148}149} else if (i < argv.length && argv[i].equals("-numGarbage")) {150++i;151if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {152try {153numGarbage = Integer.parseInt(argv[i++]);154} catch (NumberFormatException e) {155errArg = true;156}157}158} else if (i < argv.length && argv[i].equals("-garbageInterval")) {159++i;160if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {161try {162garbageInterval = Integer.parseInt(argv[i++]);163} catch (NumberFormatException e) {164errArg = true;165}166}167} else if (i < argv.length && argv[i].equals("-jniStringAllocSize")) {168++i;169if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {170try {171jniStringAllocSize = Integer.parseInt(argv[i++]);172} catch (NumberFormatException e) {173errArg = true;174}175}176} else if (i < argv.length && argv[i].startsWith("-stress")) {177++i;178if (i < argv.length && Character.isDigit(argv[i].charAt(0))) {179++i;180}181} else System.out.println("Argument #" + i++ + " is incorrect");182}183184numIteration *= stressOptions.getIterationsFactor();185numJNIter *= stressOptions.getThreadsFactor();186numInterrupter *= stressOptions.getThreadsFactor();187numGarbage *= stressOptions.getThreadsFactor();188timeOut = stressOptions.getTime() * 1000;189190sync = new Synchronizer[10];191for (i = 0; i < nJNISync; i++)192sync[i] = new Synchronizer();193dm = new jnistress002(numIteration, numJNIter, jniInterval,194numInterrupter, interruptInterval, numGarbage, garbageInterval);195dm.start();196197try {198dm.join(timeOut);199} catch (InterruptedException e) {200System.out.println("TESTER THREAD WAS INTERRUPTED");201System.exit(Consts.TEST_FAILED);202}203204if (DEBUG) System.out.println("jnistress002::main(): halt!");205206if (dm.isAlive()) {207System.out.println("TIME LIMIT EXCEEDED");208dm.halt();209if (DEBUG) System.out.println("jnistress002::main(): join!");210try {211dm.join(10000L);212} catch (InterruptedException e) {213System.out.println("TESTER THREAD WAS INTERRUPTED");214System.exit(Consts.TEST_FAILED);215}216} else {217System.out.println("TESTER THREAD FINISHED");218}219220if (DEBUG) System.out.println("jnistress002::main(): zzzz...");221222if (!JNIter002.passed())223System.exit(Consts.TEST_FAILED);224} catch (Throwable e) {225Debug.Fail(e);226}227}228229jnistress002(230long iters,231int nJNI,232int jniInterval,233int nInter,234int iruptInterval,235int nGarb,236int garbInterval237) {238int i = 0;239nCycles = iters;240/* Should have at least one of nCycles>0 */241if (nCycles <= 0) nCycles = Long.MAX_VALUE;242jniter = new JNIter002[nJNI];243interval = jniInterval;244irupt = new Interrupter[nInter];245garb = new GarbageGenerator[nGarb];246for (i = 0; i < nJNI; i++)247jniter[i] = new JNIter002(sync);248for (i = 0; i < nInter; i++) {249irupt[i] = new Interrupter(jniter, sync);250irupt[i].setInterval(iruptInterval);251}252for (i = 0; i < nGarb; i++) {253garb[i] = new GarbageGenerator();254garb[i].setInterval(garbInterval);255256}257258// premtive special class loading259objectsJNI clStub = new objectsJNI(null, 0, 0, null, 0, 0);260}261262public void run() {263try {264int i = 0;265long iCycle = 0L;266JNIter002.clearCount();267JNIter002.clearInterruptCount();268for (i = 0; i < jniter.length; i++)269jniter[i].start();270271while (JNIter002.getCount() < jniter.length) {272try {273sleep(100);274} catch (InterruptedException e) {275}276}277JNIter002.clearCount();278// JNIter002.clearInterruptCount();279synchronized (sync[0]) {280sync[0].notifyAll();281}282283for (i = 0; i < garb.length; i++)284garb[i].start();285for (i = 0; i < irupt.length - 1; i++)286irupt[i].start();287288if (DEBUG) System.out.println("Cycles=" + nCycles);289for (iCycle = 0; iCycle < nCycles && !done && JNIter002.passed(); iCycle++) {290System.out.print("Cycle: " + iCycle);291try {292sleep(interval);293} catch (InterruptedException e) {294}295synchronized (sync[1]) {296System.out.println(" Interrupt count=" +297JNIter002.getInterruptCount());298}299JNIter002.clearCount();300synchronized (sync[0]) {301sync[0].notifyAll();302}303int n = 0;304for (i = 0; i < jniter.length; i++)305if (jniter[i].finished()) n++;306if (n == jniter.length) break;307}308if (JNIter002.passed()) {309System.out.println("JNI TEST PASSED");310} else {311System.out.println("JNI TEST FAILED");312}313for (i = 0; i < irupt.length; i++)314irupt[i].halt();315for (i = 0; i < garb.length; i++)316garb[i].halt();317for (i = 0; i < jniter.length; i++)318jniter[i].halt();319/* Flush any waiters */320if (DEBUG) System.out.println("jnistress002::run(): before sync[0]");321synchronized (sync[0]) {322sync[0].notifyAll();323}324if (DEBUG) System.out.println("jnistress002::run(): after sync[0]");325for (i = 0; i < irupt.length; i++) {326try {327irupt[i].join();328} catch (InterruptedException e) {329}330}331if (DEBUG) System.out.println("jnistress002::run(): X");332for (i = 0; i < garb.length; i++) {333try {334garb[i].join();335} catch (InterruptedException e) {336}337}338if (DEBUG) System.out.println("jnistress002::run(): Y");339System.out.println("jniter.length is " + jniter.length);340for (i = 0; i < jniter.length; i++) {341try {342if (jniter[i].isAlive()) {343jniter[i].join();344}345} catch (InterruptedException e) {346}347}348if (DEBUG) System.out.println("jnistress002::run(): Z");349} catch (Throwable e) {350Debug.Fail(e);351}352}353354public void halt() {355done = true;356}357358public boolean finished() {359return done;360}361362long nCycles = 0;363JNIter002[] jniter;364static Synchronizer[] sync;365private int interval = 100;366Interrupter[] irupt;367GarbageGenerator[] garb;368private boolean done = false;369final private static boolean DEBUG = false;370}371372class objectsJNI {373public String instName;374public int i;375public long l;376public char[] c;377public float f;378public double d;379380public objectsJNI(String name,381int intgr,382long lng,383char[] charr,384float flt,385double dbl386) {387instName = name;388i = intgr;389l = lng;390f = flt;391d = dbl;392c = charr;393}394395public boolean equals(Object o) {396397if (this.getClass() != o.getClass())398return false;399400Field[] fields = o.getClass().getFields();401try {402for (int i = 0; i < fields.length; i++) {403if (fields[i].get(o) instanceof char[]) {404for (int j = 0; j < ((char[]) fields[i].get(this)).length; j++)405if (((char[]) fields[i].get(this))[j] !=406((char[]) fields[i].get(o))[j]) {407System.out.println(408"Char arrays have difference in " + j);409return false;410}411} else if (!fields[i].get(this).equals(fields[i].get(o))) {412System.out.println(413"The fields No. " + i + " are different");414return false;415}416}417} catch (Exception e) {418System.out.println("Error : " + e);419}420;421return true;422}423}424425class JNIter002 extends Thread {426427// The native method for testing JNI Object's calls428public native objectsJNI[] jniobjects(String s, int i, long l,429char[] c, float f, double d);430431static {432System.loadLibrary("jnistress002");433}434435Random myRandom = new Random(Utils.getRandomInstance().nextLong());436437public JNIter002(Synchronizer[] aSync) {438sync = aSync;439}440441public void run() {442try {443String s;444int i;445long l;446char[] c;447float f;448double d;449int iter = 0;450451/* Synchronize start of work */452incCount();453synchronized (sync[0]) {454try {455sync[0].wait();456} catch (InterruptedException e) {457}458}459while (!done && pass) {460try {461/* Synchronized the JNI stressing */462synchronized (sync[2]) {463incCount();464}465synchronized (sync[0]) {466try {467sync[0].wait();468} catch (InterruptedException e) {469synchronized (sync[1]) {470JNIter002.incInterruptCount();471}472}473}474synchronized (sync[0]) {475i = myRandom.nextInt(Integer.MAX_VALUE);476l = myRandom.nextLong();477f = myRandom.nextFloat();478d = myRandom.nextDouble();479s = getName();480c = s.toCharArray();481objectsJNI test = new objectsJNI(s, i, l, c, f, d);482Object[] testJNI = jniobjects(s, i, l, c, f, d);483484for (int j = 0; j < testJNI.length; j++)485if (!testJNI[j].equals(test)) {486System.out.println("Objects are different");487fieldprint("JNI object", testJNI[j]);488fieldprint("Java object", test);489pass = false;490}491}492if (DEBUG) System.out.println("We have " + activeCount() +493" threads now.");494synchronized (this) {495try {496wait(1L);497} catch (InterruptedException e) {498throw new InterruptedException();499}500}501} catch (InterruptedException e) {502synchronized (sync[1]) {503JNIter002.incInterruptCount();504}505}506iter++;507iter = iter % CASECOUNT;508}509if (DEBUG) System.out.println("JNITer::run(): done=" + done);510done = true;511if (DEBUG) System.out.println("JNITer::run(): pass=" + JNIter002.pass);512if (DEBUG) System.out.println("JNIter002::run(): done");513} catch (Throwable e) {514Debug.Fail(e);515}516}517518private synchronized static void incCount() {519count++;520}521522public static int getCount() {523return count;524}525526public synchronized static void clearCount() {527count = 0;528}529530private synchronized static void incInterruptCount() {531interruptCount++;532}533534public static int getInterruptCount() {535return interruptCount;536}537538public synchronized static void clearInterruptCount() {539interruptCount = 0;540}541542public static void halt() {543done = true;544}545546public boolean finished() {547return done;548}549550public static boolean passed() {551return pass;552}553554Synchronizer[] sync;555private static int count = 0;556private static int interruptCount = 0;557private static boolean done = false;558private static boolean pass = true;559final private static int CASECOUNT = 2;560final private static boolean DEBUG = false;561562static void fieldprint(String s, Object obj) {563Field[] fields = obj.getClass().getFields();564System.out.println(s);565try {566for (int i = 0; i < fields.length; i++) {567if (fields[i].get(obj) instanceof java.lang.String)568System.out.println(569fields[i] + " = \"" + fields[i].get(obj) + "\"");570else if (fields[i].get(obj) instanceof char[])571System.out.println(fields[i] + " = \"" +572new String((char[]) fields[i].get(obj)) + "\"");573else574System.out.println(575fields[i] + " = " + fields[i].get(obj));576}577} catch (Exception e) {578System.out.println("Error: " + e);579}580}581}582583584