ceki 2003/06/02 10:45:06 Modified: tests/src/java/org/apache/log4j/helpers VerifierThread.java ReaderWriterLockTestCase.java src/java/org/apache/log4j/helpers ReaderWriterLock.java tests build.xml Log: Fixed problems in the TestCase. The ReaderWriterLock was modified to cater for the TestCase. Changes will be removed after further testing. Revision Changes Path 1.2 +61 -15 jakarta-log4j/tests/src/java/org/apache/log4j/helpers/VerifierThread.java Index: VerifierThread.java =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/src/java/org/apache/log4j/helpers/VerifierThread.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- VerifierThread.java 27 May 2003 20:18:57 -0000 1.1 +++ VerifierThread.java 2 Jun 2003 17:45:05 -0000 1.2 @@ -49,6 +49,8 @@ package org.apache.log4j.helpers; +import junit.framework.TestCase; + import org.apache.oro.text.perl.Perl5Util; import java.io.BufferedReader; @@ -66,52 +68,72 @@ boolean[] readLockWaiters; boolean[] writerLockWaiters; BufferedReader bufferedReader; + double v1 = 0; + double v2 = 0; + Perl5Util regex; + Exception exception; + boolean interrupt; VerifierThread(BufferedReader br, int numberOfReaders, int numberOfWriters) { bufferedReader = br; readLockHolders = new boolean[numberOfReaders]; readLockWaiters = new boolean[numberOfReaders]; writerLockWaiters = new boolean[numberOfWriters]; + regex = new Perl5Util(); + } + + boolean getInterrupt() { + return interrupt; } - public void run() { System.out.println("In run of VerifThread"); - - Perl5Util regex = new Perl5Util(); - + String line = null; + while (true) { try { - String line = bufferedReader.readLine(); - System.out.println(line); - - if (regex.match("/([RW])-(\\d{1,2}) (.*)/", line)) { + line = bufferedReader.readLine(); + if(!interrupt) { + System.out.println(line); + } + if (regex.match("/([RW])-(\\d{1,3}) (.*)/", line)) { String type = regex.group(1); int num = Integer.parseInt(regex.group(2)); String msg = regex.group(3); + //System.out.println(type +"_"+num+ " "+msg); if (type.equals("R")) { readerMsg(num, msg); } else if (type.equals("W")) { + writerMsg(num, msg); } } else { System.out.println( "[" + line + "] does not match expected pattern."); } - - //System.out.println("."+type+"-"+num+" "+msg); - } catch (IOException e) { + } catch (Exception e) { + if(exception == null) { + exception = e; + } + interrupt = true; + System.out.println("====Offending line ["+line+"]."); } } } + public Exception getException() { + return exception; + } + void readerMsg(int num, String msg) { if (msg.equals("Asking for read lock.")) { askReadLock(num); } else if (msg.equals("Got read lock.")) { gotReadLock(num); - } else if (msg.startsWith("Value")) { - //releaseReadLock(num); + } else if (msg.startsWith("Value1")) { + value1Message(num, msg); + } else if (msg.startsWith("Value2")) { + value2Message(num, msg); } else if (msg.equals("About to release read lock.")) { releaseReadLock(num); } @@ -122,8 +144,9 @@ askWriterLock(num); } else if (msg.equals("Got write lock.")) { gotWriteLock(num); - } else if (msg.startsWith("Value")) { - //releaseReadLock(num); + } else if (msg.equals("About to increment values.")) { + v1 += 1; + v2 += 10.0; } else if (msg.equals("About to release write lock.")) { releaseWriteLock(num); } @@ -139,6 +162,7 @@ return true; } } + return false; } @@ -206,5 +230,27 @@ } writeLockHolder = -1; + } + + void value1Message(int num, String msg) { + if (regex.match("/Value1 is (\\d*)/", msg)) { + double r = Double.parseDouble(regex.group(1)); + + if (r != v1) { + throw new IllegalStateException( + "Reported value is " + r + " was expecting " + v1); + } + } + } + + void value2Message(int num, String msg) { + if (regex.match("/Value1 is (\\d*)/", msg)) { + double r = Double.parseDouble(regex.group(1)); + + if (r != v2) { + throw new IllegalStateException( + "Reported value is " + r + " was expecting " + v2); + } + } } } 1.4 +75 -51 jakarta-log4j/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java Index: ReaderWriterLockTestCase.java =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/src/java/org/apache/log4j/helpers/ReaderWriterLockTestCase.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- ReaderWriterLockTestCase.java 27 May 2003 20:30:51 -0000 1.3 +++ ReaderWriterLockTestCase.java 2 Jun 2003 17:45:05 -0000 1.4 @@ -53,12 +53,7 @@ import junit.framework.TestCase; import junit.framework.TestSuite; -import org.apache.log4j.LogManager; - -import org.apache.oro.text.perl.Perl5Util; - import java.io.BufferedReader; -import java.io.IOException; import java.io.PipedReader; import java.io.PipedWriter; import java.io.PrintWriter; @@ -75,17 +70,24 @@ * */ public class ReaderWriterLockTestCase extends TestCase { + static final int NUM_READERS = 120; //120; + static final int NUM_WRITERS = 4; //4; + static long WLOOP; // number of repetitions for writer threads + static long RLOOP; // number of repetitions for reader threads double value1 = 0; double value2 = 0; - ReaderWriterLock lock = new ReaderWriterLock(); + + // this is the object we are testing: + ReaderWriterLock lock; + + // The bufferedReader will be passed to the VerifierThread BufferedReader bufferedReader; + + // This is wehere readers and writers send their output PrintWriter printWriter; - - static int WLOOP = 30000; - static int RLOOP = WLOOP*2; /** - * Constructor for ReaderWriterLockTestCasae. + * Constructor for ReaderWriterLockTestCase. * @param arg0 */ public ReaderWriterLockTestCase(String arg0) { @@ -93,52 +95,59 @@ } protected void setUp() throws Exception { + // We write to a piped buffer so that a verifer thread can check the output PipedWriter pipedWriter = new PipedWriter(); PipedReader pipedReader = new PipedReader(); bufferedReader = new BufferedReader(pipedReader); pipedReader.connect(pipedWriter); - //pipedWriter.connect(pipedReader); printWriter = new PrintWriter(pipedWriter); + lock = new ReaderWriterLock(printWriter); } protected void tearDown() throws Exception { } - public void test1() { - int maxReaders = 120; - int maxWriters = 4; - Thread[] threads = new Thread[maxReaders + maxWriters]; + public void test1() throws Exception { + WLOOP = Long.parseLong(System.getProperty("runLen")); + RLOOP = (long) (WLOOP * (1.0)); // readers loop longer + + Thread[] threads = new Thread[NUM_READERS + NUM_WRITERS]; - VerifierThread vt = new VerifierThread(bufferedReader, maxReaders, maxWriters); + VerifierThread vt = + new VerifierThread(bufferedReader, NUM_READERS, NUM_WRITERS); vt.start(); - for (int i = 0; i < maxReaders; i++) { - threads[i] = new ReaderThread(i); + for (int i = 0; i < NUM_READERS; i++) { + threads[i] = new ReaderThread(i, vt); } - for (int i = 0; i < maxWriters; i++) { - threads[maxReaders + i] = new WriterThread(i); + for (int i = 0; i < NUM_WRITERS; i++) { + threads[NUM_READERS + i] = new WriterThread(i, vt); } - for (int i = 0; i < (maxWriters + maxReaders); i++) { + for (int i = 0; i < (NUM_WRITERS + NUM_READERS); i++) { threads[i].start(); } - for (int i = 0; i < (maxWriters + maxReaders); i++) { + for (int i = 0; i < (NUM_WRITERS + NUM_READERS); i++) { try { threads[i].join(); } catch (InterruptedException e) { } } + + Exception e = vt.getException(); + + if (e != null) { + throw e; + } } - void printMessage(String msg) { - synchronized (printWriter) { - //printWriter.print("["); - printWriter.print(Thread.currentThread().getName()); - printWriter.print(" "); - printWriter.println(msg); + void delay(long delay) { + try { + Thread.sleep(delay); + } catch (InterruptedException e) { } } @@ -149,62 +158,77 @@ return suite; } + void printMessage(String msg) { + //printWriter.print("["); + printWriter.println(Thread.currentThread().getName()+" "+msg); + } + + class ReaderThread extends Thread { - ReaderThread(int i) { + int tNum; + VerifierThread vt; + + ReaderThread(int i, VerifierThread vt) { super("R-" + i); + tNum = i; + this.vt = vt; } public void run() { printMessage("In run()"); - for (int l = 0; l < RLOOP; l++) { - printMessage("Asking for read lock."); + for (int t = 0; t < RLOOP; t++) { + if (vt.getInterrupt()) { + return; + } + + //printMessage("Asking for read lock."); lock.getReadLock(); - printMessage("Got read lock."); + //printMessage("Got read lock."); printMessage("Value1 is " + value1); printMessage("Value2 is " + value2); - try { - sleep(10); - } catch (InterruptedException e) { - } + delay(10); - printMessage("About to release read lock."); + //printMessage("About to release read lock."); lock.releaseReadLock(); } } } - + class WriterThread extends Thread { - WriterThread(int i) { + int tNum; + VerifierThread vt; + + WriterThread(int i, VerifierThread vt) { super("W-" + i); + tNum = i; + this.vt = vt; } public void run() { printMessage("In run"); - for (int i = 0; i < WLOOP; i++) { - try { - sleep(30); - } catch (InterruptedException e) { + for (int t = 0; t < WLOOP; t++) { + if (vt.getInterrupt()) { + return; } - printMessage("Asking for write lock."); + // on average, the wait is (3.5)*30 + delay((((tNum * 13) + t) % 7) * 30); + + //printMessage("Asking for write lock."); lock.getWriteLock(); - printMessage("Got write lock."); + //printMessage("Got write lock."); printMessage("About to increment values."); value1 += 1; value2 += 10; - try { - sleep(10); - } catch (InterruptedException e) { - } + delay(10); - printMessage("About to release write lock."); + //printMessage("About to release write lock."); lock.releaseWriteLock(); } } } - } 1.2 +86 -35 jakarta-log4j/src/java/org/apache/log4j/helpers/ReaderWriterLock.java Index: ReaderWriterLock.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/helpers/ReaderWriterLock.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ReaderWriterLock.java 24 May 2003 21:04:00 -0000 1.1 +++ ReaderWriterLock.java 2 Jun 2003 17:45:05 -0000 1.2 @@ -46,49 +46,100 @@ * Apache Software Foundation, please see <http://www.apache.org/>. * */ + package org.apache.log4j.helpers; +import java.io.PrintWriter; + + /** - * + * * A RederWriterLock allows multiple readers to obtain the lock at the same time * but allows only one writer at a time. - * - * Priority is given to waiting writers - * + * + * When both readers and writers wait to obtain the lock, priority is given to + * waiting writers. + * * @author Ceki Gülcü * */ public class ReaderWriterLock { + int readers = 0; + int writers = 0; + int waitingWriters = 0; + PrintWriter printWriter; + + public ReaderWriterLock() { + } + + public ReaderWriterLock(PrintWriter pw) { + printWriter = pw; + } + + public synchronized void getReadLock() { + if (printWriter != null) { + printMessage("Asking for read lock."); + } + + while ((writers > 0) || (waitingWriters > 0)) { + try { + wait(); + } catch (InterruptedException ie) { + } + } + + if (printWriter != null) { + printMessage("Got read lock."); + } + + readers++; + } + + public synchronized void releaseReadLock() { + if (printWriter != null) { + printMessage("About to release read lock."); + } + + readers--; + + if (waitingWriters > 0) { + notifyAll(); + } + } + + public synchronized void getWriteLock() { + if (printWriter != null) { + printMessage("Asking for write lock."); + } + + waitingWriters++; + + while ((readers > 0) || (writers > 0)) { + try { + wait(); + } catch (InterruptedException ie) { + } + } + + if (printWriter != null) { + printMessage("Got write lock."); + } + + waitingWriters--; + writers++; + } + + public synchronized void releaseWriteLock() { + if (printWriter != null) { + printMessage("About to release write lock."); + } + + writers--; + notifyAll(); + } - int readers = 0; - int writers = 0; - int waitingWriters = 0; - - public synchronized void getReadLock() { - while(writers > 0 || waitingWriters > 0) { - try {wait();} catch (InterruptedException ie) {} - } - readers++; - } - - public synchronized void releaseReadLock() { - readers --; - if(waitingWriters >0) - notifyAll(); - } - - public synchronized void getWriteLock() { - waitingWriters++; - while(readers > 0 || writers > 0) { - try {wait();} catch (InterruptedException ie) {} - } - waitingWriters--; - writers++; - } - - public synchronized void releaseWriteLock() { - writers--; - notifyAll(); - } - + void printMessage(String msg) { + //printWriter.print("["); + printWriter.println(Thread.currentThread().getName() + " " + msg); + } } 1.33 +2 -1 jakarta-log4j/tests/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/build.xml,v retrieving revision 1.32 retrieving revision 1.33 diff -u -r1.32 -r1.33 --- build.xml 24 May 2003 21:04:00 -0000 1.32 +++ build.xml 2 Jun 2003 17:45:06 -0000 1.33 @@ -411,7 +411,8 @@ <target name="ReaderWriterLock" depends="build, cleanOutputDir"> - <junit printsummary="yes" fork="no" haltonfailure="yes"> + <junit printsummary="yes" fork="no" haltonfailure="yes"> + <sysproperty key="runLen" value="10000"/> <classpath refid="tests.classpath"/> <formatter type="plain" usefile="false"/> <test name="org.apache.log4j.helpers.ReaderWriterLockTestCase" />
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]