comparison tango/example/synchronization/mutex.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.Mutex;
9 private import tango.core.Exception;
10 private import tango.core.Thread;
11 private import tango.io.Stdout;
12 private import tango.text.convert.Integer;
13 debug (mutex)
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 /**
22 * Example program for the tango.core.sync.Mutex module.
23 */
24 void main(char[][] args)
25 {
26 debug (mutex)
27 {
28 Logger log = Log.getLogger("mutex");
29
30 log.addAppender(new ConsoleAppender(new DateLayout()));
31
32 log.info("Mutex test");
33 }
34
35 testNonRecursive();
36 testLocking();
37 testRecursive();
38 }
39
40 /**
41 * Test that non-recursive mutexes actually do what they're supposed to do.
42 *
43 * Remarks:
44 * Windows only supports recursive mutexes.
45 */
46 void testNonRecursive()
47 {
48 version (Posix)
49 {
50 debug (mutex)
51 {
52 Logger log = Log.getLogger("mutex.non-recursive");
53 }
54
55 Mutex mutex = new Mutex(Mutex.Type.NonRecursive);
56 bool couldLock;
57
58 try
59 {
60 mutex.lock();
61 debug (mutex)
62 log.trace("Acquired mutex");
63 couldLock = mutex.tryLock();
64 if (couldLock)
65 {
66 debug (mutex)
67 {
68 log.trace("Re-acquired mutex");
69 log.trace("Releasing mutex");
70 }
71 mutex.unlock();
72 }
73 else
74 {
75 debug (mutex)
76 log.trace("Re-acquiring the mutex failed");
77 }
78 debug (mutex)
79 log.trace("Releasing mutex");
80 mutex.unlock();
81 }
82 catch (SyncException e)
83 {
84 Stderr.formatln("Sync exception caught when testing non-recursive mutexes:\n{0}\n", e.toString());
85 }
86 catch (Exception e)
87 {
88 Stderr.formatln("Unexpected exception caught when testing non-recursive mutexes:\n{0}\n", e.toString());
89 }
90
91 if (!couldLock)
92 {
93 debug (mutex)
94 log.info("The non-recursive Mutex test was successful");
95 }
96 else
97 {
98 debug (mutex)
99 {
100 log.error("Non-recursive mutexes are not working: "
101 "Mutex.tryAcquire() did not fail on an already acquired mutex");
102 assert(false);
103 }
104 else
105 {
106 assert(false, "Non-recursive mutexes are not working: "
107 "Mutex.tryAcquire() did not fail on an already acquired mutex");
108 }
109 }
110 }
111 }
112
113 /**
114 * Create several threads that acquire and release a mutex several times.
115 */
116 void testLocking()
117 {
118 const uint MaxThreadCount = 10;
119 const uint LoopsPerThread = 1000;
120
121 debug (mutex)
122 {
123 Logger log = Log.getLogger("mutex.locking");
124 }
125
126 Mutex mutex = new Mutex();
127 uint lockCount = 0;
128
129 void mutexLockingThread()
130 {
131 try
132 {
133 for (uint i; i < LoopsPerThread; i++)
134 {
135 synchronized (mutex)
136 {
137 lockCount++;
138 }
139 }
140 }
141 catch (SyncException e)
142 {
143 Stderr.formatln("Sync exception caught inside mutex testing thread:\n{0}\n", e.toString());
144 }
145 catch (Exception e)
146 {
147 Stderr.formatln("Unexpected exception caught inside mutex testing thread:\n{0}\n", e.toString());
148 }
149 }
150
151 ThreadGroup group = new ThreadGroup();
152 Thread thread;
153 char[10] tmp;
154
155 for (uint i = 0; i < MaxThreadCount; i++)
156 {
157 thread = new Thread(&mutexLockingThread);
158 thread.name = "thread-" ~ format(tmp, i);
159
160 debug (mutex)
161 log.trace("Created thread " ~ thread.name);
162 thread.start();
163
164 group.add(thread);
165 }
166
167 debug (mutex)
168 log.trace("Waiting for threads to finish");
169 group.joinAll();
170
171 if (lockCount == MaxThreadCount * LoopsPerThread)
172 {
173 debug (mutex)
174 log.info("The Mutex locking test was successful");
175 }
176 else
177 {
178 debug (mutex)
179 {
180 log.error("Mutex locking is not working properly: "
181 "the number of times the mutex was acquired is incorrect");
182 assert(false);
183 }
184 else
185 {
186 assert(false,"Mutex locking is not working properly: "
187 "the number of times the mutex was acquired is incorrect");
188 }
189 }
190 }
191
192 /**
193 * Test that recursive mutexes actually do what they're supposed to do.
194 */
195 void testRecursive()
196 {
197 const uint LoopsPerThread = 1000;
198
199 debug (mutex)
200 {
201 Logger log = Log.getLogger("mutex.recursive");
202 }
203
204 Mutex mutex = new Mutex;
205 uint lockCount = 0;
206
207 try
208 {
209 for (uint i = 0; i < LoopsPerThread; i++)
210 {
211 mutex.lock();
212 lockCount++;
213 }
214 }
215 catch (SyncException e)
216 {
217 Stderr.formatln("Sync exception caught in recursive mutex test:\n{0}\n", e.toString());
218 }
219 catch (Exception e)
220 {
221 Stderr.formatln("Unexpected exception caught in recursive mutex test:\n{0}\n", e.toString());
222 }
223
224 for (uint i = 0; i < lockCount; i++)
225 {
226 mutex.unlock();
227 }
228
229 if (lockCount == LoopsPerThread)
230 {
231 debug (mutex)
232 log.info("The recursive Mutex test was successful");
233 }
234 else
235 {
236 debug (mutex)
237 {
238 log.error("Recursive mutexes are not working: "
239 "the number of times the mutex was acquired is incorrect");
240 assert(false);
241 }
242 else
243 {
244 assert(false, "Recursive mutexes are not working: "
245 "the number of times the mutex was acquired is incorrect");
246 }
247 }
248 }