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