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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10433 - (hide annotations) (download)
Tue Sep 10 11:16:57 2013 UTC (6 years, 3 months ago) by Dpocock
File MIME type: text/plain
File size: 12561 byte(s)
rutil: Data: use of fixed-size integer types for methods that work with fixed buffer sizes
1 dlb 3311 #include <iostream>
2 jason 5276 #include "rutil/Log.hxx"
3     #include "rutil/Fifo.hxx"
4     #include "rutil/FiniteFifo.hxx"
5     #include "rutil/TimeLimitFifo.hxx"
6     #include "rutil/Data.hxx"
7     #include "rutil/ThreadIf.hxx"
8     #include "rutil/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 bcampen 7081 delete mFifo.getNext(100);
99 dlb 4746 }
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 Dpocock 10433 for (UInt32 n = 0; n < 0x1ffff; n++)
129 dlb 4746 {
130     if (mFifo.wouldAccept(TimeLimitFifo<Foo>::EnforceTimeDepth))
131     {
132 bcampen 7081 mFifo.add(new Foo(Data(n)), TimeLimitFifo<Foo>::EnforceTimeDepth);
133 dlb 4746 }
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 derek 5677
161     {
162     cerr << "!! test getNext(ms) empty fifo timing" << endl;
163     Fifo<Foo> fifo;
164     UInt64 begin(Timer::getTimeMs());
165     fifo.getNext(2000);
166     UInt64 end(Timer::getTimeMs());
167     cerr << begin << " " << end << " " << end-begin << endl;
168    
169     int offMark = 2000 - (end - begin);
170    
171     assert(abs(offMark) < 200);
172     }
173 dlb 3311
174     Fifo<Foo> f;
175     FiniteFifo<Foo> ff(5);
176    
177     {
178 dlb 4746 cerr << "!! test basic" << endl;
179    
180 dlb 3311 bool c;
181     TimeLimitFifo<Foo> tlf(5, 10); // 5 seconds or 10 count limit
182    
183     assert(tlf.empty());
184     assert(tlf.size() == 0);
185     assert(tlf.timeDepth() == 0);
186    
187 bcampen 7081 c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
188 dlb 3311 assert(c);
189 dlb 3908
190 sgodin 4753 #ifdef VERBOSE
191 dlb 3908 cerr << __LINE__ << endl;
192 sgodin 4753 #endif
193    
194 dlb 3311 assert(!tlf.empty());
195     assert(tlf.size() == 1);
196 bbramwel 3820 #ifdef VERBOSE
197 dlb 3311 cerr << tlf.timeDepth() << endl;
198 bbramwel 3820 #endif
199 dlb 3311 assert(tlf.timeDepth() == 0);
200    
201 sgodin 4753 #ifdef VERBOSE
202 dlb 3908 cerr << __LINE__ << endl;
203 sgodin 4753 #endif
204 dlb 3908
205 sgodin 4753 sleepMS(2000);
206 dlb 3311
207     assert(!tlf.empty());
208     assert(tlf.size() == 1);
209     assert(tlf.timeDepth() > 1);
210    
211 bcampen 7081 delete tlf.getNext();
212 dlb 3311
213     assert(tlf.empty());
214     assert(tlf.size() == 0);
215     assert(tlf.timeDepth() == 0);
216    
217 sgodin 4753 #ifdef VERBOSE
218 dlb 3908 cerr << __LINE__ << endl;
219 sgodin 4753 #endif
220 dlb 3908
221 bcampen 7081 c = tlf.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
222 dlb 3311 assert(c);
223 sgodin 4753 sleepMS(3000);
224 bcampen 7081 c = tlf.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
225 dlb 3311 assert(c);
226 sgodin 4753 sleepMS(3000);
227 bcampen 7081 c = tlf.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
228 dlb 3311 assert(!c);
229 bcampen 7081 c = tlf.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
230 dlb 3311 assert(c);
231 bcampen 7081 c = tlf.add(new Foo("internal"), TimeLimitFifo<Foo>::InternalElement);
232 dlb 3311 assert(c);
233    
234 dlb 3908 cerr << __LINE__ << endl;
235    
236 bcampen 7081 Foo* fp = tlf.getNext();
237 dlb 3311 assert(fp->mVal == "first");
238 bcampen 7081 delete fp;
239     c = tlf.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
240 dlb 3311 assert(c);
241     }
242    
243     {
244 dlb 4746 cerr << "!! Test time depth" << endl;
245    
246 dlb 3311 TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
247     bool c;
248    
249     assert(tlfNS.empty());
250     assert(tlfNS.size() == 0);
251     assert(tlfNS.timeDepth() == 0);
252    
253 bcampen 7081 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
254 dlb 3311 assert(c);
255 sgodin 4753 sleepMS(3000);
256 bcampen 7081 c = tlfNS.add(new Foo("second"), TimeLimitFifo<Foo>::EnforceTimeDepth);
257 dlb 3311 assert(c);
258 sgodin 4753 sleepMS(3000);
259 bcampen 7081 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
260 dlb 3311 assert(!c);
261 bcampen 7081 Foo* fp = tlfNS.getNext();
262 dlb 3311 assert(fp->mVal == "first");
263 bcampen 7081 delete fp;
264     c = tlfNS.add(new Foo("third"), TimeLimitFifo<Foo>::EnforceTimeDepth);
265 dlb 3311 assert(c);
266     }
267    
268     {
269     TimeLimitFifo<Foo> tlfNS(5, 0); // 5 seconds, no count limit
270     bool c;
271    
272     assert(tlfNS.empty());
273     assert(tlfNS.size() == 0);
274     assert(tlfNS.timeDepth() == 0);
275    
276     for (int i = 0; i < 100; ++i)
277     {
278 bcampen 7081 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
279 dlb 3311 assert(c);
280     }
281    
282 sgodin 4753 sleepMS(6000);
283 bcampen 7081 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::EnforceTimeDepth);
284 dlb 3311 assert(!c);
285    
286 bcampen 7081 c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
287 dlb 3311 assert(c);
288    
289     assert(tlfNS.size() == 101);
290    
291     while (!tlfNS.empty())
292     {
293 bcampen 7081 delete tlfNS.getNext();
294 dlb 3311 }
295    
296 bcampen 7081 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
297 dlb 3311 assert(c);
298     }
299    
300     {
301 dlb 4746 cerr << "!! Test reserved" << endl;
302    
303 dlb 3311 TimeLimitFifo<Foo> tlfNS(5, 10); // 5 seconds, limit 10 (2 reserved)
304     bool c;
305    
306     assert(tlfNS.empty());
307     assert(tlfNS.size() == 0);
308     assert(tlfNS.timeDepth() == 0);
309    
310     for (int i = 0; i < 8; ++i)
311     {
312 bcampen 7081 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
313 dlb 3311 assert(c);
314     }
315    
316 bcampen 7081 c = tlfNS.add(new Foo("nope"), TimeLimitFifo<Foo>::IgnoreTimeDepth);
317 dlb 3311 assert(!c);
318    
319     assert(tlfNS.size() == 8);
320    
321 bcampen 7081 c = tlfNS.add(new Foo("yep"), TimeLimitFifo<Foo>::InternalElement);
322 dlb 3311 assert(c);
323    
324 bcampen 7081 c = tlfNS.add(new Foo("yepAgain"), TimeLimitFifo<Foo>::InternalElement);
325 dlb 3311 assert(c);
326    
327 bcampen 7081 c = tlfNS.add(new Foo("hard nope!"), TimeLimitFifo<Foo>::InternalElement);
328 dlb 3311 assert(!c);
329    
330     while (!tlfNS.empty())
331     {
332 bcampen 7081 delete tlfNS.getNext();
333 dlb 3311 }
334    
335 bcampen 7081 c = tlfNS.add(new Foo("first"), TimeLimitFifo<Foo>::EnforceTimeDepth);
336 dlb 3311 assert(c);
337     }
338    
339     {
340 dlb 4746 cerr << "!! Test unlimited" << endl;
341    
342 dlb 3311 TimeLimitFifo<Foo> tlfNS(0, 0); // unlimited
343    
344     bool c;
345    
346     assert(tlfNS.empty());
347     assert(tlfNS.size() == 0);
348     assert(tlfNS.timeDepth() == 0);
349    
350     for (int i = 0; i < 100; ++i)
351     {
352 bcampen 7081 c = tlfNS.add(new Foo(Data("element") + Data(i)), TimeLimitFifo<Foo>::EnforceTimeDepth);
353 dlb 3311 assert(c);
354 sgodin 4753 sleepMS(1000);
355 dlb 3311 }
356 bbramwel 3820 }
357    
358     {
359 dlb 4746 cerr << "!! Test produce consumer" << endl;
360    
361 bbramwel 3820 TimeLimitFifo<Foo> tlfNS(20, 5000);
362     Producer prod(tlfNS);
363     Consumer cons(tlfNS);
364 dlb 3374
365 bbramwel 3820 cons.run();
366     prod.run();
367     #ifdef VERBOSE
368     cerr << "Producer and consumer threads are running" << endl;
369     #endif
370     prod.join();
371     #ifdef VERBOSE
372     cerr << "Producer thread finished" << endl;
373     #endif
374     cons.shutdown();
375     cons.join();
376     #ifdef VERBOSE
377     cerr << "Consumer thread finished" << endl;
378     #endif
379 dlb 3311 }
380 dlb 4746
381     {
382     cerr << "!! Test producers consumers" << endl;
383    
384 sgodin 4753 TimeLimitFifo<Foo> tlfNS(20, 50000);
385 dlb 4746
386 sgodin 4753 Producer prod1(tlfNS);
387     Producer prod2(tlfNS);
388     Producer prod3(tlfNS);
389     Producer prod4(tlfNS);
390     Producer prod5(tlfNS);
391     Producer prod6(tlfNS);
392     Producer prod7(tlfNS);
393     Producer prod8(tlfNS);
394     Producer prod9(tlfNS);
395     Producer prod10(tlfNS);
396 dlb 4746
397 sgodin 4753 Consumer cons1(tlfNS);
398     Consumer cons2(tlfNS);
399     Consumer cons3(tlfNS);
400     Consumer cons4(tlfNS);
401     Consumer cons5(tlfNS);
402     Consumer cons6(tlfNS);
403     Consumer cons7(tlfNS);
404     Consumer cons8(tlfNS);
405     Consumer cons9(tlfNS);
406     Consumer cons10(tlfNS);
407 dlb 4746
408    
409 sgodin 4753 cons1.run();
410     cons2.run();
411     cons3.run();
412     cons4.run();
413     cons5.run();
414     cons6.run();
415     cons7.run();
416     cons8.run();
417     cons9.run();
418     cons10.run();
419 dlb 4746
420 sgodin 4753 #ifdef VERBOSE
421     cerr << "before getNext(1000) " << Timer::getTimeMs() << endl;
422     #endif
423     tlfNS.getNext(1000);
424     #ifdef VERBOSE
425     cerr << "after getNext(1000) " << Timer::getTimeMs() << endl;
426     #endif
427     prod1.run();
428 dlb 4746
429 sgodin 4753 #ifdef VERBOSE
430     cerr << "before getNext(1000) " << Timer::getTimeMs() << endl;
431     #endif
432     tlfNS.getNext(1000);
433     #ifdef VERBOSE
434     cerr << "after getNext(1000) " << Timer::getTimeMs() << endl;
435     #endif
436     prod2.run();
437     prod3.run();
438     prod4.run();
439     prod5.run();
440     prod6.run();
441     prod7.run();
442     prod8.run();
443     prod9.run();
444     prod10.run();
445 dlb 4746
446 sgodin 4753 // Wait for producers to finish
447     prod1.join();
448     prod2.join();
449     prod3.join();
450     prod4.join();
451     prod5.join();
452     prod6.join();
453     prod7.join();
454     prod8.join();
455     prod9.join();
456     prod10.join();
457 dlb 4746
458 sgodin 4753 // Give some time for consumers to finish consuming, before shutting down
459     sleepMS(1000);
460 dlb 4746 }
461    
462 dlb 3311 cerr << "All OK" << endl;
463     return 0;
464     }
465    
466     /* ====================================================================
467     * The Vovida Software License, Version 1.0
468     *
469     * Redistribution and use in source and binary forms, with or without
470     * modification, are permitted provided that the following conditions
471     * are met:
472     *
473     * 1. Redistributions of source code must retain the above copyright
474     * notice, this list of conditions and the following disclaimer.
475     *
476     * 2. Redistributions in binary form must reproduce the above copyright
477     * notice, this list of conditions and the following disclaimer in
478     * the documentation and/or other materials provided with the
479     * distribution.
480     *
481     * 3. The names "VOCAL", "Vovida Open Communication Application Library",
482     * and "Vovida Open Communication Application Library (VOCAL)" must
483     * not be used to endorse or promote products derived from this
484     * software without prior written permission. For written
485     * permission, please contact vocal@vovida.org.
486     *
487     * 4. Products derived from this software may not be called "VOCAL", nor
488     * may "VOCAL" appear in their name, without prior written
489     * permission of Vovida Networks, Inc.
490     *
491     * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
492     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
493     * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
494     * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
495     * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
496     * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
497     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
498     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
499     * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
500     * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
501     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
502     * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
503     * DAMAGE.
504     *
505     * ====================================================================
506     *
507     * This software consists of voluntary contributions made by Vovida
508     * Networks, Inc. and many individuals on behalf of Vovida Networks,
509     * Inc. For more information on Vovida Networks, Inc., please see
510     * <http://www.vovida.org/>.
511     *
512     */

Properties

Name Value
svn:eol-style native
svn:mime-type text/plain

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27