Mercurial > projects > ldc
diff tango/example/synchronization/condition.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/example/synchronization/condition.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,307 @@ +/******************************************************************************* + copyright: Copyright (c) 2006 Juan Jose Comellas. All rights reserved + license: BSD style: $(LICENSE) + author: Juan Jose Comellas <juanjo@comellas.com.ar> + Converted to use core.sync by Sean Kelly <sean@f4.ca> +*******************************************************************************/ + +private import tango.core.sync.Condition; +private import tango.core.Exception; +private import tango.core.Thread; +private import tango.text.convert.Integer; +private import tango.io.Stdout; +debug (condition) +{ + private import tango.util.log.Log; + private import tango.util.log.ConsoleAppender; + private import tango.util.log.DateLayout; +} + + +void main(char[][] args) +{ + debug (condition) + { + Logger log = Log.getLogger("condition"); + + log.addAppender(new ConsoleAppender(new DateLayout())); + + log.info("Condition test"); + } + + testNotifyOne(); + testNotifyAll(); +} + + +/** + * Test for Condition.notify(). + */ +void testNotifyOne() +{ + debug (condition) + { + Logger log = Log.getLogger("condition.notify-one"); + } + + scope Mutex mutex = new Mutex(); + scope Condition cond = new Condition(mutex); + int waiting = 0; + Thread thread; + + void notifyOneTestThread() + { + debug (condition) + { + Logger log = Log.getLogger("condition.notify-one." ~ Thread.getThis().name()); + + log.trace("Starting thread"); + } + + try + { + synchronized (mutex) + { + debug (condition) + log.trace("Acquired mutex"); + + scope(exit) + { + debug (condition) + log.trace("Releasing mutex"); + } + + waiting++; + + while (waiting != 2) + { + debug (condition) + log.trace("Waiting on condition variable"); + cond.wait(); + } + + debug (condition) + log.trace("Condition variable was signaled"); + } + } + catch (SyncException e) + { + Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}", + Thread.getThis().name(), e.toString()); + } + catch (Exception e) + { + Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}", + Thread.getThis().name(), e.toString()); + } + debug (condition) + log.trace("Exiting thread"); + } + + thread = new Thread(¬ifyOneTestThread); + thread.name = "thread-1"; + + debug (condition) + log.trace("Created thread " ~ thread.name); + thread.start(); + + try + { + // Poor man's barrier: wait until the other thread is waiting. + while (true) + { + synchronized (mutex) + { + if (waiting != 1) + { + Thread.yield(); + } + else + { + break; + } + } + } + + synchronized (mutex) + { + debug (condition) + log.trace("Acquired mutex"); + + waiting++; + + debug (condition) + log.trace("Notifying test thread"); + cond.notify(); + + debug (condition) + log.trace("Releasing mutex"); + } + + thread.join(); + + if (waiting == 2) + { + debug (condition) + log.info("The Condition notification test to one thread was successful"); + } + else + { + debug (condition) + { + log.error("The condition variable notification to one thread is not working"); + assert(false); + } + else + { + assert(false, "The condition variable notification to one thread is not working"); + } + } + } + catch (SyncException e) + { + Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString()); + } +} + + +/** + * Test for Condition.notifyAll(). + */ +void testNotifyAll() +{ + const uint MaxThreadCount = 10; + + debug (condition) + { + Logger log = Log.getLogger("condition.notify-all"); + } + + scope Mutex mutex = new Mutex(); + scope Condition cond = new Condition(mutex); + int waiting = 0; + + /** + * This thread waits for a notification from the main thread. + */ + void notifyAllTestThread() + { + debug (condition) + { + Logger log = Log.getLogger("condition.notify-all." ~ Thread.getThis().name()); + + log.trace("Starting thread"); + } + + try + { + synchronized (mutex) + { + debug (condition) + log.trace("Acquired mutex"); + + waiting++; + + while (waiting != MaxThreadCount + 1) + { + debug (condition) + log.trace("Waiting on condition variable"); + cond.wait(); + } + + debug (condition) + log.trace("Condition variable was signaled"); + + debug (condition) + log.trace("Releasing mutex"); + } + } + catch (SyncException e) + { + Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}", + Thread.getThis().name(), e.toString()); + } + catch (Exception e) + { + Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}", + Thread.getThis().name(), e.toString()); + } + debug (condition) + log.trace("Exiting thread"); + } + + ThreadGroup group = new ThreadGroup(); + Thread thread; + char[10] tmp; + + for (uint i = 0; i < MaxThreadCount; ++i) + { + thread = new Thread(¬ifyAllTestThread); + thread.name = "thread-" ~ format(tmp, i); + + group.add(thread); + debug (condition) + log.trace("Created thread " ~ thread.name); + thread.start(); + } + + try + { + // Poor man's barrier: wait until all the threads are waiting. + while (true) + { + synchronized (mutex) + { + if (waiting != MaxThreadCount) + { + Thread.yield(); + } + else + { + break; + } + } + } + + synchronized (mutex) + { + debug (condition) + log.trace("Acquired mutex"); + + waiting++; + + debug (condition) + log.trace("Notifying all threads"); + cond.notifyAll(); + + debug (condition) + log.trace("Releasing mutex"); + } + + debug (condition) + log.trace("Waiting for threads to finish"); + group.joinAll(); + + if (waiting == MaxThreadCount + 1) + { + debug (condition) + log.info("The Condition notification test to many threads was successful"); + } + else + { + debug (condition) + { + log.error("The condition variable notification to many threads is not working"); + assert(false); + } + else + { + assert(false, "The condition variable notification to many threads is not working"); + } + } + } + catch (SyncException e) + { + Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString()); + } +}