comparison 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
comparison
equal deleted inserted replaced
131:5825d48b27d1 132:1700239cab2e
1 /*******************************************************************************
2 copyright: Copyright (c) 2006 Juan Jose Comellas. All rights reserved
3 license: BSD style: $(LICENSE)
4 author: Juan Jose Comellas <juanjo@comellas.com.ar>
5 Converted to use core.sync by Sean Kelly <sean@f4.ca>
6 *******************************************************************************/
7
8 private import tango.core.sync.Condition;
9 private import tango.core.Exception;
10 private import tango.core.Thread;
11 private import tango.text.convert.Integer;
12 private import tango.io.Stdout;
13 debug (condition)
14 {
15 private import tango.util.log.Log;
16 private import tango.util.log.ConsoleAppender;
17 private import tango.util.log.DateLayout;
18 }
19
20
21 void main(char[][] args)
22 {
23 debug (condition)
24 {
25 Logger log = Log.getLogger("condition");
26
27 log.addAppender(new ConsoleAppender(new DateLayout()));
28
29 log.info("Condition test");
30 }
31
32 testNotifyOne();
33 testNotifyAll();
34 }
35
36
37 /**
38 * Test for Condition.notify().
39 */
40 void testNotifyOne()
41 {
42 debug (condition)
43 {
44 Logger log = Log.getLogger("condition.notify-one");
45 }
46
47 scope Mutex mutex = new Mutex();
48 scope Condition cond = new Condition(mutex);
49 int waiting = 0;
50 Thread thread;
51
52 void notifyOneTestThread()
53 {
54 debug (condition)
55 {
56 Logger log = Log.getLogger("condition.notify-one." ~ Thread.getThis().name());
57
58 log.trace("Starting thread");
59 }
60
61 try
62 {
63 synchronized (mutex)
64 {
65 debug (condition)
66 log.trace("Acquired mutex");
67
68 scope(exit)
69 {
70 debug (condition)
71 log.trace("Releasing mutex");
72 }
73
74 waiting++;
75
76 while (waiting != 2)
77 {
78 debug (condition)
79 log.trace("Waiting on condition variable");
80 cond.wait();
81 }
82
83 debug (condition)
84 log.trace("Condition variable was signaled");
85 }
86 }
87 catch (SyncException e)
88 {
89 Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}",
90 Thread.getThis().name(), e.toString());
91 }
92 catch (Exception e)
93 {
94 Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}",
95 Thread.getThis().name(), e.toString());
96 }
97 debug (condition)
98 log.trace("Exiting thread");
99 }
100
101 thread = new Thread(&notifyOneTestThread);
102 thread.name = "thread-1";
103
104 debug (condition)
105 log.trace("Created thread " ~ thread.name);
106 thread.start();
107
108 try
109 {
110 // Poor man's barrier: wait until the other thread is waiting.
111 while (true)
112 {
113 synchronized (mutex)
114 {
115 if (waiting != 1)
116 {
117 Thread.yield();
118 }
119 else
120 {
121 break;
122 }
123 }
124 }
125
126 synchronized (mutex)
127 {
128 debug (condition)
129 log.trace("Acquired mutex");
130
131 waiting++;
132
133 debug (condition)
134 log.trace("Notifying test thread");
135 cond.notify();
136
137 debug (condition)
138 log.trace("Releasing mutex");
139 }
140
141 thread.join();
142
143 if (waiting == 2)
144 {
145 debug (condition)
146 log.info("The Condition notification test to one thread was successful");
147 }
148 else
149 {
150 debug (condition)
151 {
152 log.error("The condition variable notification to one thread is not working");
153 assert(false);
154 }
155 else
156 {
157 assert(false, "The condition variable notification to one thread is not working");
158 }
159 }
160 }
161 catch (SyncException e)
162 {
163 Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString());
164 }
165 }
166
167
168 /**
169 * Test for Condition.notifyAll().
170 */
171 void testNotifyAll()
172 {
173 const uint MaxThreadCount = 10;
174
175 debug (condition)
176 {
177 Logger log = Log.getLogger("condition.notify-all");
178 }
179
180 scope Mutex mutex = new Mutex();
181 scope Condition cond = new Condition(mutex);
182 int waiting = 0;
183
184 /**
185 * This thread waits for a notification from the main thread.
186 */
187 void notifyAllTestThread()
188 {
189 debug (condition)
190 {
191 Logger log = Log.getLogger("condition.notify-all." ~ Thread.getThis().name());
192
193 log.trace("Starting thread");
194 }
195
196 try
197 {
198 synchronized (mutex)
199 {
200 debug (condition)
201 log.trace("Acquired mutex");
202
203 waiting++;
204
205 while (waiting != MaxThreadCount + 1)
206 {
207 debug (condition)
208 log.trace("Waiting on condition variable");
209 cond.wait();
210 }
211
212 debug (condition)
213 log.trace("Condition variable was signaled");
214
215 debug (condition)
216 log.trace("Releasing mutex");
217 }
218 }
219 catch (SyncException e)
220 {
221 Stderr.formatln("Sync exception caught in Condition test thread {0}:\n{1}",
222 Thread.getThis().name(), e.toString());
223 }
224 catch (Exception e)
225 {
226 Stderr.formatln("Unexpected exception caught in Condition test thread {0}:\n{1}",
227 Thread.getThis().name(), e.toString());
228 }
229 debug (condition)
230 log.trace("Exiting thread");
231 }
232
233 ThreadGroup group = new ThreadGroup();
234 Thread thread;
235 char[10] tmp;
236
237 for (uint i = 0; i < MaxThreadCount; ++i)
238 {
239 thread = new Thread(&notifyAllTestThread);
240 thread.name = "thread-" ~ format(tmp, i);
241
242 group.add(thread);
243 debug (condition)
244 log.trace("Created thread " ~ thread.name);
245 thread.start();
246 }
247
248 try
249 {
250 // Poor man's barrier: wait until all the threads are waiting.
251 while (true)
252 {
253 synchronized (mutex)
254 {
255 if (waiting != MaxThreadCount)
256 {
257 Thread.yield();
258 }
259 else
260 {
261 break;
262 }
263 }
264 }
265
266 synchronized (mutex)
267 {
268 debug (condition)
269 log.trace("Acquired mutex");
270
271 waiting++;
272
273 debug (condition)
274 log.trace("Notifying all threads");
275 cond.notifyAll();
276
277 debug (condition)
278 log.trace("Releasing mutex");
279 }
280
281 debug (condition)
282 log.trace("Waiting for threads to finish");
283 group.joinAll();
284
285 if (waiting == MaxThreadCount + 1)
286 {
287 debug (condition)
288 log.info("The Condition notification test to many threads was successful");
289 }
290 else
291 {
292 debug (condition)
293 {
294 log.error("The condition variable notification to many threads is not working");
295 assert(false);
296 }
297 else
298 {
299 assert(false, "The condition variable notification to many threads is not working");
300 }
301 }
302 }
303 catch (SyncException e)
304 {
305 Stderr.formatln("Sync exception caught in main thread:\n{0}", e.toString());
306 }
307 }