// $Archive:: $ // $Date: Wed, 06 Oct 2004 18:30:32 -0700 $ // $Revision: 1.3 $ // Description: Titanium synchronization tester // Copyright 2000, Dan Bonachea class Flag { private volatile int val; public Flag(int init) { val = init; } public Flag() { this(-1); } public void set(int val) { this.val = val; } public void set() { set(Ti.thisProc()); } public int get() { return val; } public void check(int val, String loc) { if (this.val != val) throw new InternalError("flag mismatch - illegal synchronization detected" + (loc.length() > 0 ? " (at " + loc : "")); } // helpers public void check(int val) { check(val,""); } public void check(String loc) { check(Ti.thisProc(),loc); } public void check() { check(Ti.thisProc()); } } //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ public class synctest2 { private static Flag flag; //------------------------------------------------------------------------------------ // test simple wait/notify public static Flag t3ahelp; public static void test3a(int single iters) { for (int single i = 0; i < iters; i++) { if (Ti.thisProc() == 0) { System.out.print("."); System.out.flush(); } test3asub(i); Ti.barrier(); } } public static int t3ajunk; private static void test3asub(int i) { if (Ti.thisProc() == 0) t3ahelp.set(0); Ti.barrier(); synchronized (flag) { synchronized (flag) { flag.set(); doWork(); flag.check("entered sync"); try { if (t3ahelp.get() < Ti.numProcs() - 1) { t3ahelp.set(t3ahelp.get()+1); flag.wait(); } } catch (InterruptedException exn) { throwInternalError("thread was interrupted during a wait. i=" +i); } flag.set(); doWork(); flag.check("exited wait 1"); } doWork(); flag.check("exited wait 2"); } doWork(); flag.check("outside sync"); synchronized (flag) { flag.check("inside second sync"); flag.notify(); doWork(); flag.check("inside second sync after notify"); } } //------------------------------------------------------------------------------------ // test simple wait/notify public static Flag t3bhelp; public static void test3b(int single iters) { if (Ti.thisProc() == 0) t3bhelp.set(0); Ti.barrier(); test3bsub(iters); doWork(); flag.check("outside sync"); synchronized (flag) { flag.check("inside second sync"); flag.notify(); doWork(); flag.check("inside second sync after notify"); } Ti.barrier(); } public static int t3bjunk; private static void test3bsub(int i) { if (Ti.thisProc() == 0) { System.out.print("."); System.out.flush(); } synchronized (flag) { if (i > 0) { test3bsub(i-1); } else if (i==0) { flag.set(); doWork(); flag.check("entered sync"); try { if (t3bhelp.get() < Ti.numProcs() - 1) { t3bhelp.set(t3bhelp.get()+1); flag.wait(); } } catch (InterruptedException exn) { throwInternalError("thread was interrupted during a wait. i=" +i); } flag.set(); } doWork(); flag.check("exited wait " + i); } } //------------------------------------------------------------------------------------ public static void main(String single [] single args) { if (Ti.thisProc() == 0) System.out.println("Beginning synchronization tests (this could take awhile)."); if (Ti.numProcs() < 4 && Ti.thisProc() == 0) System.out.println("WARNING: Ti.numProcs() == " + Ti.numProcs() + ", too few for an accurate test!!"); int single iters = 10; Flag success = broadcast new Flag(1) from 0; flag = broadcast new Flag() from 0; t3ahelp = broadcast new Flag(0) from 0; t3bhelp = broadcast new Flag(0) from 0; success.set(1); Ti.barrier(); try { test3a(iters); } catch (InternalError exn) { System.out.println("P#"+Ti.thisProc()+"/"+Ti.numProcs()+": Test3a FAILED: " + exn.getMessage()); success.set(0); } Ti.barrier(); if (Ti.thisProc() == 0) { if (success.get() != 0) System.out.println("Test3a PASSED."); else System.out.println("Test3a FAILED"); } Ti.barrier(); success.set(1); Ti.barrier(); try { test3b(iters); } catch (InternalError exn) { System.out.println("P#"+Ti.thisProc()+"/"+Ti.numProcs()+": Test3b FAILED: " + exn.getMessage()); success.set(0); } Ti.barrier(); if (Ti.thisProc() == 0) { if (success.get() != 0) System.out.println("Test3b PASSED."); else System.out.println("Test3b FAILED"); } Ti.barrier(); if (Ti.thisProc() == 0) System.out.println("Tests complete"); } //------------------------------------------------------------------------------------ private static double junk; private static java.util.Random rand = broadcast new java.util.Random() from 0; public static void doWork() { double x = 1.00001; int [] junkarr = new int[16535]; try { Thread.sleep((int)(Ti.thisProc()*10)); } catch (InterruptedException exn) { throwInternalError("thread was interrupted during a sleep in doWork"); } for (int i = 0; i < 100000; i++) { x = x * 0.99999 / 0.9999; } try { Thread.sleep(rand.nextDouble() > 0.95 ? 1000 : 0); // for platforms w/o usleep } catch (InterruptedException exn) { throwInternalError("thread was interrupted during a sleep in doWork"); } junk = x; Thread.yield(); } public static void throwInternalError(String s) { throw new InternalError(s); } }