22 #include <boost/scoped_ptr.hpp> 37 #include <rtt-config.h> 39 #include <boost/foreach.hpp> 40 #include <boost/lexical_cast.hpp> 48 Dummy(
double a = 0.0,
double b =1.0,
double c=2.0)
49 :d1(a), d2(b), d3(c) {}
55 return d.
d1 == d1 && d.
d2 == d2 && d.
d3 == d3;
60 return d.
d1 != d1 || d.
d2 != d2 || d.
d3 != d3;
65 return d1+d2+d3 < d.
d1 + d.
d2 + d.
d3;
118 template <
class Worker>
119 class ThreadPool :
public std::vector< std::pair< boost::shared_ptr<Worker>, boost::shared_ptr<ThreadInterface> > >
122 typedef std::vector< std::pair< boost::shared_ptr<Worker>, boost::shared_ptr<ThreadInterface> > >
Threads;
127 template <
typename Arg1>
132 for(iterator worker = this->begin(); worker != this->end(); ++worker) {
133 worker->first.reset(
new Worker(arg1));
134 worker->second.reset(
new Activity(scheduler, priority, period, worker->first.get(), name + boost::lexical_cast<std::string>(count++)));
141 for(iterator worker = this->begin(); worker != this->end(); ++worker) {
142 worker->second.reset();
143 worker->first.reset();
150 for(const_iterator worker = this->begin(); worker != this->end(); ++worker) {
151 if (!worker->second->start()) result =
false;
159 for(const_iterator worker = this->begin(); worker != this->end(); ++worker) {
160 worker->second->stop();
191 void testBufMultiThreaded(
int number_of_writers,
int number_of_readers);
192 void testDObjMultiThreaded(
int number_of_writers,
int number_of_readers);
197 lockfree =
new BufferLockFree<Dummy>(
QS,
Dummy());
199 unsync =
new BufferUnSync<Dummy>(
QS,
Dummy());
206 dlockfree =
new DataObjectLockFree<Dummy>(
Dummy());
238 DataObjectWriter(DataObjectInterface<Dummy> *dataobj) : dataobj(dataobj), stop(false), writes(0), dropped(0) {}
244 while (stop ==
false) {
245 if (dataobj->Set(sample)) {
272 DataObjectReader(DataObjectInterface<Dummy> *dataobj) : dataobj(dataobj), stop(false), reads(0) {}
278 while (stop ==
false) {
281 ++reads_by_status[fs];
304 BufferWriter(BufferInterface<Dummy> *buffer) : buffer(buffer), stop(false), writes(0), dropped(0) {}
310 while (stop ==
false) {
311 if (buffer->Push(sample)) {
338 BufferReader(BufferInterface<Dummy> *buffer) : buffer(buffer), stop(false), reads(0) {}
344 while (stop ==
false) {
347 ++reads_by_status[fs];
371 BOOST_CHECK( buffer->Pop(r) == false );
373 BOOST_CHECK( buffer->Push( *d ) );
374 BOOST_CHECK( buffer->Pop(r) );
375 BOOST_CHECK( r == *d );
377 BOOST_CHECK( buffer->Push( *c ) );
378 BOOST_CHECK( buffer->Pop(r) );
379 BOOST_CHECK( r == *c );
381 BOOST_CHECK( buffer->Push( *d ) );
382 BOOST_CHECK( buffer->Push( *c ) );
383 BOOST_CHECK( buffer->Push( *d ) );
384 BOOST_CHECK( buffer->Push( *c ) );
385 BOOST_CHECK( buffer->Push( *d ) );
386 BOOST_CHECK( buffer->Push( *c ) );
387 BOOST_CHECK( buffer->Push( *d ) );
388 BOOST_CHECK( buffer->Push( *c ) );
389 BOOST_CHECK( buffer->Push( *d ) );
390 BOOST_CHECK( buffer->Push( *c ) );
391 BOOST_CHECK( buffer->Push( *c ) == false );
392 BOOST_CHECK( buffer->Push( *c ) == false );
393 BOOST_CHECK( buffer->Push( *c ) == false );
394 BOOST_CHECK( buffer->Push( *c ) == false );
395 BOOST_CHECK( buffer->Push( *c ) == false );
396 BOOST_CHECK( buffer->Push( *c ) == false );
397 BOOST_CHECK( buffer->Push( *c ) == false );
398 BOOST_CHECK( buffer->Push( *c ) == false );
399 BOOST_CHECK( buffer->Push( *c ) == false );
400 BOOST_CHECK( buffer->Push( *c ) == false );
401 BOOST_CHECK( buffer->Push( *c ) == false );
402 BOOST_CHECK( buffer->Push( *c ) == false );
403 BOOST_CHECK( buffer->Pop(r) );
404 BOOST_CHECK( r == *d );
405 BOOST_CHECK( buffer->Pop(r) );
406 BOOST_CHECK( r == *c );
407 BOOST_CHECK( buffer->Pop(r) );
408 BOOST_CHECK( r == *d );
409 BOOST_CHECK( buffer->Pop(r) );
410 BOOST_CHECK( r == *c );
411 BOOST_CHECK( buffer->Pop(r) );
412 BOOST_CHECK( r == *d );
415 BOOST_CHECK( buffer->Push( *d ) );
416 BOOST_CHECK( buffer->Push( *c ) );
417 BOOST_CHECK( buffer->Push( *d ) );
418 BOOST_CHECK( buffer->Push( *c ) );
419 BOOST_CHECK( buffer->Push( *d ) );
421 BOOST_CHECK( buffer->Pop(r) );
422 BOOST_CHECK( r == *c );
423 BOOST_CHECK( buffer->Pop(r) );
424 BOOST_CHECK( r == *d );
425 BOOST_CHECK( buffer->Pop(r) );
426 BOOST_CHECK( r == *c );
427 BOOST_CHECK( buffer->Pop(r) );
428 BOOST_CHECK( r == *d );
429 BOOST_CHECK( buffer->Pop(r) );
430 BOOST_CHECK( r == *c );
431 BOOST_CHECK( buffer->Pop(r) );
432 BOOST_CHECK( r == *d );
433 BOOST_CHECK( buffer->Pop(r) );
434 BOOST_CHECK( r == *c );
435 BOOST_CHECK( buffer->Pop(r) );
436 BOOST_CHECK( r == *d );
437 BOOST_CHECK( buffer->Pop(r) );
438 BOOST_CHECK( r == *c );
439 BOOST_CHECK( buffer->Pop(r) );
440 BOOST_CHECK( r == *d );
442 BOOST_CHECK( buffer->Pop(r) == false );
443 BOOST_CHECK( buffer->Pop(r) == false );
444 BOOST_CHECK( buffer->Pop(r) == false );
445 BOOST_CHECK( buffer->Pop(r) == false );
446 BOOST_CHECK( buffer->Pop(r) == false );
447 BOOST_CHECK( buffer->Pop(r) == false );
448 BOOST_CHECK( buffer->Pop(r) == false );
449 BOOST_CHECK( buffer->Pop(r) == false );
450 BOOST_CHECK( buffer->Pop(r) == false );
451 BOOST_CHECK( buffer->Pop(r) == false );
452 BOOST_CHECK( buffer->Pop(r) == false );
454 BOOST_CHECK( buffer->Push( *c ) );
455 BOOST_CHECK( buffer->Push( *d ) );
456 BOOST_CHECK( buffer->Push( *c ) );
457 BOOST_CHECK( buffer->Push( *d ) );
458 BOOST_CHECK( buffer->Push( *c ) );
460 std::vector<Dummy> v;
461 BOOST_CHECK( 5 == buffer->Pop(v) );
462 BOOST_CHECK( v[0] == *c );
463 BOOST_CHECK( v[1] == *d );
464 BOOST_CHECK( v[2] == *c );
465 BOOST_CHECK( v[3] == *d );
466 BOOST_CHECK( v[4] == *c );
469 BOOST_CHECK( buffer->Push( *c ) );
470 BOOST_CHECK( buffer->Push( *d ) );
471 BOOST_CHECK( buffer->Push( v ) == (int)v.size() );
472 BOOST_CHECK( buffer->Push( *c ) );
473 BOOST_CHECK( buffer->Push( *d ) );
474 BOOST_CHECK( buffer->Push( v ) == 1 );
475 BOOST_CHECK( buffer->Push( v ) == 0 );
476 BOOST_CHECK( buffer->Push( v ) == 0 );
477 BOOST_CHECK( buffer->Push( v ) == 0 );
478 BOOST_CHECK( buffer->Push( v ) == 0 );
479 BOOST_CHECK( buffer->Push( v ) == 0 );
480 BOOST_CHECK( buffer->Push( v ) == 0 );
481 BOOST_CHECK( buffer->Push( v ) == 0 );
482 BOOST_CHECK( buffer->Push( v ) == 0 );
483 BOOST_CHECK( buffer->Push( v ) == 0 );
484 BOOST_CHECK( buffer->Push( v ) == 0 );
485 BOOST_CHECK( buffer->Push( v ) == 0 );
486 BOOST_CHECK( buffer->Push( v ) == 0 );
487 BOOST_REQUIRE_EQUAL( sz, buffer->Pop(v) );
488 BOOST_CHECK( v[0] == *c );
489 BOOST_CHECK( v[1] == *d );
490 BOOST_CHECK( v[2] == *c );
491 BOOST_CHECK( v[3] == *d );
492 BOOST_CHECK( v[4] == *c );
493 BOOST_CHECK( v[5] == *d );
494 BOOST_CHECK( v[6] == *c );
495 BOOST_CHECK( v[7] == *c );
496 BOOST_CHECK( v[8] == *d );
498 BOOST_CHECK( 0 == buffer->Pop(v) );
514 BOOST_CHECK( circular->Pop(r) == false );
516 BOOST_CHECK( circular->Push( *d ) );
517 BOOST_CHECK( circular->Pop(r) );
518 BOOST_CHECK( r == *d );
520 BOOST_CHECK( circular->Push( *c ) );
521 BOOST_CHECK( circular->Pop(r) );
522 BOOST_CHECK( r == *c );
524 BOOST_CHECK( circular->Push( *d ) );
525 BOOST_CHECK( circular->Push( *c ) );
526 BOOST_CHECK( circular->Push( *d ) );
527 BOOST_CHECK( circular->Push( *c ) );
528 BOOST_CHECK( circular->Push( *d ) );
529 BOOST_CHECK( circular->Push( *c ) );
530 BOOST_CHECK( circular->Push( *d ) );
531 BOOST_CHECK( circular->Push( *c ) );
532 BOOST_CHECK( circular->Push( *d ) );
533 BOOST_CHECK( circular->Push( *c ) );
534 BOOST_CHECK( circular->Push( *d ) );
535 BOOST_CHECK( circular->Push( *c ) );
536 BOOST_CHECK( circular->Push( *d ) );
537 BOOST_CHECK( circular->Push( *c ) );
538 BOOST_CHECK( circular->Push( *d ) );
539 BOOST_CHECK( circular->Push( *c ) );
540 BOOST_CHECK( circular->Push( *d ) );
541 BOOST_CHECK( circular->Push( *c ) );
542 BOOST_CHECK( circular->Push( *d ) );
543 BOOST_CHECK( circular->Pop(r) );
544 BOOST_CHECK( r == *c );
545 BOOST_CHECK( circular->Pop(r) );
546 BOOST_CHECK( r == *d );
547 BOOST_CHECK( circular->Pop(r) );
548 BOOST_CHECK( r == *c );
549 BOOST_CHECK( circular->Pop(r) );
550 BOOST_CHECK( r == *d );
551 BOOST_CHECK( circular->Pop(r) );
552 BOOST_CHECK( r == *c );
555 BOOST_CHECK( circular->Push( *d ) );
556 BOOST_CHECK( circular->Push( *c ) );
557 BOOST_CHECK( circular->Push( *d ) );
558 BOOST_CHECK( circular->Push( *c ) );
559 BOOST_CHECK( circular->Push( *d ) );
561 BOOST_CHECK( circular->Pop(r) );
562 BOOST_CHECK( r == *d );
563 BOOST_CHECK( circular->Pop(r) );
564 BOOST_CHECK( r == *c );
565 BOOST_CHECK( circular->Pop(r) );
566 BOOST_CHECK( r == *d );
567 BOOST_CHECK( circular->Pop(r) );
568 BOOST_CHECK( r == *c );
569 BOOST_CHECK( circular->Pop(r) );
570 BOOST_CHECK( r == *d );
571 BOOST_CHECK( circular->Pop(r) );
572 BOOST_CHECK( r == *d );
573 BOOST_CHECK( circular->Pop(r) );
574 BOOST_CHECK( r == *c );
575 BOOST_CHECK( circular->Pop(r) );
576 BOOST_CHECK( r == *d );
577 BOOST_CHECK( circular->Pop(r) );
578 BOOST_CHECK( r == *c );
579 BOOST_CHECK( circular->Pop(r) );
580 BOOST_CHECK( r == *d );
582 BOOST_CHECK( circular->Pop(r) == false );
583 BOOST_CHECK( circular->Pop(r) == false );
584 BOOST_CHECK( circular->Pop(r) == false );
585 BOOST_CHECK( circular->Pop(r) == false );
586 BOOST_CHECK( circular->Pop(r) == false );
587 BOOST_CHECK( circular->Pop(r) == false );
588 BOOST_CHECK( circular->Pop(r) == false );
589 BOOST_CHECK( circular->Pop(r) == false );
590 BOOST_CHECK( circular->Pop(r) == false );
591 BOOST_CHECK( circular->Pop(r) == false );
592 BOOST_CHECK( circular->Pop(r) == false );
594 BOOST_CHECK( circular->Push( *c ) );
595 BOOST_CHECK( circular->Push( *d ) );
596 BOOST_CHECK( circular->Push( *c ) );
597 BOOST_CHECK( circular->Push( *d ) );
598 BOOST_CHECK( circular->Push( *c ) );
600 std::vector<Dummy> v;
601 BOOST_CHECK( 5 == circular->Pop(v) );
602 BOOST_CHECK( v[0] == *c );
603 BOOST_CHECK( v[1] == *d );
604 BOOST_CHECK( v[2] == *c );
605 BOOST_CHECK( v[3] == *d );
606 BOOST_CHECK( v[4] == *c );
609 BOOST_CHECK( circular->Push( *c ) );
610 BOOST_CHECK( circular->Push( *d ) );
611 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
612 BOOST_CHECK( circular->Push( *c ) );
613 BOOST_CHECK( circular->Push( *d ) );
614 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
615 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
616 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
617 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
618 BOOST_CHECK( circular->Push( v ) == (int)v.size() );
619 BOOST_REQUIRE_EQUAL( sz, circular->Pop(v) );
620 BOOST_CHECK( v[0] == *c );
621 BOOST_CHECK( v[1] == *d );
622 BOOST_CHECK( v[2] == *c );
623 BOOST_CHECK( v[3] == *d );
624 BOOST_CHECK( v[4] == *c );
625 BOOST_CHECK( v[5] == *c );
626 BOOST_CHECK( v[6] == *d );
627 BOOST_CHECK( v[7] == *c );
628 BOOST_CHECK( v[8] == *d );
629 BOOST_CHECK( v[9] == *c );
630 BOOST_CHECK( 0 == circular->Pop(v) );
638 Dummy d(5.0, 4.0, 3.0);
640 BOOST_REQUIRE_EQUAL(
NoData, dataobj->Get(d) );
641 BOOST_REQUIRE_EQUAL( d,
Dummy(5.0, 4.0, 3.0) );
644 BOOST_REQUIRE_EQUAL( *c, dataobj->Get() );
646 while ( i != 3.5*dlockfree->MAX_THREADS ) {
651 BOOST_REQUIRE_EQUAL( d , dataobj->Get() );
652 BOOST_REQUIRE_EQUAL( d , dataobj->Get() );
664 BOOST_REQUIRE( readers.
start() );
665 BOOST_REQUIRE( writers.
start() );
667 BOOST_REQUIRE( writers.
stop() );
668 BOOST_REQUIRE( readers.
stop() );
670 int total_writes = 0, total_dropped = 0, total_reads = 0;
671 std::map<FlowStatus, int> total_reads_by_status;
673 BOOST_REQUIRE( !writer.second->isRunning() );
674 total_writes += writer.first->writes;
675 total_dropped += writer.first->dropped;
676 BOOST_CHECK_GT(writer.first->writes, 0);
679 BOOST_REQUIRE( !reader.second->isRunning() );
680 total_reads += reader.first->reads;
681 BOOST_CHECK_GT(reader.first->reads, 0);
682 BOOST_FOREACH(ReadsByStatusMap::value_type &reads_by_status, reader.first->reads_by_status) {
683 total_reads_by_status[reads_by_status.first] += reads_by_status.second;
687 if (buffer != circular) {
688 BOOST_CHECK_EQUAL(total_writes, (total_reads_by_status[
NewData] + buffer->size()));
690 BOOST_CHECK_GE(total_writes, (total_reads_by_status[
NewData] + buffer->size()));
693 if (writers.size() == 1) {
694 if (buffer != circular) {
695 BOOST_WARN_EQUAL(0, total_dropped);
697 BOOST_CHECK_EQUAL(0, total_dropped);
710 BOOST_REQUIRE( readers.
start() );
711 BOOST_REQUIRE( writers.
start() );
713 BOOST_REQUIRE( writers.
stop() );
714 BOOST_REQUIRE( readers.
stop() );
716 int total_writes = 0, total_dropped = 0, total_reads = 0;
717 std::map<FlowStatus, int> total_reads_by_status;
719 BOOST_REQUIRE( !writer.second->isRunning() );
720 total_writes += writer.first->writes;
721 total_dropped += writer.first->dropped;
722 BOOST_CHECK_GT(writer.first->writes, 0);
725 BOOST_REQUIRE( !reader.second->isRunning() );
726 total_reads += reader.first->reads;
727 BOOST_CHECK_GT(reader.first->reads, 0);
728 BOOST_FOREACH(ReadsByStatusMap::value_type &reads_by_status, reader.first->reads_by_status) {
729 total_reads_by_status[reads_by_status.first] += reads_by_status.second;
734 BOOST_CHECK_GE(total_writes, total_reads_by_status[
NewData]);
735 if (writers.size() == 1) {
736 BOOST_CHECK_EQUAL(total_dropped, 0);
755 mpool =
new TsPool<Dummy>(
QS);
756 vpool =
new TsPool<std::vector<Dummy> >(
QS, std::vector<Dummy>(
QS) );
764 template <
typename T>
773 Worker(TsPool<T> *pool) : mpool(pool), stop(false), cycles(0) {}
779 while( stop ==
false ) {
781 BOOST_VERIFY( item = mpool->allocate() );
782 getThread()->yield();
783 if (item) BOOST_VERIFY(mpool->deallocate(item));
796 os <<
"(" << d.
d1 <<
","<<d.
d2<<
","<<d.
d3<<
")";
825 appends = 0; erases = 0;
829 while (stop ==
false ) {
831 while ( stop ==
false && mlst->append(
Dummy(i,i,i) ) ) { ++i; ++appends; }
833 while ( mlst->erase(
Dummy(i-1,i-1,i-1) ) ) { --i; ++erases; }
859 while (stop ==
false && i < 2500 ) {
886 AQWorker(T* l ) : stop(false), mlst(l),appends(0), erases(0) {
887 orig =
new Dummy( 1,2,3);
898 while (stop ==
false ) {
900 if ( mlst->enqueue( d ) ) { ++appends; }
902 if ( mlst->dequeue( d ) ) {
935 AQGrower(T* l ) : stop(false), mlst(l), appends(0) {
936 orig =
new Dummy( 1,2,3);
948 while (stop ==
false ) {
949 if ( mlst->enqueue(d) ) {
973 AQEater(T* l ) : stop(false), mlst(l), erases(0) {}
981 while (stop ==
false ) {
982 if ( mlst->dequeue(d) ) {
1011 BOOST_CHECK( aqueue->isFull() == false );
1012 BOOST_CHECK( aqueue->isEmpty() == true );
1013 BOOST_CHECK( aqueue->dequeue(c) == false );
1014 BOOST_CHECK( c == d );
1016 for (
int i = 0; i <
QS; ++i) {
1017 BOOST_CHECK( aqueue->enqueue( d ) ==
true);
1021 BOOST_CHECK( aqueue->isFull() == true );
1022 BOOST_CHECK( aqueue->isEmpty() == false );
1023 BOOST_CHECK( aqueue->enqueue( d ) == false );
1026 aqueue->dequeue( d );
1027 BOOST_CHECK( aqueue->isFull() == false );
1030 for (
int i = 0; i <
QS - 1 ; ++i) {
1031 BOOST_CHECK( aqueue->dequeue( d ) ==
true);
1034 BOOST_CHECK( aqueue->isFull() == false );
1035 BOOST_CHECK( aqueue->isEmpty() == true );
1053 BOOST_CHECK( aqueue->isFull() == false );
1054 BOOST_CHECK( aqueue->isEmpty() == true );
1055 BOOST_CHECK( aqueue->dequeue(c) == false );
1056 BOOST_CHECK( c == d );
1058 for (
int i = 0; i <
QS; ++i) {
1059 BOOST_CHECK( aqueue->enqueue( d ) ==
true);
1064 BOOST_CHECK( aqueue->isFull() == true );
1065 BOOST_CHECK( aqueue->isEmpty() == false );
1066 BOOST_CHECK( aqueue->enqueue( d ) == false );
1069 aqueue->dequeue( d );
1071 BOOST_CHECK( aqueue->isFull() == false );
1074 for (
int i = 0; i <
QS - 1 ; ++i) {
1075 BOOST_CHECK( aqueue->dequeue( d ) ==
true);
1079 BOOST_CHECK( aqueue->isFull() == false );
1080 BOOST_CHECK( aqueue->isEmpty() == true );
1081 BOOST_CHECK( aqueue->dequeue(d) == false );
1094 circular = clockfree;
1117 dataobj = dlockfree;
1138 .multiple_writers(
true)
1140 testBufMultiThreaded(4, 1);
1146 .multiple_writers(
true)
1148 testBufMultiThreaded(4, 1);
1157 .multiple_writers(
true)
1158 .multiple_readers(
true)
1160 testBufMultiThreaded(4, 4);
1166 .multiple_writers(
true)
1167 .multiple_readers(
true)
1169 testBufMultiThreaded(4, 4);
1178 .multiple_writers(
true)
1179 .multiple_readers(
true)
1181 testBufMultiThreaded(4, 4);
1187 .multiple_writers(
true)
1188 .multiple_readers(
true)
1190 testBufMultiThreaded(4, 4);
1197 testDObjMultiThreaded(4, 1);
1204 testDObjMultiThreaded(1, 4);
1211 testDObjMultiThreaded(4, 4);
1218 testDObjMultiThreaded(1, 4);
1229 BOOST_REQUIRE_EQUAL( sz, mpool->
capacity() );
1230 BOOST_REQUIRE_EQUAL( sz, vpool->
capacity() );
1231 BOOST_CHECK_EQUAL( sz, mpool->
size());
1232 BOOST_CHECK_EQUAL( sz, vpool->
size());
1237 std::vector<Dummy>* v = vpool->allocate();
1238 BOOST_CHECK_EQUAL( sz - 1, vpool->
size());
1239 std::vector<Dummy>::size_type szv =
QS;
1240 BOOST_REQUIRE_EQUAL( szv, v->size() );
1241 BOOST_REQUIRE_EQUAL( szv, v->capacity() );
1242 BOOST_CHECK(vpool->deallocate( v ));
1243 BOOST_CHECK_EQUAL( sz, vpool->
size());
1245 BOOST_CHECK_EQUAL( vpool->size(),
QS);
1248 std::vector<Dummy*> mpv;
1251 mpv.push_back( mpool->allocate() );
1252 BOOST_CHECK_EQUAL( sz - i - 1, mpool->
size());
1253 BOOST_CHECK( mpv.back() );
1254 BOOST_REQUIRE_EQUAL( sz, mpool->
capacity() );
1256 BOOST_CHECK_EQUAL( mpool->size(), 0);
1257 BOOST_CHECK_EQUAL( mpool->allocate(), (
Dummy*)0 );
1259 BOOST_CHECK_EQUAL( i , mpool->size());
1260 BOOST_CHECK(mpool->deallocate( mpv.front() ));
1261 BOOST_CHECK_EQUAL( i + 1, mpool->size());
1262 mpv.erase( mpv.begin() );
1263 BOOST_REQUIRE_EQUAL( sz, mpool->
capacity() );
1265 BOOST_CHECK_EQUAL( mpv.size(), 0 );
1266 BOOST_CHECK_EQUAL( mpool->size(),
QS);
1271 Logger::In in(
"testMemoryPoolMultiThreaded");
1272 int number_of_workers =
QS;
1275 BOOST_CHECK_EQUAL( mpool->size(),
QS);
1277 BOOST_REQUIRE( workers.start() );
1279 BOOST_REQUIRE( workers.stop() );
1280 BOOST_CHECK_EQUAL( mpool->size(),
QS);
1282 int total_cycles = 0;
1284 BOOST_CHECK_GT(worker.first->cycles, 0);
1285 log(
Info) << worker.second->getName() <<
": " << worker.first->cycles <<
" cycles" <<
endlog();
1286 total_cycles += worker.first->cycles;
1290 BOOST_CHECK_EQUAL( vpool->size(),
QS);
1292 BOOST_REQUIRE( workers.start() );
1294 BOOST_REQUIRE( workers.stop() );
1295 BOOST_CHECK_EQUAL( vpool->size(),
QS);
1297 int total_cycles = 0;
1299 BOOST_CHECK_GT(worker.first->cycles, 0);
1300 log(
Info) << worker.second->getName() <<
": " << worker.first->cycles <<
" cycles" <<
endlog();
1301 total_cycles += worker.first->cycles;
1311 BOOST_CHECK( mslist->empty() );
1314 BOOST_CHECK( mslist->hasKey(
Dummy()) == false );
1317 BOOST_CHECK( mslist->erase(
Dummy()) == false );
1320 BOOST_CHECK( mslist->insert(
Dummy(1,2,1)) == true );
1321 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,1)) == true );
1323 BOOST_CHECK( mslist->insert(
Dummy(1,2,1)) == false );
1324 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,1)) == true );
1327 BOOST_CHECK( mslist->erase(
Dummy(1,2,1)) == true );
1328 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,1)) == false );
1329 BOOST_CHECK( mslist->erase(
Dummy(1,2,1)) == false );
1330 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,1)) == false );
1332 BOOST_CHECK( mslist->insert(
Dummy(1,2,1)) == true );
1333 BOOST_CHECK( mslist->insert(
Dummy(1,2,2)) == true );
1334 BOOST_CHECK( mslist->insert(
Dummy(1,2,3)) == true );
1335 BOOST_CHECK( mslist->insert(
Dummy(1,2,4)) == true );
1336 BOOST_CHECK( mslist->insert(
Dummy(1,2,5)) == true );
1337 BOOST_CHECK( mslist->insert(
Dummy(1,2,6)) == true );
1338 BOOST_CHECK( mslist->insert(
Dummy(1,2,7)) == true );
1340 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,4)) == true );
1341 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,7)) == true );
1343 BOOST_CHECK( mslist->erase(
Dummy(1,2,7)) == true );
1344 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,7)) == false );
1346 BOOST_CHECK( mslist->erase(
Dummy(1,2,4)) == true );
1347 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,4)) == false );
1349 mslist->applyOnData( &
addOne );
1350 BOOST_CHECK( mslist->hasKey(
Dummy(2,3,2)) == true );
1351 BOOST_CHECK( mslist->hasKey(
Dummy(2,3,3)) == true );
1352 BOOST_CHECK( mslist->hasKey(
Dummy(2,3,4)) == true );
1353 BOOST_CHECK( mslist->hasKey(
Dummy(2,3,6)) == true );
1354 BOOST_CHECK( mslist->hasKey(
Dummy(2,3,7)) == true );
1356 mslist->applyOnData( &
subOne );
1357 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,1)) == true );
1358 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,2)) == true );
1359 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,3)) == true );
1360 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,5)) == true );
1361 BOOST_CHECK( mslist->hasKey(
Dummy(1,2,6)) == true );
1363 BOOST_CHECK( mslist->erase(
Dummy(1,2,1)) == true );
1364 BOOST_CHECK( mslist->erase(
Dummy(1,2,6)) == true );
1365 BOOST_CHECK( mslist->erase(
Dummy(1,2,5)) == true );
1366 BOOST_CHECK( mslist->erase(
Dummy(1,2,2)) == true );
1367 BOOST_CHECK( mslist->erase(
Dummy(1,2,3)) == true );
1369 BOOST_CHECK( mslist->empty() );
1374 #ifdef OROPKG_OS_GNULINUX 1381 BOOST_REQUIRE_EQUAL( 10, listlockfree->
capacity() );
1382 BOOST_REQUIRE_EQUAL( 0, listlockfree->
size() );
1390 BOOST_REQUIRE(pool.start());
1393 BOOST_REQUIRE(gthread->start());
1395 BOOST_REQUIRE(gthread->stop());
1398 BOOST_REQUIRE(pool.stop());
1403 log(
Info) << it->second->getName() <<
" appends: " << it->first->appends<<
endlog();
1404 log(
Info) << it->second->getName() <<
" erases: " << it->first->erases<<
endlog();
1416 BOOST_CHECK_EQUAL( it->first->appends, it->first->erases );
1421 delete listlockfree;
1432 boost::scoped_ptr<Activity> gthread(
new Activity(20, grower,
"AQGrower"));
1433 boost::scoped_ptr<Activity> ethread(
new Activity(20, eater,
"AQEater"));
1440 log(
Info) <<
"Stressing multi-read/multi-write..." <<
endlog();
1441 BOOST_REQUIRE(pool.
start());
1443 log(
Info) <<
"Stressing multi-read/multi-write...on full buffer" <<
endlog();
1444 BOOST_REQUIRE(gthread->start());
1446 BOOST_REQUIRE(gthread->
stop());
1447 log(
Info) <<
"Stressing multi-read/multi-write...on empty buffer" <<
endlog();
1448 BOOST_REQUIRE(ethread->start());
1450 BOOST_REQUIRE(pool.
stop());
1454 BOOST_REQUIRE(gthread->
stop());
1455 BOOST_REQUIRE(ethread->stop());
1461 appends += it->first->appends;
1462 erases += it->first->erases;
1465 erases += eater->erases;
1468 <<
"Total appends: " << appends <<
endlog();
1470 if (appends != erases +
int(qt->
size())) {
1475 BOOST_CHECK( qt->
size() <=
QS );
1476 while( qt->
size() != 0 ) {
1477 BOOST_CHECK( qt->
dequeue(d) ==
true);
1481 BOOST_CHECK( i <=
QS);
1486 BOOST_CHECK( qt->
dequeue(d) == false );
1487 BOOST_CHECK( qt->
dequeue(d) == false );
1489 BOOST_CHECK_EQUAL( qt->
size(), 0 );
1492 BOOST_CHECK_EQUAL( appends,
1509 boost::scoped_ptr<Activity> gthread(
new Activity(20, grower,
"AQGrower"));
1510 boost::scoped_ptr<Activity> ethread(
new Activity(20, eater,
"AQEater"));
1517 log(
Info) <<
"Stressing multi-write/single-read..." <<
endlog();
1518 BOOST_REQUIRE(pool.
start());
1519 BOOST_REQUIRE(gthread->start());
1520 BOOST_REQUIRE(ethread->start());
1522 BOOST_REQUIRE(pool.
stop());
1523 log(
Info) <<
"Stressing single-write/single-read..." <<
endlog();
1525 BOOST_REQUIRE(gthread->
stop());
1526 BOOST_REQUIRE(ethread->stop());
1532 appends += it->first->appends;
1535 erases += eater->erases;
1538 <<
"Total appends: " << appends <<
endlog();
1540 if (appends !=
int(qt->
size()) + erases) {
1545 BOOST_CHECK( qt->
size() <=
QS );
1546 while( qt->
size() != 0 ) {
1547 BOOST_CHECK( qt->
dequeue(d) ==
true);
1551 BOOST_CHECK( i <=
QS);
1556 BOOST_CHECK( qt->
dequeue(d) == false );
1557 BOOST_CHECK( qt->
dequeue(d) == false );
1559 BOOST_CHECK_EQUAL( qt->
size(), 0 );
1562 BOOST_CHECK_EQUAL( appends,
void testDObjMultiThreaded(int number_of_writers, int number_of_readers)
static Logger::LogFunction nlog()
#define BOOST_FIXTURE_TEST_SUITE(suite_name, F)
BufferWriter(BufferInterface< Dummy > *buffer)
BufferInterface< Dummy > * buffer
ReadsByStatusMap reads_by_status
~BuffersAtomicMWMRQueueTest()
BOOST_AUTO_TEST_CASE(testAtomicMWMRQueue)
BufferInterface< Dummy > * circular
BufferReader(BufferInterface< Dummy > *buffer)
DataObjectLockFree< Dummy > * dlockfree
BufferLocked< Dummy > * clocked
AtomicMWSRQueue< Dummy * > MWSRQueueType
ThreadInterface * bthread
void testBufMultiThreaded(int number_of_writers, int number_of_readers)
#define BOOST_AUTO_TEST_SUITE_END()
std::vector< std::pair< boost::shared_ptr< Worker >, boost::shared_ptr< ThreadInterface > > > Threads
A class for running a certain piece of code in a thread.
ThreadInterface * athread
BufferInterface< Dummy > * buffer
~BuffersAtomicMWSRQueueTest()
A class which provides unprotected (not thread-safe) access to one typed element of data...
Worker(TsPool< T > *pool)
DataObjectInterface< Dummy > * dataobj
BufferLockFree< Dummy > * clockfree
ThreadPool(int threads, int scheduler, int priority, Seconds period, const std::string &name, const Arg1 &arg1)
DataObjectReader(DataObjectInterface< Dummy > *dataobj)
BuffersAtomicMWMRQueueTest()
std::ostream & operator<<(std::ostream &os, const std::vector< double > &vect)
BufferUnSync< Dummy > * cunsync
DataObjectInterface< Dummy > * dataobj
Dummy(double a=0.0, double b=1.0, double c=2.0)
Threads::value_type value_type
DataObjectLocked< Dummy > * dlocked
This DataObject is a Lock-Free implementation, such that reads and writes can happen concurrently wit...
ThreadInterface * athread
ThreadInterface * bthread
DataObjectUnSync< Dummy > * dunsync
BufferInterface< Dummy > * buffer
Threads::iterator iterator
An Activity executes a RunnableInterface object in a (periodic) thread.
A DataObjectInterface implements multi-threaded read/write solutions.
unsigned int sleep(unsigned int s)
bool operator<(const Dummy &d) const
ReadsByStatusMap reads_by_status
A class which provides locked/protected access to one typed element of data.
TsPool< std::vector< Dummy > > * vpool
DataObjectWriter(DataObjectInterface< Dummy > *dataobj)
BufferUnSync< Dummy > * unsync
BuffersAtomicMWSRQueueTest()
An object oriented wrapper around a non recursive mutex.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
BufferLockFree< Dummy > * lockfree
bool operator!=(const Dummy &d) const
bool operator==(const Dummy &d) const
DataObjectInterface< Dummy > * dataobj
AtomicMWMRQueue< Dummy * > MWMRQueueType
std::map< FlowStatus, int > ReadsByStatusMap
Threads::const_iterator const_iterator
static Logger::LogFunction endlog()
BufferLocked< Dummy > * locked
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...