diff options
-rw-r--r-- | java/JACE/tests/Concurrency/IterationTest.java | 235 | ||||
-rw-r--r-- | java/JACE/tests/Concurrency/RWMutexTest.java | 137 | ||||
-rw-r--r-- | java/JACE/tests/Concurrency/TimingTest.java | 290 | ||||
-rw-r--r-- | java/JACE/tests/Concurrency/TokenTest.java | 95 |
4 files changed, 757 insertions, 0 deletions
diff --git a/java/JACE/tests/Concurrency/IterationTest.java b/java/JACE/tests/Concurrency/IterationTest.java new file mode 100644 index 00000000000..79e083e7f7a --- /dev/null +++ b/java/JACE/tests/Concurrency/IterationTest.java @@ -0,0 +1,235 @@ +/************************************************* + * + * = PACKAGE + * JACE.tests.Concurrency + * + * = FILENAME + * IterationTest.java + * + *@author Prashant Jain + *@author Everett Anderson + * + *************************************************/ +package JACE.tests.Concurrency; + +import java.io.*; +import JACE.OS.*; +import JACE.Concurrency.*; + +/** + * Test which uses an AbstractLock to prevent threads from mangling + * shared data. This currently tests the four local concurrency + * mechanisms -- Token, Mutex, RWMutex, and Semaphore. + */ +public class IterationTest +{ + static class LockReader extends Thread + { + LockReader (int nIterations, AbstractLock lock) + { + this.nIterations_ = nIterations; + this.lock_ = lock; + } + + public void run () + { + for (int i = 1; i <= this.nIterations_; i++) + { + // Acquire the lock (will block until it gets it) + try + { + this.lock_.acquire (); + } + catch (InterruptedException e) + { + ACE.ERROR (e); + } + catch (LockException e) + { + ACE.ERROR (e); + } + + IterationTest.count++; + ACE.DEBUG (Thread.currentThread ().toString () + + " reader acquired lock in iteration " + i + + ", count = " + IterationTest.count); + + try + { + Thread.sleep (1); + } + catch (InterruptedException e) + { + } + // Release the lock + try + { + this.lock_.release (); + } + catch (LockException e) + { + ACE.ERROR (e); + } + try + { + Thread.sleep (1); + } + catch (InterruptedException e) + { + } + + } + } + + int nIterations_; + AbstractLock lock_; + } + + static class LockWriter extends Thread + { + LockWriter (int nIterations, AbstractLock lock) + { + this.nIterations_ = nIterations; + this.lock_ = lock; + } + + public void run () + { + for (int i = 1; i <= this.nIterations_; i++) + { + // Acquire the lock (will block until it gets it) + try + { + this.lock_.acquire (); + } + catch (InterruptedException e) + { + ACE.ERROR (e); + } + catch (LockException e) + { + ACE.ERROR (e); + } + + + IterationTest.count++; + ACE.DEBUG (Thread.currentThread ().toString () + + " writer acquired lock in iteration " + i + + ", count = " + IterationTest.count); + + try + { + Thread.sleep (1); + } + catch (InterruptedException e) + { + } + + // Release the lock + try + { + this.lock_.release (); + } + catch (LockException e) + { + ACE.ERROR (e); + } + + try + { + Thread.sleep (1); + } + catch (InterruptedException e) + { + } + + } + } + + int nIterations_; + AbstractLock lock_; + } + + final static int TOKEN = 0; + final static int MUTEX = 1; + final static int RWMUTEX = 2; + final static int SEMAPHORE = 3; + + /** + * Command line arguments: + * + * (number of readers) (number of writers) (number of iterations) + */ + public static void main (String args[]) throws InterruptedException + { + int nReaders = 1; + int nWriters = 1; + int nIterations = 100; + int i; + + ACE.enableDebugging (); + + try + { + if (args.length == 3) + { + nReaders = Integer.parseInt (args[0]); + nWriters = Integer.parseInt (args[1]); + nIterations = Integer.parseInt (args[2]); + } + } + catch (NumberFormatException e) + { + ACE.ERROR ("Illegal argument."); + } + + AbstractLock lock = null; + Thread threads[] = new Thread [nReaders + nWriters]; + + for (int state = TOKEN; state <= SEMAPHORE; state++) { + + count = 0; + + switch (state) + { + case TOKEN: + ACE.DEBUG ("--------\nTesting Token:"); + lock = new Token (); + break; + case MUTEX: + ACE.DEBUG ("--------\nTesting Mutex:"); + lock = new Mutex (); + break; + case RWMUTEX: + ACE.DEBUG ("--------\nTesting RWMutex:"); + lock = new RWMutex (); + break; + case SEMAPHORE: + ACE.DEBUG ("--------\nTesting Semaphore:"); + lock = new Semaphore (); + break; + } + + int numThreads = 0; + + // Spawn off the readers and writers + for (i = 0; i < nReaders; i++) { + threads[numThreads] = new LockReader (nIterations, lock); + threads[numThreads].start (); + numThreads++; + } + + for (i = 0; i < nWriters; i++) { + threads[numThreads] = new LockWriter (nIterations, lock); + threads[numThreads].start (); + numThreads++; + } + + for (i = 0; i < numThreads; i++) + threads[i].join (); + + } + } + + public static int count; +} diff --git a/java/JACE/tests/Concurrency/RWMutexTest.java b/java/JACE/tests/Concurrency/RWMutexTest.java new file mode 100644 index 00000000000..ff2bbc1f396 --- /dev/null +++ b/java/JACE/tests/Concurrency/RWMutexTest.java @@ -0,0 +1,137 @@ +/************************************************* + * + * = PACKAGE + * JACE.tests.Concurrency + * + * = FILENAME + * RWMutexTest.java + * + *@author Ross Dargahi (rossd@krinfo.com) + * + *************************************************/ +package JACE.tests.Concurrency; + +import JACE.OS.*; +import JACE.Concurrency.*; + +public class RWMutexTest +{ + static class TestThread extends Thread + { + TestThread(String name, + boolean writer, + AbstractLock lock) + { + super (name); + mWriter = writer; + mLock = lock; + } + + public void output (String msg) + { + synchronized (iosynch) { + ACE.DEBUG (msg); + } + } + + public void run() + { + for (int i = 0; i < 10; i++) + { + try + { + if (!mWriter) + { + mLock.acquireRead(); + output (getName() + ": Acquired Read Lock"); + + int sleepTime = 10; + sleep (sleepTime); + + mLock.release (); + output (getName () + ": Released Read Lock"); + } + else + { + mLock.acquireWrite (); + output (getName () + ": Acquired Write Lock"); + + int sleepTime = 10; + sleep (sleepTime); + + mLock.release (); + output (getName () + ": Released Write Lock"); + } + } + catch (InterruptedException ex) + { + ACE.ERROR ("InterruptedException"); + } + catch (LockException ex) + { + ACE.ERROR ("LockException: " + ex.getMessage ()); + } + } + } + + AbstractLock mLock; + boolean mWriter; + + static Object iosynch = new Object (); + } + + /** + * Command line arguments: + * + * Optional class name to use for the tests (must implement the + * AbstractLock interface). Followed by an optional number of + * iterations. + */ + public static void main(String [] args) + throws ClassNotFoundException, + IllegalAccessException, + InstantiationException, + InterruptedException, + NumberFormatException + { + AbstractLock lock; + int iterations = 1; + + ACE.enableDebugging (); + + if (args.length > 0) { + ACE.DEBUG("Using class " + args[0] + " as the Lock"); + + lock = (AbstractLock)(Class.forName (args[0]).newInstance ()); + + if (args.length > 1) + iterations = Integer.parseInt (args[1]); + + } else + lock = new RWMutex (); + + for (int i = 0; i < iterations; i++) { + + ACE.DEBUG("Iteration " + (i + 1)); + + TestThread t1 = new TestThread ("1", false, lock); + TestThread t2 = new TestThread ("2", false, lock); + TestThread t3 = new TestThread ("3", false, lock); + TestThread t4 = new TestThread ("4", true, lock); + TestThread t5 = new TestThread ("5", false, lock); + TestThread t6 = new TestThread ("6", false, lock); + TestThread t7 = new TestThread ("7", false, lock); + TestThread t8 = new TestThread ("8", true, lock); + + t1.start (); + t2.start (); + t3.start (); + t4.start (); + t5.start (); + t6.start (); + t7.start (); + t8.start (); + } + } +} + diff --git a/java/JACE/tests/Concurrency/TimingTest.java b/java/JACE/tests/Concurrency/TimingTest.java new file mode 100644 index 00000000000..783d2e003a2 --- /dev/null +++ b/java/JACE/tests/Concurrency/TimingTest.java @@ -0,0 +1,290 @@ +package JACE.tests.Concurrency; + +import JACE.OS.*; +import JACE.ASX.*; +import JACE.Concurrency.*; + +/** + * Performs a test with 5 threads. This should test what happens during + * renews, also testing what happens when timeout exceptions are generated + * during operations. + * + * Sample output: + * + * Thread 1 calling acquire + * Thread 1 got lock + * Thread 1 doing work + * Thread 2 calling acquire + * Thread 1 finished doing work + * Thread 1 calling renew -1 1 + * Thread 2 got lock + * Thread 2 doing work + * Thread 3 calling acquire + * Thread 4 calling acquire + * Thread 5 calling acquire with 1 sec timeout + * Thread 1 timed out in renew + * Thread 1 failed renewing + * Thread 1 calling release + * Thread 1 failed release + * Thread 5 timed out in acquire + * Thread 5 failed acquire + * Thread 5 calling release + * Thread 5 failed release + * Thread 2 finished doing work + * Thread 2 calling renew 1 + * Thread 3 got lock + * Thread 3 doing work + * Thread 3 finished doing work + * Thread 3 calling release + * Thread 3 released + * Thread 2 got the lock back + * Thread 2 calling release + * Thread 2 released + * Thread 4 got lock + * Thread 4 doing work + * Thread 4 finished doing work + * Thread 4 calling release + * Thread 4 released + */ +public class TimingTest +{ + static class Worker extends Thread + { + AbstractLock lock; + String name; + int order; + + public Worker (String name, int order, AbstractLock lock) + { + this.name = name; + this.order = order; + this.lock = lock; + } + + public void run() + { + switch (this.order) + { + case 1: + methodA(); + break; + case 2: + methodB(); + break; + case 3: + methodC(); + break; + case 4: + methodD(); + break; + } + } + + public void methodA() + { + // acquires + // launches a class 2 worker + // works + // renew -1 with a 1 sec timeout (intended to fail) + // release + + try { + if (acquire() == AbstractLock.FAILURE) + return; + + new Worker("Thread 2", 2, lock).start(); + + work(3000); + + renew(-1, 1); + } finally { + release(); + } + } + + public void methodB() + { + // acquire + // launch two new class 3 workers and one class 4 worker + // work + // renew, yielding to one waiter + // release + try { + if (acquire() == AbstractLock.FAILURE) + return; + + new Worker ("Thread 3", 3, lock).start (); + new Worker ("Thread 4", 3, lock).start (); + new Worker ("Thread 5", 4, lock).start (); + + work(3000); + + renew(1); + } finally { + release(); + } + } + + public void methodC() + { + // acquire + // work + // release + + try { + if (acquire() == AbstractLock.FAILURE) + return; + + work(1000); + } finally { + release(); + } + + } + + public void methodD() + { + // acquire with a short timeout + // (shouldn't get past the timeout) + try { + if (acquire (1) == AbstractLock.FAILURE) + return; + + ACE.DEBUG (name + " probably should have timed out in acquire"); + work (1000); + } finally { + release (); + } + } + + public int acquire (int relativeTimeout) + { + int result = AbstractLock.FAILURE; + ACE.DEBUG(name + " calling acquire with " + relativeTimeout + + " sec timeout"); + + try { + result = lock.acquire (TimeValue.relativeTimeOfDay (relativeTimeout, 0)); + } catch (JACE.ASX.TimeoutException e) { + ACE.DEBUG(name + " timed out in acquire"); + } catch (Exception e) { + ACE.DEBUG (name + " got exception: " + e); + } + + if (result != AbstractLock.FAILURE) + ACE.DEBUG(name + " got lock"); + else + ACE.DEBUG(name + " failed acquire"); + + return result; + } + + public int acquire() + { + int result = AbstractLock.FAILURE; + + ACE.DEBUG(name + " calling acquire"); + try { + result = lock.acquire(); + } catch (Exception e) { + ACE.DEBUG(name + " got exception: " + e); + } + if (result != AbstractLock.FAILURE) + ACE.DEBUG(name + " got lock"); + else + ACE.DEBUG(name + " failed acquire"); + + return result; + } + + public void release() + { + ACE.DEBUG(name + " calling release"); + int result = AbstractLock.FAILURE; + try { + result = lock.release(); + } catch (Exception e) { + ACE.DEBUG (name + " got exception: " + e); + } + + if (result != AbstractLock.FAILURE) + ACE.DEBUG(name + " released"); + else + ACE.DEBUG(name + " failed release"); + } + + public void renew(int pos) + { + int result = AbstractLock.FAILURE; + ACE.DEBUG(name + " calling renew " + pos); + try { + result = lock.renew(pos); + } catch (Exception e) { + ACE.DEBUG (name + " got exception: " + e); + } + + if (result != AbstractLock.FAILURE) + ACE.DEBUG(name + " got the lock back"); + else + ACE.DEBUG(name + " failed renewing"); + } + + public void renew(int pos, int relativeTimeout) + { + int result = AbstractLock.FAILURE; + ACE.DEBUG(name + " calling renew " + pos + " " + + relativeTimeout); + try { + result = lock.renew(pos, + TimeValue.relativeTimeOfDay(relativeTimeout, + 0)); + } catch (JACE.ASX.TimeoutException e) { + ACE.DEBUG(name + " timed out in renew"); + } catch (Exception e) { + ACE.DEBUG (name + " got exception: " + e); + } + + if (result != AbstractLock.FAILURE) + ACE.DEBUG(name + " got the lock back"); + else + ACE.DEBUG(name + " failed renewing"); + } + + public void work(int ms) + { + ACE.DEBUG(name + " doing work"); + try { + Thread.sleep(ms); + } catch (InterruptedException e) { + ACE.DEBUG(name + " was interrupted"); + } + ACE.DEBUG(name + " finished doing work"); + } + } + + /** + * Command line: + * + * Optional class name (which implements AbstractLock) to test + */ + public static void main(String args[]) { + AbstractLock lock; + + ACE.enableDebugging (); + + try { + + if (args.length > 0) { + ACE.DEBUG("Using class " + args[0] + " as the Lock"); + + lock = (AbstractLock)(Class.forName (args[0]).newInstance ()); + } else + lock = new Token (); + + new Worker("Thread 1", 1, lock).start(); + + } catch (Exception e) { + ACE.ERROR("Error: " + e); + } + } +} diff --git a/java/JACE/tests/Concurrency/TokenTest.java b/java/JACE/tests/Concurrency/TokenTest.java new file mode 100644 index 00000000000..162170f1996 --- /dev/null +++ b/java/JACE/tests/Concurrency/TokenTest.java @@ -0,0 +1,95 @@ +/************************************************* + * + * = PACKAGE + * tests.Concurrency + * + * = FILENAME + * TokenTest.java + * + *@author Prashant Jain + * + *************************************************/ +package JACE.tests.Concurrency; + +import java.io.*; +import JACE.OS.*; +import JACE.Concurrency.ThreadManager; +import JACE.Concurrency.*; +import JACE.ASX.TimeValue; + +public class TokenTest implements Runnable +{ + static class MyToken extends Token + { + public void sleepHook () + { + ACE.DEBUG (Thread.currentThread ().getName () + + " blocking, sleepHook called"); + } + } + + public void run () + { + String name = Thread.currentThread().getName(); + try + { + if (this.token_.acquire () != AbstractLock.FAILURE) + ACE.DEBUG (name + " got token"); + else + ACE.DEBUG (name + " couldn't get token"); + + ACE.DEBUG (name + " calling acquire again (test nesting)"); + if (this.token_.acquire() != AbstractLock.FAILURE) + ACE.DEBUG (name + " got token again"); + else + ACE.DEBUG (name + " couldn't get token"); + + Thread.sleep (1000); + + ACE.DEBUG (name + " gives it up for max 2 sec to first waiter"); + this.token_.renew (1, TimeValue.relativeTimeOfDay(2, 0)); + + ACE.DEBUG (name + " releases the token once"); + this.token_.release (); + ACE.DEBUG (name + " calls release again (nesting level was 2)"); + this.token_.release (); + } + catch (InterruptedException e) + { + this.token_.release (); + } + catch (JACE.ASX.TimeoutException e) + { + ACE.DEBUG (name + " timed out"); + } + } + + /** + * Command line: optional number of threads to create (defaults to 2) + */ + public static void main (String args []) + { + ThreadManager tm = new ThreadManager (); + int n = 2; + + ACE.enableDebugging (); + + try + { + if (args.length == 1) + { + n = Integer.parseInt (args[0]); + } + } + catch (NumberFormatException e) + { + ACE.ERROR ("Illegal argument."); + } + + tm.spawnN (n, + new TokenTest (), + false); + } + + private static MyToken token_ = new MyToken (); +} |