You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sm...@apache.org on 2007/06/08 18:35:10 UTC
svn commit: r545554 [5/13] - in
/harmony/enhanced/buildtest/branches/2.0/tests/reliability: ./ run/ src/
src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/harmony/
src/java/org/apache/harmony/test/ src/java/org/apache/harmony/test/reliab...
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ExcptHandlerTest/ExcptHandlerTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ExcptHandlerTest/ExcptHandlerTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ExcptHandlerTest/ExcptHandlerTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ExcptHandlerTest/ExcptHandlerTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Oleg Oleinik
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.ExcptHandlerTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+
+/*
+ * Goal: check that Thread exception handling mechanism works as expected
+ * when various types of runtime exceptions/errors are thrown.
+ * Actually, not very close to often real-life situation...
+ *
+ * The test does:
+ *
+ * 1. Creates N_OF_THREADS threads of a dozen of various types. Each thread
+ * typically locks some object and causes runtime exceptions/errors to be thrown.
+ *
+ * Caused exceptions are: StackOverflowError, NullPointerException,
+ * ArrayIndexOutOfBoundsException, NegativeArraySizeException, ArithmeticException,
+ * ArrayStoreException, IllegalMonitorStateException, ClassCastException, RuntimeException.
+ *
+ * 2. For each Thread either UncaughtExceptionHandler or DefaultUncaughtExceptionHandler
+ * is set. The handlers just wrap and re-throw the caught exception, expecting that
+ * VM ignores the exception.
+ *
+ * 3. Starts threads and waits for there completion.
+ *
+ * 4. Expected result: no crashes, no hangs (including due to that objects are
+ * not unlocked when exceptions are thrown).
+ */
+
+
+public class ExcptHandlerTest extends Test {
+
+ static int N_OF_THREADS = 5;
+
+ static volatile int counter = 0;
+
+ public static void main(String[] args) {
+ System.exit(new ExcptHandlerTest().test(args));
+ }
+
+ public int test(String[] params) {
+
+ parseParams(params);
+
+ // threads: daemon/non-daemon x handler/default handler
+
+ return (test(true, true) && test(false, true) &&
+ test(true, false) && test(false, false)) ? pass("OK") : fail("");
+ }
+
+ boolean test(boolean daemon, boolean defaultHandler) {
+
+ clearInvokedHandlers();
+
+ Thread[][] t = new Thread[11][N_OF_THREADS];
+
+ ThreadGroup tg = new ThreadGroup("");
+
+ int[][] obj1 = {{1, 1}, {1, 1}};
+ Object[][] obj2 = {{"a", "b"}, {"c", "d"}};
+ Object[][] obj3 = {{"", ""}, {"", ""}};
+
+ // First, create threads of various exception types
+
+ for (int i = 0; i < t[0].length; ++i){
+ t[0][i] = new StackOverflowT(tg);
+ t[1][i] = new NullPointerT(tg);
+ t[2][i] = new IndexOutOfBoundsT(tg);
+ t[3][i] = new NegativeArraySizeT(tg);
+ t[4][i] = new ArithmeticT(tg);
+ t[5][i] = new ArrayStoreT(tg);
+ t[6][i] = new IllegalStateT1(tg, obj1);
+ t[7][i] = new IllegalStateT2(tg, obj2);
+ t[8][i] = new IllegalStateT3(tg, obj3);
+ t[9][i] = new RuntimeExcptT(tg);
+ t[10][i] = new ClassCastT(tg);
+ }
+
+ MyUncoughtExceptionHandler h = new MyUncoughtExceptionHandler();
+
+ // Then, set handlers and start threads
+
+ for (int i = 0; i < t.length; ++i){
+ for (int j = 0; j < t[i].length; ++j) {
+ t[i][j].setDaemon(daemon);
+ if (defaultHandler){
+ t[i][j].setDefaultUncaughtExceptionHandler(h);
+ } else {
+ t[i][j].setUncaughtExceptionHandler(h);
+ }
+ t[i][j].start();
+ }
+ }
+
+ // Then, wait for threads completion
+
+ for (int i = 0; i < t.length; ++i){
+ for (int j = 0; j < t[i].length; ++j) {
+ try {
+ t[i][j].join();
+ // System.out.println("Joined thread " + t[i][j] + " / " + j);
+ } catch (InterruptedException ie) {
+ // System.out.println("InteruptedException while joining all started threads");
+ }
+ }
+ }
+
+ // Finally, check that expected number of uncaught exception
+ // handlers was called
+
+ int invoked_handlers = getInvokedHandlers();
+
+ if (invoked_handlers != t.length * t[0].length) {
+ log.add("" + invoked_handlers + " exception handlers were invoked, while " +
+ t.length * t[0].length + " expected");
+ return false;
+ }
+
+ return true;
+ }
+
+ public void parseParams(String[] params){
+ if (params.length >= 1) {
+ N_OF_THREADS = Integer.parseInt(params[0]);
+ }
+ }
+
+ static synchronized int getInvokedHandlers(){
+ return counter;
+ }
+
+ static synchronized void incInvokedHandlers(){
+ ++counter;
+ }
+
+ static synchronized void clearInvokedHandlers(){
+ counter = 0;
+ }
+
+}
+
+
+ // A thread which causes StackOverflowError to be thrown through
+ // recursive method invocation.
+
+class StackOverflowT extends Thread {
+
+ Object[] o = new Object[10];
+
+ StackOverflowT(ThreadGroup parent){
+ super(parent, "StackOverflowT");
+ }
+
+ public void run() {
+ m(0);
+ }
+
+ void m(int depth) {
+ if (depth == 0) {
+ // lets see what happens if we lock an object,
+ // no specific checks whether or not the object is unlocked
+ // when exception is generated (if not threads try to lock
+ // a single object in other cases below)
+ synchronized (o){
+ m(depth + 1);
+ }
+ } else {
+ m(depth + 1);
+ }
+ }
+}
+
+ // A thread which causes NullPinterException to be thrown
+
+class NullPointerT extends Thread {
+
+ static int[] arr = new int[10];
+
+ Object f = null;
+ String s = null;
+
+ NullPointerT(ThreadGroup parent){
+ super(parent, "NullPointerT");
+ }
+
+ public void run() {
+ synchronized(arr){
+ s = getF().toString();
+ }
+ }
+
+ Object getF() {
+ Object[] o = {new Object(), null};
+ for (int i = 0; i < o.length; ++i) {
+ f = o[i];
+ }
+ return f;
+ }
+}
+
+ //A thread which causes ArrayIndexOutOfBoundsException to be thrown
+
+class IndexOutOfBoundsT extends Thread {
+
+ Object f = null;
+
+ static Object obj = new Object();
+
+ IndexOutOfBoundsT(ThreadGroup parent){
+ super(parent, "IndexOutOfBoundsT");
+ }
+
+ public void run() {
+ synchronized(obj){
+ Object[] o = {new Object(), null};
+ for (int i = 0; i < 3; ++i) {
+ f = o[i];
+ }
+ }
+ }
+}
+
+ // A thread which causes NegativeArraySizeException to be thrown
+
+class NegativeArraySizeT extends Thread {
+
+ int i = -1;
+
+ int[] j = null;
+
+ NegativeArraySizeT(ThreadGroup parent){
+ super(parent, "NegativeArraySizeT");
+ }
+
+ NegativeArraySizeT (int i) {
+ this.i = i;
+ }
+
+ public void run() {
+ synchronized(this){
+ j = new int[i];
+ }
+ }
+}
+
+ //A thread which causes ArithmeticException to be thrown
+
+class ArithmeticT extends Thread {
+
+ int i = 0, k = 10;
+
+ boolean[] j = {true, false};
+
+ ArithmeticT(int i, int k) {
+ this.i = i;
+ this.k = k;
+ }
+
+ ArithmeticT(ThreadGroup parent){
+ super(parent, "ArithmeticT");
+ }
+
+ public void run() {
+ synchronized(j){
+ j = new boolean[k/i];
+ }
+ }
+}
+
+ //A thread which causes ArrayStoreException to be thrown
+
+class ArrayStoreT extends Thread {
+
+ static Object[] obj = new String[2];
+
+ ArrayStoreT(ThreadGroup parent){
+ super(parent, "ArrayStoreT");
+ }
+
+ public void run() {
+ synchronized (obj){
+ obj[1] = this;
+ }
+ }
+}
+
+ // A thread which causes IllegalMonitorStateException to be thrown
+ // when wait() is called for different object than was locked
+
+class IllegalStateT1 extends Thread {
+
+ int[][] obj = {{1, 1}, {1, 1}};
+
+ IllegalStateT1(ThreadGroup parent, int[][] obj){
+ super(parent, "IllegalStateT1");
+ this.obj = obj;
+ }
+
+ public void run() {
+ synchronized(obj[0]) {
+ try {
+ obj.wait();
+ } catch (InterruptedException ie){
+ }
+ }
+ }
+}
+
+ //A thread which causes IllegalMonitorStateException to be thrown
+ //when notify() is called for different object than was locked
+
+class IllegalStateT2 extends Thread {
+
+ static Object[][] obj = {{"", ""}, {"", ""}};
+
+ IllegalStateT2(ThreadGroup parent, Object[][] obj){
+ super(parent, "IllegalStateT2");
+ this.obj = obj;
+ }
+
+ public void run() {
+ synchronized(obj[0][1]){
+ obj.notify();
+ }
+ }
+}
+
+ //A thread which causes IllegalMonitorStateException to be thrown
+ //when notifyAll() is called for different object than was locked
+
+class IllegalStateT3 extends Thread {
+
+ Object[][] obj = {{"", ""}, {"", ""}};
+
+ IllegalStateT3(ThreadGroup parent, Object[][] obj){
+ super(parent, "IllegalStateT3");
+ this.obj = obj;
+ }
+
+ public void run() {
+ synchronized(obj) {
+ obj[0][0].notifyAll();
+ }
+ }
+}
+
+ //A thread which explicitely throws instance of RuntimeException
+
+class RuntimeExcptT extends Thread {
+
+ RuntimeExcptT(ThreadGroup parent){
+ super(parent, "RuntimeExcptT");
+ }
+
+ public void run() {
+ throw new RuntimeException("");
+ }
+}
+
+ //A thread which causes ClassCastException to be thrown
+
+class ClassCastT extends Thread {
+
+ Object obj = new String("");
+
+ ClassCastT(ThreadGroup parent){
+ super(parent, "ClassCastT");
+ }
+
+ public void run() {
+ ((ClassCastT)getObj()).obj = new String("abc");
+ }
+
+ Object getObj() {
+ return this.obj;
+ }
+}
+
+ // Exception handler - does nothing but wraps handled exception and re-throws
+ // expecting that VM will just ignore it
+
+class MyUncoughtExceptionHandler implements Thread.UncaughtExceptionHandler {
+
+ public void uncaughtException(Thread t, Throwable e) {
+ // System.out.println("Thread " + t.getName() + ", exception " + e);
+ ExcptHandlerTest.incInvokedHandlers();
+ throw new RuntimeException(e);
+ }
+}
+
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ExcptHandlerTest/ExcptHandlerTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/LifeSimulationTest/Life.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/LifeSimulationTest/Life.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/LifeSimulationTest/Life.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/LifeSimulationTest/Life.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.2 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.LifeSimulationTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.util.Random;
+
+/**
+ * The test emulate life of primary creatures ("Life" game by John Horton Conway).
+ * (http://en.wikipedia.org/wiki/Conway's_Game_of_Life)
+ *
+ * The laws of life are pretty simple:
+ * Every "creature" has 2 properties "age" and "health"
+ * and has ability "to feed".
+ * The "creature" passes away if
+ * - age is achieved age limit,
+ * - ate few of "food".
+ * The "creature" can generate new "creature"
+ * if it is "adult" (age > 1/3 age limit) and has enough "health".
+ *
+ * Also the more "creatures" means the less food.
+ * All "creatures" have to die due to end of "food"
+ */
+
+public class Life extends Test {
+
+ static int total = 0;
+ static int maxAge = 100;
+ static Random rand = new Random ();
+ static int maxTotal = 200;
+ static volatile int food = 100000;
+ static int inithealth = 100;
+ static Life base;
+ Object lock = new Object();
+
+ public static void main(String[] args) {
+ base = new Life();
+ System.exit(base.test(args));
+ }
+
+ public int test(String[] params) {
+ boolean br_started = false;
+ parseParams(params);
+ // log.add("maxTotal creatures = " + maxTotal);
+ // log.add("maxAge of creature = " + maxAge);
+ // log.add("initial health of creature = " + inithealth);
+ // log.add("total amount of food = " + food);
+
+ total = 0;
+ BigBrother br = new BigBrother();
+ for (int i = 0; i < maxTotal; i++) {
+ new Creature(Integer.toString(i), lock).start();
+ if (total > 2 && !br_started) {
+ br.start();
+ br_started = true;
+ }
+ }
+
+ try {
+ br.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ maxTotal = Integer.parseInt(params[0]);
+ if (params.length >= 2) {
+ maxAge = Integer.parseInt(params[1]);
+ if (params.length >= 3) {
+ inithealth= Integer.parseInt(params[2]);
+ if (params.length >= 4) {
+ food = Integer.parseInt(params[3]);
+ }
+ }
+ }
+ }
+ }
+
+}
+
+class BigBrother extends Thread {
+
+ public void run () {
+ while (Life.total > 0){
+ // Life.base.log.add(Life.total + " food:"+ Life.food);
+ Thread.yield();
+ }
+ return;
+ }
+}
+
+class Creature extends Thread {
+ private String name;
+ private int age;
+ private int health;
+ private Life base;
+ private int child;
+ private Object lock;
+
+ Creature (String name, Object lock) {
+ age = 0;
+ child = 0;
+ health = Life.inithealth;
+ this.name = name;
+ base = Life.base;
+ this.lock = lock;
+ }
+
+ public void run () {
+ incTotal();
+ // base.log.add(name + " was born");
+ while (age < Life.maxAge && health > 0){
+ age++;
+ synchronized (lock) {
+ feed();
+ fission();
+ }
+ health--;
+ // base.log.add(name + " alive " + age + " h:" + health);
+ Thread.yield();
+ }
+ decTotal();
+ // base.log.add(name + " died");
+ return;
+ }
+
+
+ private void fission() {
+ if (age > Life.maxAge/3
+ && health > Life.inithealth/5
+ && Life.total < Life.maxTotal) {
+ new Creature(name + "+" + (++child), lock).start();
+ health -= 20;
+ if (age > 4*Life.maxAge/5) { //pretty old
+ health = 0; // kill creature - no chance to live
+ }
+ }
+ }
+
+ private void feed() {
+ int morsel = 0;
+ int creature_share = 0;
+ if (Life.total < Life.maxTotal && 0 < Life.food) {
+ creature_share = Life.food/Life.total;
+ morsel = creature_share / (Life.rand.nextInt(99) + 1);
+ if (morsel == 0) {
+ morsel = 2;
+ }
+ Life.food -= morsel;
+ health += morsel;
+ } else {
+ health -=50;
+ }
+ // base.log.add(name + "/" + health + " feeds " + morsel + " of " + creature_share);
+ }
+
+ private void incTotal() {
+ synchronized (lock) {
+ Life.total++;
+ }
+ }
+
+ private void decTotal() {
+ synchronized (lock) {
+ Life.total--;
+ }
+ }
+
+}
\ No newline at end of file
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/LifeSimulationTest/Life.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/RecursiveThreadTest/RecursiveTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/RecursiveThreadTest/RecursiveTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/RecursiveThreadTest/RecursiveTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/RecursiveThreadTest/RecursiveTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.5 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.RecursiveThreadTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+
+/**
+ * Goal: check that VM supports volatile variables
+ * The test does:
+ * 1. Reads parameters, which are:
+ * param[0] - depth of recursion of threads
+ * param[1] - size of Object array for each thread
+ * 2. Starts first thread, which starts the next one and so on ...
+ *
+ * 3. Each thread (except the last), being started:
+ * a. Starts child thread
+ * b. Creates param[1]-sized array of Object and fills it
+ * c. Changes parent's flag to allow it finish
+ * d. Finishes run if child thread allowed
+ *
+ */
+
+
+public class RecursiveTest extends Test {
+
+ public static int depth = 1000;
+ public static int size = 1000;
+ public static volatile boolean finish = false;
+
+ public static void main(String[] args) {
+ System.exit(new RecursiveTest().test(args));
+ }
+
+ public int test(String[] params) {
+ finish = false;
+ parseParams(params);
+ recurThread grandpa = new recurThread();
+ recurThread dad = (new recurThread(grandpa));
+ dad.start();
+ /*
+ try {
+ dad.join();
+ log.add("Thread dad joined()");
+ } catch (InterruptedException ie) {
+ return fail("interruptedException while join of thread");
+ }
+ */
+ while (!finish) {};
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ depth = Integer.parseInt(params[0]);
+ if (params.length >= 2) {
+ size = Integer.parseInt(params[1]);
+ }
+ }
+ }
+
+}
+
+class recurThread extends Thread {
+ recurThread parent;
+
+ volatile boolean flag;
+
+ public recurThread() {
+ flag = true;
+ }
+
+ public recurThread(recurThread pt) {
+ parent = pt;
+ flag = false;
+ }
+
+ private void doSomething() {
+ // just wasting memory
+ Object[] array = new Object[RecursiveTest.size];
+ for (int i = 0; i < RecursiveTest.size; i++) {
+ array[i] = new recurThread();
+ }
+ }
+
+ public void run() {
+ RecursiveTest.depth--;
+ //RecursiveTest.log.add("d=" + RecursiveTest.depth);
+ if (RecursiveTest.depth > 0) { //is this the last thread?
+ //no, starts another
+ recurThread rt = new recurThread(this);
+ rt.start();
+ doSomething();
+ } else { //yes
+ flag = true;
+ RecursiveTest.finish = true; // stop test
+ }
+ parent.flag = true; //allow to parent thread finish
+
+ //waiting for permission to finish from child
+ while (!flag) {
+ Thread.yield();
+ };
+ return;
+ }
+
+}
+
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/RecursiveThreadTest/RecursiveTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/StackTraceTest/StackTraceTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/StackTraceTest/StackTraceTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/StackTraceTest/StackTraceTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/StackTraceTest/StackTraceTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,417 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Oleg Oleinik
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.StackTraceTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.util.Random;
+
+/*
+ * Goal: check that Thread's getStackTrace() and getAllStackTraces() do not
+ * cause crashes or hangs or memory leaks.
+ *
+ * The test does:
+ *
+ * 1. Starts N_OF_THREADS threads of a dozen of various types.
+ * Types of threads differ in which locks they hold and free in waits
+ * when stackTrace methods are called.
+ *
+ * 2. For each started thread calls getStackTrace() (and getAllStackTraces()).
+ *
+ * 3. Interrupts all started threads and waits for their completion.
+ *
+ * 4. Expected result: no crashes or hangs.
+ */
+
+
+public class StackTraceTest extends Test {
+
+ static int N_OF_THREADS = 5;
+
+ public static void main(String[] args) {
+ System.exit(new StackTraceTest().test(args));
+ }
+
+ public int test(String[] params) {
+
+ parseParams(params);
+
+ return (test(true) && test(false)) ? pass("OK") : fail("");
+ }
+
+ boolean test(boolean daemon) {
+
+ boolean failed = false;
+
+ ThreadCounter.clear();
+
+ Thread[][] t = new Thread[11][N_OF_THREADS];
+
+ Object[] o1 = new Object[10];
+ int[] o2 = new int[100];
+
+ for (int i = 0; i < t[0].length; ++i){
+ t[0][i] = new A();
+ t[1][i] = new B();
+ t[2][i] = new C();
+ t[3][i] = new D();
+ t[4][i] = new E();
+ t[5][i] = new F();
+ t[6][i] = new G();
+ t[7][i] = new H();
+ // all these I-type threads will lock/wait Object[] object
+ t[8][i] = new I(o1);
+ // all these I-type threads will lock/wait int[] object
+ t[9][i] = new I(o2);
+ t[10][i] = new J();
+ }
+
+ for (int i = 0; i < t.length; ++i){
+ for (int j = 0; j < t[i].length; ++j) {
+ t[i][j].setDaemon(daemon);
+ t[i][j].start();
+ }
+ }
+
+ // No synchronization. We call stack trace methods independently
+ // from where the started threads are. The only expectation is
+ // that they are actually running.
+
+ while (ThreadCounter.getRunning() < t.length * t[0].length) {
+ Thread.yield();
+ }
+ // System.out.println("All threads are running...");
+
+ for (int i = 0; i < t.length; ++i){
+
+ for (int j = 0; j < t[i].length; ++j) {
+
+ t[i][j].getStackTrace();
+
+ // currentThread() call has no special meaning, just in case
+ if (Thread.currentThread() == null) {
+ if (!failed) { // log failure only once to avoid overwhelming in log
+ log.add("currentThread() returned null unexpectedly");
+ }
+ failed = true;
+ }
+
+ Thread.getAllStackTraces();
+ Thread.yield();
+ }
+ }
+
+ for (int i = 0; i < t.length; ++i){
+ for (int j = 0; j < t[i].length; ++j) {
+ t[i][j].interrupt();
+ try {
+ t[i][j].join();
+ // System.out.println("Joined thread " + i + " / " + j);
+ } catch (InterruptedException ie) {
+ System.out.println("InteruptedException while joining all started A,B,C,D... threads");
+ }
+ }
+ }
+
+ return !failed;
+ }
+
+ public void parseParams(String[] params) {
+ }
+}
+
+ // A thread invoking synchronized static method which holds A.class lock
+ // and waits infinitely (actually, until the thread is interrupted)
+
+class A extends BaseThread {
+
+ public void run() {
+ m(this);
+ }
+
+ static synchronized void m(Thread t) {
+ try {
+ ThreadCounter.incRunning();
+ while (!t.isInterrupted()) {
+ A.class.wait();
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("A: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking static method which holds newly created Object lock
+ // and waits infinitely (actually, until the thread is interrupted)
+
+class B extends BaseThread {
+
+ public void run() {
+ m(this);
+ }
+
+ static void m(Thread t) {
+ try {
+ B b = new B();
+ synchronized(b) {
+ ThreadCounter.incRunning();
+ while (!t.isInterrupted()) {
+ b.wait();
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("B: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which holds 'this' object lock
+ // and waits infinitely (actually, until the thread is interrupted)
+
+class C extends BaseThread {
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ synchronized(this) {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ this.wait();
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("C: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking synchronized instance method which holds 'this'
+ // and newly created Object locks and waits infinitely (actually, until
+ // the thread is interrupted)
+
+class D extends BaseThread {
+
+ public void run() {
+ m();
+ }
+
+ synchronized void m() {
+ try {
+ synchronized(new D()) {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ this.wait();
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("D: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which just sleeps in 'try' section
+ // infinitely (actually, until the thread is interrupted)
+
+class E extends BaseThread {
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ Thread.sleep(100);
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("E: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which just sleeps in 'catch' section
+ // infinitely (actually, until the thread is interrupted)
+
+class F extends BaseThread {
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ try {
+ throw new NullPointerException("npe");
+ } catch (NullPointerException npe) {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ Thread.sleep(100);
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("F: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which just sleeps in 'finally' section
+ // infinitely (actually, until the thread is interrupted)
+
+class G extends BaseThread {
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ try {
+ throw new NullPointerException("npe");
+ } catch (NullPointerException npe) {
+ } finally {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ Thread.sleep(100);
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("G: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which holds static newly created Object
+ // and waits infinitely (actually, until the thread is interrupted)
+
+class H extends BaseThread {
+
+ static H h = new H();
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ synchronized (h) {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ h.wait(100);
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("H: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+ // A thread invoking instance method which holds a lock to array of
+ // objects and waits infinitely (actually, until the thread is interrupted)
+
+class I extends BaseThread {
+
+ Object o = null;
+
+ public I(Object o) {
+ this.o = o;
+ }
+
+ public void run() {
+ m();
+ }
+
+ void m() {
+ try {
+ synchronized (o) {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ o.wait();
+ }
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("I1: interrupted, InterruptedException");
+ return;
+ }
+ }
+}
+
+
+ // A thread invoking instance method which is recursively invokes itself
+ // at the end holds 'this' lock and waits infinitely (actually, until
+ // the thread is interrupted).
+
+class J extends BaseThread {
+
+ public void run() {
+ m(20);
+ }
+
+ void m(int depth) {
+ if (depth > 0){
+ m(depth -1);
+ } else {
+ synchronized (this) {
+ try {
+ ThreadCounter.incRunning();
+ while (!this.isInterrupted()) {
+ this.wait();
+ }
+ } catch (InterruptedException ie) {
+ // System.out.println("J: interrupted, InterruptedException");
+ }
+ }
+ }
+ }
+}
+
+class BaseThread extends Thread {
+ // just in case - if some common functionality will be needed
+}
+
+class ThreadCounter {
+
+ static volatile int running = 0;
+
+ static synchronized int getRunning() {
+ return running;
+ }
+
+ static synchronized void incRunning() {
+ running++;
+ }
+
+ static synchronized void clear() {
+ running = 0;
+ }
+}
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/StackTraceTest/StackTraceTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,237 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.3 $
+ */
+package org.apache.harmony.test.reliability.api.kernel.thread.Synchronization;
+import org.apache.harmony.test.reliability.share.Test;
+
+/**
+ * Goal: check thread synchronization
+ * The test does:
+ * 1. Reads parameter, which is:
+ * param[0] - number of iterations to run each thread
+ * 2. Create 7 threads which work with the same object
+ * - The object has several variables that are changed by various methods
+ * with "synchronized" block.
+ * 3. Checks that each thread PASSed.
+ * 4. Each thread, being started:
+ * a. Runs param[0] iterations in a cycle, on each iteration:
+ * b. call method with "synchronized" block.
+ * c. stops if variable changed in "synchronized" block.
+ */
+
+public class SynchroTest extends Test {
+ static int iteration = 50;
+ static volatile int finish;
+
+ SynchroThread[] synchroThread = new SynchroThread[7];
+
+
+ public static void main(String[] args) {
+ System.exit(new SynchroTest().test(args));
+ }
+
+ public int test(String[] params) {
+
+ parseParams(params);
+ WorkingClass workingObj = new WorkingClass();
+
+ synchroThread[0] = new SynchroThread(workingObj, 1);
+ synchroThread[1] = new SynchroThread(workingObj, 2);
+ synchroThread[2] = new SynchroThread(workingObj, 3);
+ synchroThread[3] = new SynchroThread(workingObj, 4);
+ synchroThread[4] = new SynchroThread(workingObj, 12);
+ synchroThread[5] = new SynchroThread(workingObj, 34);
+ synchroThread[6] = new SynchroThread(workingObj, 1234);
+
+ finish = synchroThread.length;
+ for (int i = 0; i < synchroThread.length; i++) {
+ synchroThread[i].start();
+ }
+ while(finish > 0) {};
+
+ for (int i = 0; i < synchroThread.length; i++) {
+ if (synchroThread[i].status == SynStatus.FAIL) {
+ log.add("Status of thread " + i + " is FAIL");
+ return fail("Synchronization is broken");
+ }
+ }
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ iteration = Integer.parseInt(params[0]);
+ }
+ }
+
+}
+
+class SynchroThread extends Thread {
+ WorkingClass workingObj;
+ int selector;
+ int iteration;
+ int status;
+
+ public SynchroThread(WorkingClass wc, int sel) {
+ workingObj = wc;
+ selector = sel;
+ iteration = SynchroTest.iteration;
+ status = SynStatus.PASS;
+ }
+
+ public void run() {
+ boolean res = true;
+
+ while (res && iteration-- > 0 ) {
+ switch (selector) {
+ case 1:
+ res = workingObj.do_1();
+ case 2:
+ res = workingObj.do_2();
+ case 12:
+ res = workingObj.do_12();
+ case 3:
+ res = workingObj.do_3();
+ case 4:
+ res = workingObj.do_4();
+ case 34:
+ res = workingObj.do_34();
+ case 1234:
+ res = workingObj.do_1234();
+ }
+ if (!res) {
+ status = SynStatus.FAIL;
+ }
+ }
+ synchronized (workingObj) {
+ SynchroTest.finish--;
+ }
+ return;
+ }
+
+}
+
+class WorkingClass {
+ public int var1;
+ public int var2;
+ public int var3;
+ public int var4;
+ public Object lock12;
+ public Object lock34;
+ public Object lock1234;
+
+
+ WorkingClass (){
+ var1 = 0;
+ var2 = 0;
+ var3 = 0;
+ var4 = 0;
+ lock12 = new Object();
+ lock34 = new Object();
+ lock1234 = new Object();
+ }
+
+
+ public boolean do_1() {
+ boolean result;
+ synchronized (lock12) {
+ var1 = 1;
+ Thread.yield();
+ result = (var1 == 1);
+ }
+ return result;
+ }
+
+
+ public boolean do_2() {
+ boolean result;
+ synchronized (lock12) {
+ var2 = 2;
+ Thread.yield();
+ result = (var2 == 2);
+ }
+ return result;
+ }
+
+ public boolean do_12() {
+ boolean result;
+ synchronized (lock12) {
+ var1 = 12;
+ var2 = 12;
+ Thread.yield();
+ result = ((var1 == 12) && (var2 == 12));
+ }
+ return result;
+ }
+
+ public boolean do_3() {
+ boolean result;
+ synchronized (lock34) {
+ var3 = 3;
+ Thread.yield();
+ result = (var3 == 3);
+ }
+ return result;
+ }
+
+ public boolean do_4() {
+ boolean result;
+ synchronized (lock34) {
+ var4 = 4;
+ Thread.yield();
+ result = (var4 == 4);
+ }
+ return result;
+ }
+
+ public boolean do_34() {
+ boolean result;
+ synchronized (lock34) {
+ var3 = 34;
+ var4 = 34;
+ Thread.yield();
+ result = ((var3 == 34) && (var3 == 34));
+ }
+ return result;
+ }
+
+ public boolean do_1234() {
+ boolean result;
+ synchronized (lock12) {
+ synchronized (lock34) {
+ var1 = 1234;
+ var2 = 1234;
+ var3 = 1234;
+ var4 = 1234;
+ Thread.yield();
+ result = ((var1 == 1234) && (var2 == 1234) && (var3 == 1234) && (var4 == 1234));
+ }
+ }
+ return result;
+ }
+}
+
+class SynStatus {
+ public static final int FAIL = -1;
+ public static final int PASS = 1;
+}
+
+
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest2.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest2.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest2.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest2.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.2 $
+ */
+package org.apache.harmony.test.reliability.api.kernel.thread.Synchronization;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Random;
+/**
+ * Goal: check thread synchronization.
+ * Test simulates write to tape. There are 2 types of writer.
+ * Each writer writes series of int values on "tape".
+ * Type1 has right to exclusive write - no one can interrupte it during writing.
+ * The test does:
+ * 1. Reads parameter, which is:
+ * param[0] - number of threads
+ * param[1] - length of series
+ * 2. Creates and starts param[0] writers/threads (Type1 or Type 2 is selected randomly)
+ * 3. Each writer/thread, being started writes on "tape" series of int.
+ * 4. After all writers finished checks that the tape has
+ * uninterrupted series written by type1 writer.
+ */
+
+
+public class SynchroTest2 extends Test {
+ static int iteration = 50;
+ static volatile int finish;
+ static Object finlock = new Object();
+
+ Tape tape = new Tape();
+ int thread_number = 20;
+
+ static int serial = 5;
+
+ public static void main(String[] args) {
+ System.exit(new SynchroTest2().test(args));
+ }
+
+ public int test(String[] params) {
+ int l;
+ Random rand = new Random();
+ int key4type1 = 1000;
+ int key4type2 = 0;
+ int key = key4type1;
+
+ parseParams(params);
+ finish = thread_number;
+ for (int i = 0; i < thread_number; i++) {
+ l = rand.nextInt(3);
+ if (l == 1) {
+ new WriterType1(key4type1++, tape).start();
+ } else {
+ new WriterType2(key4type2++, tape).start();
+ }
+ }
+ while (finish > 0) {} ;
+
+ l = tape.size();
+ for (int i = 0; i < l; i++) {
+ int k = tape.get(i);
+ if (k >= key) {
+ for (int j = 1; j < serial; j++) {
+ int m = tape.get(++i);
+ //log.add("#" + m);
+ if (m != k) {
+ return fail("wrong record!");
+ }
+ }
+ } else {
+ // log.add(" " + tape.get(i));
+ }
+ }
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ thread_number = Integer.parseInt(params[0]);
+ if (params.length >= 2) {
+ serial = Integer.parseInt(params[1]);
+ }
+ }
+ }
+
+}
+
+class Lock {
+ private int active_writers1;
+ private int active_writers2;
+ private int waiting_writers2;
+
+ private final LinkedList writerLocks = new LinkedList(); //list of locks
+ // for writers
+
+ public synchronized void request_write2() {
+ if (active_writers1 == 0 && writerLocks.size() == 0) {
+ active_writers2++;
+ } else {
+ waiting_writers2++;
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ //just ignore
+ }
+ }
+ }
+
+ public synchronized void write2_accomplished() {
+ if (--active_writers2 == 0)
+ notify_writers1();
+ }
+
+ public void request_write1() {
+ Object lock = new Object();
+ synchronized (lock) {
+ synchronized (this) {
+ boolean okay_to_write = (writerLocks.size() == 0
+ && active_writers2 == 0 && active_writers1 == 0);
+ if (okay_to_write) {
+ active_writers1++;
+ return; // the "return" jumps over the "wait" call
+ }
+ writerLocks.addLast(lock);
+ }
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ public synchronized void write1_accomplished() {
+ active_writers1--;
+ if (waiting_writers2 > 0) // priority to waiting writers2
+ notify_writers2();
+ else
+ notify_writers1();
+ }
+
+ private void notify_writers2() { // must be accessed from a synchronized
+ // method
+ active_writers2 += waiting_writers2;
+ waiting_writers2 = 0;
+ notifyAll();
+ }
+
+ private void notify_writers1() { // must be accessed from a synchronized
+ // method
+ if (writerLocks.size() > 0) {
+ Object oldest = writerLocks.removeFirst();
+ active_writers1++;
+ synchronized (oldest) {
+ oldest.notify();
+ }
+ }
+ }
+}
+
+class WriterType1 extends Thread {
+ private Tape tape;
+
+ private int key;
+
+ public WriterType1(int k, Tape tape) {
+ this.tape = tape;
+ key = k;
+ }
+
+ public void run() {
+ //SynchroTest2.log.add("WT1:" + key + "started");
+ tape.write1(key);
+ synchronized (SynchroTest2.finlock) {
+ SynchroTest2.finish--;
+ // SynchroTest2.log.add("WT1:" + key + "finished");
+ }
+ }
+}
+
+class WriterType2 extends Thread {
+ private Tape tape;
+
+ private int key;
+
+ public WriterType2(int k, Tape tape) {
+ this.tape = tape;
+ key = k;
+ }
+
+ public void run() {
+ //SynchroTest2.log.add("WT2:" + key + "started");
+ tape.write2(key);
+ synchronized (SynchroTest2.finlock) {
+ SynchroTest2.finish--;
+ // SynchroTest2.log.add("WT2:" + key + "finished");
+ }
+ }
+}
+
+class Tape {
+ Lock lock = new Lock();
+ ArrayList al;
+
+ public Tape() {
+ lock = new Lock();
+ al = new ArrayList();
+ }
+
+ public int size() {
+ return al.size();
+ }
+
+ public int get(int i) {
+ return ((Integer) al.get(i)).intValue();
+ }
+
+ public synchronized void add(Object obj) {
+ al.add(obj);
+ }
+
+ public void write1(int w1) {
+ try {
+ lock.request_write1();
+ try {
+ for (int i = 0; i < SynchroTest2.serial; i++) {
+ add(new Integer(w1));
+ Thread.sleep(500);
+ }
+ } catch (InterruptedException e) {
+ }
+ } finally {
+ lock.write1_accomplished();
+ }
+ }
+
+ public void write2(int w2) {
+ try {
+ lock.request_write2();
+ try {
+ for (int i = 0; i < SynchroTest2.serial; i++) {
+ add(new Integer(w2));
+ Thread.sleep(500);
+ }
+ } catch (InterruptedException e) {
+ }
+ } finally {
+ lock.write2_accomplished();
+ }
+ }
+}
+
+
+
+
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/Synchronization/SynchroTest2.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadArrayTest/ThreadArrayTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadArrayTest/ThreadArrayTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadArrayTest/ThreadArrayTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadArrayTest/ThreadArrayTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.ThreadArrayTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+
+/**
+ * Goal: check VM thread subsystem/GC cooperations
+ * The test does:
+ * 1. Reads parameters, which are:
+ * param[0] - number of threads,
+ * param[1] - how times each thread starts
+ * 2. Creates param[0]-sized array of threads and starts each of them
+ * 3. call .join() for each thread
+ * 4. repeat steps 2-3 param[1] times
+ * No exceptions must be trown.
+ *
+ */
+
+public class ThreadArrayTest extends Test {
+
+ public static int THREADS_COUNT = 128;
+ public static int CYCLES_COUNT = 1000;
+
+ public static int[] table;
+
+ public static void main(String[] args) {
+ System.exit(new ThreadArrayTest().test(args));
+ }
+
+ public int test(String[] params) {
+ parseParams(params);
+ table = new int[THREADS_COUNT];
+
+ for (int i = 0; i < CYCLES_COUNT; i++) {
+ Thread t[] = new Thread[THREADS_COUNT];
+ for (int k = 0; k < t.length; k++) {
+ t[k] = new ThreadTest(k);
+ t[k].start();
+ }
+ try {
+ for (int k = 0; k < t.length; k++) {
+ t[k].join();
+ }
+ } catch (InterruptedException ie) {
+ return fail("interruptedException while join of threads");
+ }
+ }
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ THREADS_COUNT = Integer.parseInt(params[0]);
+ if (params.length >= 2) {
+ CYCLES_COUNT = Integer.parseInt(params[1]);
+ }
+ }
+ }
+
+}
+
+
+class ThreadTest extends Thread {
+ private int index;
+
+ public ThreadTest(int index) {
+ this.index = index;
+ }
+
+ public void run() {
+ ThreadArrayTest.table[index]++;
+ new Object();
+ }
+}
\ No newline at end of file
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadArrayTest/ThreadArrayTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadKill/ThreadKillTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadKill/ThreadKillTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadKill/ThreadKillTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadKill/ThreadKillTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2006 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Igor A. Pyankov
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.ThreadKill;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Random;
+
+import org.apache.harmony.test.reliability.share.Test;
+
+/**
+ * Goal: check VM thread subsystem/GC cooperations
+ * The test does:
+ * 1. Reads parameters, which are:
+ * param[0] - number of threads
+ * param[1] - how times repeat test
+ * 2. Creates param[0]-sized array of threads and starts them
+ * There are 2 kind of threads - math (does some calculation)
+ * and input/output (imitates output)
+ * 3. randomly interrupts threads
+ * 4. interrupts remaining threads
+ * 5. call .join() for each thread to sure that
+ * all threads have been killed
+ * 6. repeat 2-5 param[1] times
+ *
+ * No exceptions must be trown.
+ *
+ */
+
+public class ThreadKillTest extends Test {
+ public static Random rand = new Random();
+ public static Object lock = new Object();
+ public static int THREADS_COUNT = 10;
+ public static int CYCLES_COUNT = 10;
+ public static int[] table;
+ public static volatile int started = 0;
+
+ public static void main(String[] args) {
+ System.exit(new ThreadKillTest().test(args));
+ }
+
+ public int test(String[] params) {
+ parseParams(params);
+ //table = new int[THREADS_COUNT];
+ started = 0;
+ for (int i = 0; i < CYCLES_COUNT; i++) {
+ Thread t[] = new Thread[THREADS_COUNT];
+ for (int k = 0; k < THREADS_COUNT;) {
+ t[k] = new MathThread(k);
+ k++;
+ t[k] = new IOThread(k);
+ k++;
+ }
+ try {
+ for (int k = 0; k < THREADS_COUNT; k++) {
+ t[k].start();
+ }
+ // just wait for all threads started
+ while (started < THREADS_COUNT) {
+ Thread.yield();
+ }
+ // random murder
+ for (int k = 0; k < THREADS_COUNT*5; k++) {
+ int j = rand.nextInt(THREADS_COUNT);
+ t[j].interrupt();
+ }
+
+ //to kill survived thread
+ for (int k = 0; k < THREADS_COUNT; k++) {
+ if (!t[k].isInterrupted()) {
+ t[k].interrupt();
+ }
+ }
+
+ // wait for till all threads will be killed
+ int l = 1;
+ while (l > 0) {
+ l = 0;
+ for (int k = 0; k < THREADS_COUNT; k++) {
+ if (t[k].isAlive()) {
+ l++;
+ }
+ Thread.yield();
+ }
+ }
+ // to be sure all started treads are killed
+ for (int k = 0; k < THREADS_COUNT; k++) {
+ t[k].interrupt();
+ t[k].join();
+ }
+ } catch (InterruptedException ie) {
+ return fail("interruptedException while join of threads");
+ }
+ }
+ return pass("OK");
+ }
+
+ public void parseParams(String[] params) {
+ if (params.length >= 1) {
+ THREADS_COUNT = Integer.parseInt(params[0]);
+ if (params.length >= 2) {
+ CYCLES_COUNT = Integer.parseInt(params[1]);
+ }
+ }
+ }
+
+}
+
+
+class MathThread extends Thread {
+ private int index;
+
+ public MathThread(int index) {
+ this.index = index;
+ }
+
+ public void run() {
+ // just verify sin^2+cos^2==1
+ double alfa;
+ double sinalfa;
+ double cosalfa;
+ double beta ;
+ double gamma = 1.0D;
+ double delta = 1.0E-17;
+ int num_errors = 0;
+ ThreadKillTest.started++;
+
+ //ThreadKillTest.log.add("Theard " + index + " started");
+ while (true) {
+ alfa = ThreadKillTest.rand.nextDouble() * 2.D * java.lang.Math.PI;
+ cosalfa = java.lang.Math.cos(alfa);
+ sinalfa = java.lang.Math.sin(alfa);
+ beta = sinalfa * sinalfa + cosalfa * cosalfa;
+
+ if (java.lang.Math.abs(beta - gamma) > delta) {
+ // ThreadKillTest.log.add(index + " error " + beta);
+ num_errors++;
+ } else {
+ //ThreadKillTest.log.add (index + " OK " + beta);
+ }
+
+ // place to kill thread
+ synchronized (ThreadKillTest.lock) {
+ try {
+ ThreadKillTest.lock.wait(500);
+ } catch (InterruptedException ie) {
+ //ThreadKillTest.log.add("MathTheard " + index + " killed");
+ return;
+ }
+ }
+ }
+ }
+}
+
+class IOThread extends Thread {
+ private int index;
+ private int buflen = 256;
+ private byte b[];
+ public IOThread(int index) {
+ this.index = index;
+ }
+
+ public void run() {
+ int k = 1;
+ FakeInputStream fis = new FakeInputStream ();
+ FakeOutputStream fos = new FakeOutputStream ();
+ ThreadKillTest.started++;
+
+ //ThreadKillTest.log.add("Theard " + index + " started");
+ while (k > 0) {
+
+ b = new byte[buflen];
+ try {
+ k = fis.read(b);
+ } catch (IOException ie1) {
+ k = -10;
+ }
+ if (k >= 0) {
+ for (int i = 0; i < k; i++) {
+ b[i] = (byte) (b[i] + 12);
+ }
+
+ try {
+ fos.write(b, 0, k - 1);
+ } catch (IOException ie2) {
+ k = -20;
+ }
+ }
+ // place to kill thread
+ synchronized (ThreadKillTest.lock) {
+ try {
+ ThreadKillTest.lock.wait(100);
+ } catch (InterruptedException ie) {
+ //ThreadKillTest.log.add("IOThread " + index + " killed");
+ return;
+ }
+ }
+ }
+ }
+}
+
+class FakeOutputStream extends OutputStream {
+ private byte b[];
+ private int pointer;
+ private int buflen = 128;
+
+ public FakeOutputStream () {
+ b = new byte [buflen];
+ pointer = 0;
+ }
+
+ public void write(int arg) throws IOException {
+ // fills buffer and does nothing
+ b[pointer++]=(byte) arg;
+ if (pointer == buflen) {
+ pointer = 0;
+ }
+ }
+}
+
+class FakeInputStream extends InputStream {
+ private byte b[];
+ private int pointer;
+ private int buflen = 128;
+
+ public FakeInputStream() {
+ b = new byte[buflen];
+ ThreadKillTest.rand.nextBytes(b);
+ pointer = 0;
+ }
+
+ public int read() throws IOException {
+ if (pointer == buflen) {
+ pointer = 0;
+ ThreadKillTest.rand.nextBytes(b);
+ }
+ return (int) b[pointer++];
+ }
+}
\ No newline at end of file
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadKill/ThreadKillTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadLocalTest/ThreadLocalTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadLocalTest/ThreadLocalTest.java?view=auto&rev=545554
==============================================================================
--- harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadLocalTest/ThreadLocalTest.java (added)
+++ harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadLocalTest/ThreadLocalTest.java Fri Jun 8 09:34:52 2007
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2007 The Apache Software Foundation or its licensors, as applicable
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @author Oleg Oleinik
+ * @version $Revision: 1.1 $
+ */
+
+package org.apache.harmony.test.reliability.api.kernel.thread.ThreadLocalTest;
+
+import org.apache.harmony.test.reliability.share.Test;
+import java.util.Random;
+import java.util.Vector;
+
+/*
+ * Goal: check that ThreadLocals work as expected, i.e. really are thread-own
+ * copies of objects which can't be affected by other than the calling thread.
+ *
+ * The test does:
+ *
+ * 1. Reads parameters:
+ * params[0] - number of child threads of each thread in the tree
+ * params[1] - depth of the tree
+ *
+ * 2. Creates a Thread tree:
+ * r o o t level params[1].
+ * / | \
+ * t t t level params[1]-1. Each thread has param[0] child threads
+ * / | \ ... / | \
+ * level 0.
+ *
+ * Each created thread is started.
+ * Each thread has instance ThreadLocal variable. There is static LocalVariable as well.
+ * Each thread holds references to all its childs, parent and itself ('this').
+ *
+ * 3. Each running thread sets its private objects to thread local variables of:
+ * child threads, parent and itself and checks that variables are set correctly.
+ *
+ */
+
+
+public class ThreadLocalTest extends Test {
+
+ static int N_OF_THREADS = 2;
+
+ static int DEPTH = 6;
+
+ public static void main(String[] args) {
+ System.exit(new ThreadLocalTest().test(args));
+ }
+
+ public int test(String[] params) {
+
+ parseParams(params);
+
+ // threads: non-daemon/daemon
+
+ return (test(false) && test(false)) ? pass("OK") : fail("");
+ }
+
+ boolean test(boolean daemon) {
+
+ ThreadCounter.clear();
+
+ // First, tree building and tree's threads running starts here:
+ ThreadWithLocals t = new ThreadWithLocals(0, null, DEPTH, daemon);
+ t.setDaemon(daemon);
+ t.start();
+
+ // At this point all threads are running and doing (or already completed)
+ // set()s/get()s and checks.
+ // Lets wait they _all_ complete checks and fall into infinite cycle,
+ // that means that we can join() them and finish the test.
+
+ while(ThreadCounter.getCreated() != ThreadCounter.getFinishing()){
+ Thread.yield();
+ }
+
+ // System.out.println("All " + ThreadCounter.getCreated() + " threads are finishing");
+
+ // At this point, all threads are in infinite cycle waiting
+ // for the exit flag set, lets set the flag thus allow them to complete
+
+ ThreadCounter.setExitAllowed();
+
+ // System.out.println("Exit allowed, joining all... ");
+
+ // Join all threads
+ ThreadCounter.joinAllThreads();
+
+ // System.out.println("All threads joined");
+
+ // Finally, return results of checks done by the threads
+ return ThreadCounter.getStatus();
+ }
+
+
+ public void parseParams(String[] params){
+ if (params.length >= 1) {
+ N_OF_THREADS = Integer.parseInt(params[0]);
+ }
+ if (params.length >= 2) {
+ DEPTH = Integer.parseInt(params[1]);
+ }
+ }
+
+}
+
+class ThreadWithLocals extends Thread {
+
+ static Random RND = new Random(10);
+
+ volatile boolean running = false;
+
+ ThreadWithLocals[] t = null;
+ int ID;
+ int[] Arr;
+ SomeObject Obj;
+
+ ThreadLocal tl_var_instance = new ThreadLocal<SomeObject>() {
+ };
+
+ static ThreadLocal tl_var_static = new ThreadLocal<int[]>() {
+ };
+
+ ThreadWithLocals (int ID, ThreadWithLocals parent, int depth, boolean daemon) {
+ super();
+ this.running = false;
+ this.ID = ID;
+ this.Arr = new int[1];
+ this.Arr[0] = ID;
+ this.Obj = new SomeObject(ID);
+
+ // System.out.println("Creating " + ID);
+
+ ThreadCounter.incCreated(this);
+
+ if (depth > 0) {
+ // 't' holds references to N_OF_THREADS child threads and parent and itself:
+ t = new ThreadWithLocals[ThreadLocalTest.N_OF_THREADS + 2];
+ t[0] = parent;
+ t[1] = this;
+ for (int i = 2; i < t.length; ++i){
+ // (ID * t.length + i) is used as formula for child IDs to make IDs unique
+ t[i] = new ThreadWithLocals(ID * t.length + i, this, depth - 1, daemon);
+
+ // System.out.println("Thread " + ID + " -> " + (ID * t.length + i) + " child thread");
+ t[i].setDaemon(daemon);
+ t[i].start();
+ }
+ } else {
+ // this is leaf thread - it has no child threads, so, holds only
+ // references to parent and itself
+ t = new ThreadWithLocals[2];
+ t[0] = parent;
+ t[1] = this;
+ }
+ }
+
+ synchronized boolean isRunning(){
+ return running;
+ }
+
+ synchronized void setRunning(){
+ running = true;
+ }
+
+ public void run() {
+
+ setRunning();
+
+ // Each thread calls set()/get() and checks local variables of all
+ // threads listed in 't' (e.g. child threads, parent and itself) expecting that
+ // in concurrently running threads environment when other threads are changing
+ // the same variables, the variables are really _this_ thread-local (e.g. other
+ // threads' modifications do not affect _this_ thread's variables).
+
+ for (int i = 0; i < t.length; ++i) {
+
+ if (t[i] != null) {
+
+ // thread local variables live when the thread is alive,
+ // this check is to avoid that t[i] is started but not actually running;
+ // avoiding that some thread finished and is not alive is guaranteed
+ // below by hangUntilExitAllowed().
+
+ while(!t[i].isRunning()) {
+ Thread.yield();
+ }
+
+ // System.out.println(" Thread ID=" + ID + " - all necessary threads are alive");
+
+ int rndNumber = RND.nextInt(100) + 1;
+ for (int j = 0; j < rndNumber; ++j){
+ t[i].tl_var_static.set(this.Arr); // TEST call
+ Thread.yield();
+ }
+
+ rndNumber = RND.nextInt(100) + 1;
+ for (int j = 0; j < rndNumber; ++j){
+ t[i].tl_var_instance.set(this.Obj); // TEST call
+ Thread.yield();
+ }
+ }
+ }
+
+ ThreadCounter.joinStatus(check()); // Add status of checks of this thread to the common flag
+
+ // Signal that set()s/get()s/checks are finished; When all created threads signalled
+ // they finished, the main thread ThreadLocalTest can allow threads exit from
+ // hangUntilExitAllowed() infinite cycle.
+ ThreadCounter.incFinishing();
+
+ // System.out.println(" Thread ID=" + ID + " is going to hang before exit...");
+
+ ThreadCounter.hangUntilExitAllowed(); // Fall into infinite cycle waiting for certain flag set
+ }
+
+
+ boolean check() {
+
+ boolean passed = true;
+
+ for (int i = 0; i < t.length; ++i){
+ if (t[i] == null) {
+ continue;
+ }
+
+ int rndNumber = RND.nextInt(100) + 1;
+
+ boolean printed1 = false;
+ boolean printed2 = false;
+
+ for (int j = 0; j < rndNumber; ++j){
+
+ int[] arrThreadLocal = ((int[])t[i].tl_var_static.get()); // TEST call
+
+ // TEST checks - if variables are really thread local then the values
+ // of the variables must be this.Arr and this.Obj despite of other threads
+ // set their values to the same variables
+
+ if (arrThreadLocal != this.Arr) {
+ if (!printed1) {
+ System.out.println("Thread ID=" + this.ID + " checked value of thread ID=" + t[i].ID +
+ "'s _static_ ThreadLocal variable: get() returned wrong object " +
+ arrThreadLocal + " instead of " + this.Arr);
+ printed1 = true;
+ }
+ passed &= false;
+ }
+
+ SomeObject objThreadLocal = ((SomeObject)t[i].tl_var_instance.get()); // TEST call
+
+ if (objThreadLocal != this.Obj) {
+ if (!printed2) {
+ System.out.println("Thread ID=" + this.ID + " checked value of thread ID=" + t[i].ID +
+ "'s _instance_ ThreadLocal variable: get() returned wrong object " +
+ objThreadLocal + " instead of " + this.Obj);
+ printed2 = true;
+ }
+ passed &= false;
+ }
+ }
+
+ // System.out.println("Thread ID=" + ID + " checked " + t[i].ID + " thread's locals");
+ }
+
+ return passed;
+ }
+
+}
+
+class SomeObject {
+ int i = 0;
+
+ SomeObject(int i) {
+ this.i = i;
+ }
+
+ int getI() {
+ return i;
+ }
+}
+
+class ThreadCounter {
+
+ static volatile boolean status = true;
+ static volatile int finishing = 0;
+ static volatile int created = 0;
+
+ static volatile boolean isExitAllowed = false;
+
+ static Vector threadsVector = new Vector();
+
+
+ static synchronized void joinStatus(boolean passed) {
+ status &= passed;
+ }
+
+ static synchronized boolean getStatus() {
+ return status;
+ }
+
+ static synchronized void incCreated(Thread t) {
+ created++;
+ threadsVector.add(t);
+ }
+
+ static synchronized void incFinishing() {
+ finishing++;
+ }
+
+ static synchronized int getFinishing() {
+ return finishing;
+ }
+
+ static synchronized int getCreated() {
+ return created;
+ }
+
+ static synchronized void clear() {
+ created = 0;
+ finishing = 0;
+ status = true;
+ isExitAllowed = false;
+ threadsVector = new Vector();
+ }
+
+ static void setExitAllowed(){
+ isExitAllowed = true;
+ }
+
+ static void hangUntilExitAllowed(){
+ while(!isExitAllowed) {
+ Thread.yield();
+ }
+ }
+
+ static synchronized void joinAllThreads() {
+ if (threadsVector != null) {
+ Object[] tArray = threadsVector.toArray();
+ for (int i = 0; i < tArray.length; ++i){
+ try {
+ ((Thread)tArray[i]).join();
+ } catch (InterruptedException ie){
+ }
+ }
+ threadsVector = null;
+ }
+ }
+}
+
+
+
+
Propchange: harmony/enhanced/buildtest/branches/2.0/tests/reliability/src/java/org/apache/harmony/test/reliability/api/kernel/thread/ThreadLocalTest/ThreadLocalTest.java
------------------------------------------------------------------------------
svn:eol-style = native