Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Countdown.d

Go to the documentation of this file.
00001 
00013 module mango.locks.Countdown;
00014 
00015 private {
00016   import std.thread;
00017 
00018   import mango.sys.Atomic;
00019 
00020   import mango.locks.Utils;
00021   import mango.locks.LockImpl;
00022   import mango.locks.TimeUnit;
00023   import mango.locks.Exceptions;
00024 }
00025 
00099 class CountDownLatch {
00100 
00101   /*
00102    * Synchronization control For CountDownLatch.
00103    * Uses AbstractLock state to represent count.
00104    */
00105   private final class Sync : AbstractLock {
00106     this(int count) {
00107       state = count; 
00108     }
00109         
00110     int getCount() {
00111       return state;
00112     }
00113 
00114     int tryAcquireShared(int acquires) {
00115       return state == 0? 1 : -1;
00116     }
00117         
00118     bool tryReleaseShared(int releases) {
00119       // Decrement count; signal when transition to zero
00120       for (;;) {
00121         int c = state;
00122         if (c == 0)
00123           return false;
00124         int nextc = c-1;
00125         if (Atomic.compareAndSet32(&state_, c, nextc)) 
00126           return nextc == 0;
00127       }
00128     }
00129   }
00130 
00131   private Sync sync;
00132 
00140   this(int count) {
00141     if (count < 0)
00142       throw new IllegalArgumentException();
00143     this.sync = new Sync(count);
00144   }
00145 
00156   void wait() {
00157     sync.acquireShared(1);
00158   }
00159 
00186   bool wait(long timeout, TimeUnit unit) {
00187     return sync.tryAcquireSharedNanos(1, toNanos(timeout,unit));
00188   }
00189 
00200   void countDown() {
00201     sync.releaseShared(1);
00202   }
00203 
00209   long count() {
00210     return sync.getCount();
00211   }
00212 
00219   char[] toString() {
00220     char[16] buf;
00221 
00222     return super.toString() ~ "[Count = " ~ 
00223       itoa(buf, sync.getCount()) ~ "]";
00224   }
00225 
00226   unittest {
00227     class Worker { 
00228       private final CountDownLatch done;
00229       this(CountDownLatch d) { done = d; }
00230 
00231       ThreadReturn run() {
00232         version (LocksVerboseUnittest)
00233           printf("counting down...\n");
00234         for (int k=0;k<10000; k++){}
00235         done.countDown();
00236         return 0;
00237       }
00238     }
00239     int N = 5;
00240     version (LocksVerboseUnittest)
00241       printf("starting locks.countdown unittest\n");
00242     CountDownLatch done = new CountDownLatch(N);
00243     for (int i = 0; i < N; ++i) {
00244       Worker w = new Worker(done);
00245       Thread t = new Thread(&w.run);
00246       t.start();
00247     }
00248     for (int k=0;k<10000; k++){}
00249     done.wait(); // wait for all to finish
00250     version (LocksVerboseUnittest)
00251       printf("finished locks.countdown unittest\n");
00252   }
00253 }

Generated on Fri Nov 11 18:44:19 2005 for Mango by  doxygen 1.4.0