/[resiprocate]/main/sip/resiprocate/test/testFifo.cxx
ViewVC logotype

Contents of /main/sip/resiprocate/test/testFifo.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3820 - (show annotations) (download)
Thu Jan 20 04:36:08 2005 UTC (15 years ago) by bbramwel
File size: 9105 byte(s)
Added a threaded producer/consumer test

1 #include <iostream>
2 #include "resiprocate/os/Log.hxx"
3 #include "resiprocate/os/Fifo.hxx"
4 #include "resiprocate/os/FiniteFifo.hxx"
5 #include "resiprocate/os/TimeLimitFifo.hxx"
6 #include "resiprocate/os/Data.hxx"
7 #include "resiprocate/os/ThreadIf.hxx"
8 #include <unistd.h>
9
10 // #define VERBOSE
11
12 using namespace resip;
13 using namespace std;
14
15 class Foo
16 {
17 public:
18 Foo(const Data& val)
19 : mVal(val)
20 {}
21
22 Data mVal;
23 };
24
25 class Consumer: public ThreadIf
26 {
27 public:
28 Consumer(TimeLimitFifo<Foo>&);
29 ~Consumer() {};
30
31 void thread();
32
33 private:
34 TimeLimitFifo<Foo>& mFifo;
35 };
36
37 class Producer: public ThreadIf
38 {
39 public:
40 Producer(TimeLimitFifo<Foo>&);
41 ~Producer() {};
42
43 void thread();
44
45 private:
46 TimeLimitFifo<Foo>& mFifo;
47 };
48
49 Consumer::Consumer(TimeLimitFifo<Foo>& f) :
50 mFifo(f)
51 {}
52
53 void Consumer::thread()
54 {
55 static unsigned wakeups[6] = { 1, 2, 3, 0, 1, 3 };
56 unsigned int w = 0;
57
58 while(!mShutdown) {
59 if (mFifo.messageAvailable())
60 mFifo.getNext();
61 else
62 {
63 unsigned wakeup = wakeups[w];
64 w = (w + 1) % 6;
65 #ifdef VERBOSE
66 cerr << "Consumer sleeping for " << wakeup << " seconds with mSize " << mFifo.size() << endl;
67 #endif
68 if (wakeup > 0)
69 sleep(wakeup);
70 }
71 }
72 }
73
74 Producer::Producer(TimeLimitFifo<Foo>& f) :
75 mFifo(f)
76 {}
77
78 void Producer::thread()
79 {
80 static unsigned wakeups[6] = { 0, 1, 0, 2, 3, 1 };
81 unsigned int w = 0;
82
83 for (unsigned long n = 0; n < 0x1ffff; n++) {
84 if (mFifo.wouldAccept(TimeLimitFifo<Foo>::EnforceTimeDepth))
85 mFifo.add(new Foo(Data(n)), TimeLimitFifo<Foo>::EnforceTimeDepth);
86 else
87 {
88 unsigned wakeup = wakeups[w];
89 w = (w + 1) % 6;
90 #ifdef VERBOSE
91 cerr << "Producer sleeping for " << wakeup << " seconds at " << n << " with mSize " << mFifo.size() << endl;
92 #endif
93 if (wakeup > 0)
94 sleep(wakeup);
95 }
96 }
97 }
98
99 bool
100 isNear(int value, int reference, int epsilon=250)
101 {
102 int diff = ::abs(value-reference);
103 return (diff < epsilon);
104 }
105
106 int
107 main()
108 {
109 Log::initialize(Log::Cout, Log::Debug, Data::Empty);
110
111 Fifo<Foo> f;
112 FiniteFifo<Foo> ff(5);
113
114 {
115 bool c;
116 TimeLimitFifo<Foo> tlf(5, 10); // 5 seconds or 10 count limit
117
118 assert(tlf.empty());
119 assert(tlf.size() == 0);
120 assert(tlf.timeDepth() == 0);
121
122 c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
123 assert(c);
124
125 assert(!tlf.empty());
126 assert(tlf.size() == 1);
127 #ifdef VERBOSE
128 cerr << tlf.timeDepth() << endl;
129 #endif
130 assert(tlf.timeDepth() == 0);
131
132 sleep(2);
133
134 assert(!tlf.empty());
135 assert(tlf.size() == 1);
136 assert(tlf.timeDepth() > 1);
137
138 delete tlf.getNext();
139
140 assert(tlf.empty());
141 assert(tlf.size() == 0);
142 assert(tlf.timeDepth() == 0);
143
144 c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
145 assert(c);
146 sleep(3);
147 c = tlf.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
148 assert(c);
149 sleep(3);
150 c = tlf.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
151 assert(!c);
152 c = tlf.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
153 assert(c);
154 c = tlf.add(new Foo("internal"), TimeLimitFifo<Foo>::InternalElement);
155 assert(c);
156
157 Foo* fp = tlf.getNext();
158 assert(fp->mVal == "first");
159 delete fp;
160 c = tlf.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
161 assert(c);
162 }
163
164 {
165 TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
166 bool c;
167
168 assert(tlfNS.empty());
169 assert(tlfNS.size() == 0);
170 assert(tlfNS.timeDepth() == 0);
171
172 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
173 assert(c);
174 sleep(3);
175 c = tlfNS.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
176 assert(c);
177 sleep(3);
178 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
179 assert(!c);
180 Foo* fp = tlfNS.getNext();
181 assert(fp->mVal == "first");
182 delete fp;
183 c = tlfNS.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
184 assert(c);
185 }
186
187 {
188 TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
189 bool c;
190
191 assert(tlfNS.empty());
192 assert(tlfNS.size() == 0);
193 assert(tlfNS.timeDepth() == 0);
194
195 for (int i = 0; i < 100; ++i)
196 {
197 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
198 assert(c);
199 }
200
201 sleep(6);
202 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
203 assert(!c);
204
205 c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
206 assert(c);
207
208 assert(tlfNS.size() == 101);
209
210 while (!tlfNS.empty())
211 {
212 delete tlfNS.getNext();
213 }
214
215 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
216 assert(c);
217 }
218
219 {
220 TimeLimitFifo<Foo> tlfNS(5, 10); // 5 seconds, limit 10 (2 reserved)
221 bool c;
222
223 assert(tlfNS.empty());
224 assert(tlfNS.size() == 0);
225 assert(tlfNS.timeDepth() == 0);
226
227 for (int i = 0; i < 8; ++i)
228 {
229 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
230 assert(c);
231 }
232
233 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
234 assert(!c);
235
236 assert(tlfNS.size() == 8);
237
238 c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::InternalElement);
239 assert(c);
240
241 c = tlfNS.add(new Foo("yepAgain"), TimeLimitFifo<Foo>::InternalElement);
242 assert(c);
243
244 c = tlfNS.add(new Foo("hard nope!"), TimeLimitFifo<Foo>::InternalElement);
245 assert(!c);
246
247 while (!tlfNS.empty())
248 {
249 delete tlfNS.getNext();
250 }
251
252 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
253 assert(c);
254 }
255
256 {
257 TimeLimitFifo<Foo> tlfNS(0, 0); // unlimited
258
259 bool c;
260
261 assert(tlfNS.empty());
262 assert(tlfNS.size() == 0);
263 assert(tlfNS.timeDepth() == 0);
264
265 for (int i = 0; i < 100; ++i)
266 {
267 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
268 assert(c);
269 sleep(1);
270 }
271 }
272
273 {
274 TimeLimitFifo<Foo> tlfNS(20, 5000);
275 Producer prod(tlfNS);
276 Consumer cons(tlfNS);
277
278 cons.run();
279 prod.run();
280 #ifdef VERBOSE
281 cerr << "Producer and consumer threads are running" << endl;
282 #endif
283 prod.join();
284 #ifdef VERBOSE
285 cerr << "Producer thread finished" << endl;
286 #endif
287 cons.shutdown();
288 cons.join();
289 #ifdef VERBOSE
290 cerr << "Consumer thread finished" << endl;
291 #endif
292 }
293 cerr << "All OK" << endl;
294 return 0;
295 }
296
297 /* ====================================================================
298 * The Vovida Software License, Version 1.0
299 *
300 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
301 *
302 * Redistribution and use in source and binary forms, with or without
303 * modification, are permitted provided that the following conditions
304 * are met:
305 *
306 * 1. Redistributions of source code must retain the above copyright
307 * notice, this list of conditions and the following disclaimer.
308 *
309 * 2. Redistributions in binary form must reproduce the above copyright
310 * notice, this list of conditions and the following disclaimer in
311 * the documentation and/or other materials provided with the
312 * distribution.
313 *
314 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
315 * and "Vovida Open Communication Application Library (VOCAL)" must
316 * not be used to endorse or promote products derived from this
317 * software without prior written permission. For written
318 * permission, please contact vocal@vovida.org.
319 *
320 * 4. Products derived from this software may not be called "VOCAL", nor
321 * may "VOCAL" appear in their name, without prior written
322 * permission of Vovida Networks, Inc.
323 *
324 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
325 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
326 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
327 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
328 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
329 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
330 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
331 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
332 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
333 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
334 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
335 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
336 * DAMAGE.
337 *
338 * ====================================================================
339 *
340 * This software consists of voluntary contributions made by Vovida
341 * Networks, Inc. and many individuals on behalf of Vovida Networks,
342 * Inc. For more information on Vovida Networks, Inc., please see
343 * <http://www.vovida.org/>.
344 *
345 */

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27