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

Annotation of /main/rutil/test/testFifo.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5274 - (hide annotations) (download)
Thu Aug 18 23:53:59 2005 UTC (14 years, 3 months ago) by jason
Original Path: branches/b-directory-reorg/resip/sip/test/testFifo.cxx
File size: 12262 byte(s)
initial reorg - more to come
1 dlb 3311 #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 bbramwel 3820 #include "resiprocate/os/ThreadIf.hxx"
8 dlb 4746 #include "resiprocate/os/Timer.hxx"
9 sgodin 4753 #ifndef WIN32
10 dlb 3311 #include <unistd.h>
11 sgodin 4753 #endif
12 dlb 3311
13 dlb 4746 //#define VERBOSE
14 bbramwel 3820
15 dlb 3311 using namespace resip;
16     using namespace std;
17    
18 sgodin 4753 void sleepMS(unsigned int ms)
19     {
20     #ifdef WIN32
21     Sleep(ms);
22     #else
23     usleep(ms*1000);
24     #endif
25     }
26    
27 dlb 3311 class Foo
28     {
29     public:
30     Foo(const Data& val)
31     : mVal(val)
32     {}
33    
34     Data mVal;
35     };
36    
37 bbramwel 3820 class Consumer: public ThreadIf
38     {
39     public:
40 dlb 4746 Consumer(TimeLimitFifo<Foo>&);
41     virtual ~Consumer()
42     {
43 sgodin 4753 #ifdef VERBOSE
44     cerr << "Consumer thread finishing..." << endl;
45     #endif
46 dlb 4746 shutdown();
47     join();
48     #ifdef VERBOSE
49     cerr << "Consumer thread finished" << endl;
50     #endif
51     };
52 bbramwel 3820
53 dlb 4746 void thread();
54    
55     private:
56     TimeLimitFifo<Foo>& mFifo;
57 bbramwel 3820 };
58    
59     class Producer: public ThreadIf
60     {
61     public:
62 dlb 4746 Producer(TimeLimitFifo<Foo>&);
63     virtual ~Producer()
64     {
65 sgodin 4753 #ifdef VERBOSE
66     cerr << "Producer thread finishing" << endl;
67     #endif
68 dlb 4746 shutdown();
69     join();
70     #ifdef VERBOSE
71     cerr << "Producer thread finished" << endl;
72     #endif
73     }
74 bbramwel 3820
75 dlb 4746 void thread();
76    
77     private:
78     TimeLimitFifo<Foo>& mFifo;
79 bbramwel 3820 };
80    
81     Consumer::Consumer(TimeLimitFifo<Foo>& f) :
82 dlb 4746 mFifo(f)
83 bbramwel 3820 {}
84    
85     void Consumer::thread()
86     {
87 sgodin 4753 static unsigned wakeups[6] = { 10, 20, 30, 0, 10, 30 };
88 bbramwel 3820 unsigned int w = 0;
89    
90 sgodin 4753 #ifdef VERBOSE
91     cerr << "Consumer running..." << endl;
92     #endif
93    
94 dlb 4746 while (!mShutdown)
95     {
96     if (mFifo.messageAvailable())
97     {
98     mFifo.getNext(100);
99     }
100     else
101     {
102     unsigned wakeup = wakeups[w];
103     w = (w + 1) % 6;
104 bbramwel 3820 #ifdef VERBOSE
105 sgodin 4753 cerr << "Consumer sleeping for " << wakeup << " ms with mSize " << mFifo.size() << endl;
106 bbramwel 3820 #endif
107 dlb 4746 if (wakeup > 0)
108     {
109 sgodin 4753 sleepMS(wakeup);
110 dlb 4746 }
111     }
112 bbramwel 3820 }
113     }
114    
115     Producer::Producer(TimeLimitFifo<Foo>& f) :
116 dlb 4746 mFifo(f)
117 bbramwel 3820 {}
118    
119     void Producer::thread()
120     {
121 sgodin 4753 static unsigned wakeups[6] = { 0, 10, 0, 20, 30, 10 };
122 dlb 4746 unsigned int w = 0;
123 bbramwel 3820
124 sgodin 4753 #ifdef VERBOSE
125     cerr << "Producer running..." << endl;
126     #endif
127    
128 dlb 4746 for (unsigned long n = 0; n < 0x1ffff; n++)
129     {
130     if (mFifo.wouldAccept(TimeLimitFifo<Foo>::EnforceTimeDepth))
131     {
132     mFifo.add(new Foo(Data(n)), TimeLimitFifo<Foo>::EnforceTimeDepth);
133     }
134     else
135     {
136     unsigned wakeup = wakeups[w];
137     w = (w + 1) % 6;
138 bbramwel 3820 #ifdef VERBOSE
139 sgodin 4753 cerr << "Producer sleeping for " << wakeup << " ms at " << n << " with mSize " << mFifo.size() << endl;
140 bbramwel 3820 #endif
141 dlb 4746 if (wakeup > 0)
142     {
143 sgodin 4753 sleepMS(wakeup);
144 dlb 4746 }
145     }
146     }
147 bbramwel 3820 }
148    
149 dlb 3311 bool
150     isNear(int value, int reference, int epsilon=250)
151     {
152     int diff = ::abs(value-reference);
153     return (diff < epsilon);
154     }
155    
156     int
157     main()
158     {
159     Log::initialize(Log::Cout, Log::Debug, Data::Empty);
160    
161     Fifo<Foo> f;
162     FiniteFifo<Foo> ff(5);
163    
164     {
165 dlb 4746 cerr << "!! test basic" << endl;
166    
167 dlb 3311 bool c;
168     TimeLimitFifo<Foo> tlf(5, 10); // 5 seconds or 10 count limit
169    
170     assert(tlf.empty());
171     assert(tlf.size() == 0);
172     assert(tlf.timeDepth() == 0);
173    
174     c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
175     assert(c);
176 dlb 3908
177 sgodin 4753 #ifdef VERBOSE
178 dlb 3908 cerr << __LINE__ << endl;
179 sgodin 4753 #endif
180    
181 dlb 3311 assert(!tlf.empty());
182     assert(tlf.size() == 1);
183 bbramwel 3820 #ifdef VERBOSE
184 dlb 3311 cerr << tlf.timeDepth() << endl;
185 bbramwel 3820 #endif
186 dlb 3311 assert(tlf.timeDepth() == 0);
187    
188 sgodin 4753 #ifdef VERBOSE
189 dlb 3908 cerr << __LINE__ << endl;
190 sgodin 4753 #endif
191 dlb 3908
192 sgodin 4753 sleepMS(2000);
193 dlb 3311
194     assert(!tlf.empty());
195     assert(tlf.size() == 1);
196     assert(tlf.timeDepth() > 1);
197    
198     delete tlf.getNext();
199    
200     assert(tlf.empty());
201     assert(tlf.size() == 0);
202     assert(tlf.timeDepth() == 0);
203    
204 sgodin 4753 #ifdef VERBOSE
205 dlb 3908 cerr << __LINE__ << endl;
206 sgodin 4753 #endif
207 dlb 3908
208 dlb 3311 c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
209     assert(c);
210 sgodin 4753 sleepMS(3000);
211 dlb 3311 c = tlf.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
212     assert(c);
213 sgodin 4753 sleepMS(3000);
214 dlb 3311 c = tlf.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
215     assert(!c);
216     c = tlf.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
217     assert(c);
218     c = tlf.add(new Foo("internal"), TimeLimitFifo<Foo>::InternalElement);
219     assert(c);
220    
221 dlb 3908 cerr << __LINE__ << endl;
222    
223 dlb 3311 Foo* fp = tlf.getNext();
224     assert(fp->mVal == "first");
225     delete fp;
226     c = tlf.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
227     assert(c);
228     }
229    
230     {
231 dlb 4746 cerr << "!! Test time depth" << endl;
232    
233 dlb 3311 TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
234     bool c;
235    
236     assert(tlfNS.empty());
237     assert(tlfNS.size() == 0);
238     assert(tlfNS.timeDepth() == 0);
239    
240     c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
241     assert(c);
242 sgodin 4753 sleepMS(3000);
243 dlb 3311 c = tlfNS.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
244     assert(c);
245 sgodin 4753 sleepMS(3000);
246 dlb 3311 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
247     assert(!c);
248     Foo* fp = tlfNS.getNext();
249     assert(fp->mVal == "first");
250     delete fp;
251     c = tlfNS.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
252     assert(c);
253     }
254    
255     {
256     TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
257     bool c;
258    
259     assert(tlfNS.empty());
260     assert(tlfNS.size() == 0);
261     assert(tlfNS.timeDepth() == 0);
262    
263     for (int i = 0; i < 100; ++i)
264     {
265     c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
266     assert(c);
267     }
268    
269 sgodin 4753 sleepMS(6000);
270 dlb 3311 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
271     assert(!c);
272    
273     c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
274     assert(c);
275    
276     assert(tlfNS.size() == 101);
277    
278     while (!tlfNS.empty())
279     {
280     delete tlfNS.getNext();
281     }
282    
283     c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
284     assert(c);
285     }
286    
287     {
288 dlb 4746 cerr << "!! Test reserved" << endl;
289    
290 dlb 3311 TimeLimitFifo<Foo> tlfNS(5, 10); // 5 seconds, limit 10 (2 reserved)
291     bool c;
292    
293     assert(tlfNS.empty());
294     assert(tlfNS.size() == 0);
295     assert(tlfNS.timeDepth() == 0);
296    
297     for (int i = 0; i < 8; ++i)
298     {
299     c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
300     assert(c);
301     }
302    
303     c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
304     assert(!c);
305    
306     assert(tlfNS.size() == 8);
307    
308     c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::InternalElement);
309     assert(c);
310    
311     c = tlfNS.add(new Foo("yepAgain"), TimeLimitFifo<Foo>::InternalElement);
312     assert(c);
313    
314     c = tlfNS.add(new Foo("hard nope!"), TimeLimitFifo<Foo>::InternalElement);
315     assert(!c);
316    
317     while (!tlfNS.empty())
318     {
319     delete tlfNS.getNext();
320     }
321    
322     c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
323     assert(c);
324     }
325    
326     {
327 dlb 4746 cerr << "!! Test unlimited" << endl;
328    
329 dlb 3311 TimeLimitFifo<Foo> tlfNS(0, 0); // unlimited
330    
331     bool c;
332    
333     assert(tlfNS.empty());
334     assert(tlfNS.size() == 0);
335     assert(tlfNS.timeDepth() == 0);
336    
337     for (int i = 0; i < 100; ++i)
338     {
339     c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
340     assert(c);
341 sgodin 4753 sleepMS(1000);
342 dlb 3311 }
343 bbramwel 3820 }
344    
345     {
346 dlb 4746 cerr << "!! Test produce consumer" << endl;
347    
348 bbramwel 3820 TimeLimitFifo<Foo> tlfNS(20, 5000);
349     Producer prod(tlfNS);
350     Consumer cons(tlfNS);
351 dlb 3374
352 bbramwel 3820 cons.run();
353     prod.run();
354     #ifdef VERBOSE
355     cerr << "Producer and consumer threads are running" << endl;
356     #endif
357     prod.join();
358     #ifdef VERBOSE
359     cerr << "Producer thread finished" << endl;
360     #endif
361     cons.shutdown();
362     cons.join();
363     #ifdef VERBOSE
364     cerr << "Consumer thread finished" << endl;
365     #endif
366 dlb 3311 }
367 dlb 4746
368     {
369     cerr << "!! Test producers consumers" << endl;
370    
371 sgodin 4753 TimeLimitFifo<Foo> tlfNS(20, 50000);
372 dlb 4746
373 sgodin 4753 Producer prod1(tlfNS);
374     Producer prod2(tlfNS);
375     Producer prod3(tlfNS);
376     Producer prod4(tlfNS);
377     Producer prod5(tlfNS);
378     Producer prod6(tlfNS);
379     Producer prod7(tlfNS);
380     Producer prod8(tlfNS);
381     Producer prod9(tlfNS);
382     Producer prod10(tlfNS);
383 dlb 4746
384 sgodin 4753 Consumer cons1(tlfNS);
385     Consumer cons2(tlfNS);
386     Consumer cons3(tlfNS);
387     Consumer cons4(tlfNS);
388     Consumer cons5(tlfNS);
389     Consumer cons6(tlfNS);
390     Consumer cons7(tlfNS);
391     Consumer cons8(tlfNS);
392     Consumer cons9(tlfNS);
393     Consumer cons10(tlfNS);
394 dlb 4746
395    
396 sgodin 4753 cons1.run();
397     cons2.run();
398     cons3.run();
399     cons4.run();
400     cons5.run();
401     cons6.run();
402     cons7.run();
403     cons8.run();
404     cons9.run();
405     cons10.run();
406 dlb 4746
407 sgodin 4753 #ifdef VERBOSE
408     cerr << "before getNext(1000) " << Timer::getTimeMs() << endl;
409     #endif
410     tlfNS.getNext(1000);
411     #ifdef VERBOSE
412     cerr << "after getNext(1000) " << Timer::getTimeMs() << endl;
413     #endif
414     prod1.run();
415 dlb 4746
416 sgodin 4753 #ifdef VERBOSE
417     cerr << "before getNext(1000) " << Timer::getTimeMs() << endl;
418     #endif
419     tlfNS.getNext(1000);
420     #ifdef VERBOSE
421     cerr << "after getNext(1000) " << Timer::getTimeMs() << endl;
422     #endif
423     prod2.run();
424     prod3.run();
425     prod4.run();
426     prod5.run();
427     prod6.run();
428     prod7.run();
429     prod8.run();
430     prod9.run();
431     prod10.run();
432 dlb 4746
433 sgodin 4753 // Wait for producers to finish
434     prod1.join();
435     prod2.join();
436     prod3.join();
437     prod4.join();
438     prod5.join();
439     prod6.join();
440     prod7.join();
441     prod8.join();
442     prod9.join();
443     prod10.join();
444 dlb 4746
445 sgodin 4753 // Give some time for consumers to finish consuming, before shutting down
446     sleepMS(1000);
447 dlb 4746 }
448    
449 dlb 3311 cerr << "All OK" << endl;
450     return 0;
451     }
452    
453     /* ====================================================================
454     * The Vovida Software License, Version 1.0
455     *
456     * Redistribution and use in source and binary forms, with or without
457     * modification, are permitted provided that the following conditions
458     * are met:
459     *
460     * 1. Redistributions of source code must retain the above copyright
461     * notice, this list of conditions and the following disclaimer.
462     *
463     * 2. Redistributions in binary form must reproduce the above copyright
464     * notice, this list of conditions and the following disclaimer in
465     * the documentation and/or other materials provided with the
466     * distribution.
467     *
468     * 3. The names "VOCAL", "Vovida Open Communication Application Library",
469     * and "Vovida Open Communication Application Library (VOCAL)" must
470     * not be used to endorse or promote products derived from this
471     * software without prior written permission. For written
472     * permission, please contact vocal@vovida.org.
473     *
474     * 4. Products derived from this software may not be called "VOCAL", nor
475     * may "VOCAL" appear in their name, without prior written
476     * permission of Vovida Networks, Inc.
477     *
478     * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
479     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
480     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
481     * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
482     * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
483     * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
484     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
485     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
486     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
487     * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
488     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
489     * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
490     * DAMAGE.
491     *
492     * ====================================================================
493     *
494     * This software consists of voluntary contributions made by Vovida
495     * Networks, Inc. and many individuals on behalf of Vovida Networks,
496     * Inc. For more information on Vovida Networks, Inc., please see
497     * <http://www.vovida.org/>.
498     *
499     */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27