00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "unit.hpp"
00020
00021 #include <iostream>
00022 #include <boost/scoped_ptr.hpp>
00023
00024 #include <internal/AtomicQueue.hpp>
00025 #include <internal/AtomicMWSRQueue.hpp>
00026
00027 #include <Activity.hpp>
00028
00029 #include <RTT.hpp>
00030 #include <base/Buffer.hpp>
00031 #include <internal/ListLockFree.hpp>
00032 #include <base/DataObject.hpp>
00033 #include <internal/TsPool.hpp>
00034
00035
00036 #include <os/Thread.hpp>
00037 #include <rtt-config.h>
00038
00039 using namespace std;
00040 using namespace RTT;
00041 using namespace RTT::detail;
00042
00043 class Dummy {
00044 public:
00045 Dummy(double a = 0.0, double b =1.0, double c=2.0)
00046 :d1(a), d2(b), d3(c) {}
00047 double d1;
00048 double d2;
00049 double d3;
00050 bool operator==(const Dummy& d) const
00051 {
00052 return d.d1 == d1 && d.d2 == d2 && d.d3 == d3;
00053 }
00054
00055 bool operator!=(const Dummy& d) const
00056 {
00057 return d.d1 != d1 || d.d2 != d2 || d.d3 != d3;
00058 }
00059
00060 bool operator<(const Dummy& d) const
00061 {
00062 return d1+d2+d3 < d.d1 + d.d2 + d.d3;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 };
00074
00075
00076 typedef AtomicQueue<Dummy*> QueueType;
00077 typedef AtomicMWSRQueue<Dummy*> MWSRQueueType;
00078
00079
00080
00081 #define QS 10
00082
00083 class BuffersAQueueTest
00084 {
00085 public:
00086 AtomicQueue<Dummy*>* aqueue;
00087 ThreadInterface* athread;
00088 ThreadInterface* bthread;
00089 ListLockFree<Dummy>* listlockfree;
00090
00091 BuffersAQueueTest()
00092 {
00093 aqueue = new AtomicQueue<Dummy*>(QS);
00094 listlockfree = new ListLockFree<Dummy>(10, 4);
00095 }
00096 ~BuffersAQueueTest(){
00097 aqueue->clear();
00098 delete aqueue;
00099 delete listlockfree;
00100 }
00101 };
00102
00103 class BuffersAtomicMWSRQueueTest
00104 {
00105 public:
00106 AtomicMWSRQueue<Dummy*>* aqueue;
00107
00108 BuffersAtomicMWSRQueueTest()
00109 {
00110 aqueue = new AtomicMWSRQueue<Dummy*>(QS);
00111 }
00112 ~BuffersAtomicMWSRQueueTest(){
00113 aqueue->clear();
00114 delete aqueue;
00115 }
00116 };
00117
00118 class BuffersDataFlowTest
00119 {
00120 public:
00121 BufferLockFree<Dummy>* lockfree;
00122 DataObjectLockFree<Dummy>* dataobj;
00123
00124 ThreadInterface* athread;
00125 ThreadInterface* bthread;
00126
00127 BuffersDataFlowTest()
00128 {
00129 lockfree = new BufferLockFree<Dummy>(QS);
00130
00131 dataobj = new DataObjectLockFree<Dummy>();
00132 }
00133
00134 ~BuffersDataFlowTest(){
00135 delete lockfree;
00136 delete dataobj;
00137 }
00138 };
00139
00140 class BuffersMPoolTest
00141 {
00142 public:
00143
00144 ThreadInterface* athread;
00145 ThreadInterface* bthread;
00146
00147 TsPool<Dummy>* mpool;
00148 TsPool<std::vector<Dummy> >* vpool;
00149
00150 BuffersMPoolTest()
00151 {
00152 mpool = new TsPool<Dummy>(QS);
00153 vpool = new TsPool<std::vector<Dummy> >(QS, std::vector<Dummy>(QS) );
00154 }
00155
00156 ~BuffersMPoolTest(){
00157 delete mpool;
00158 delete vpool;
00159 }
00160 };
00161
00162
00163 std::ostream& operator<<( std::ostream& os, const Dummy& d ) {
00164 os << "(" << d.d1 <<","<<d.d2<<","<<d.d3<<")";
00165 return os;
00166 }
00167 void addOne(Dummy& d)
00168 {
00169 ++d.d1;
00170 ++d.d2;
00171 ++d.d3;
00172 }
00173
00174 void subOne(Dummy& d)
00175 {
00176 --d.d1;
00177 --d.d2;
00178 --d.d3;
00179 }
00180
00181
00182 struct LLFWorker : public RunnableInterface
00183 {
00184 volatile bool stop;
00185 typedef ListLockFree<Dummy> T;
00186 T* mlst;
00187 int i;
00188 int appends;
00189 int erases;
00190 LLFWorker(T* l ) : stop(false), mlst(l), i(1) {}
00191 bool initialize() {
00192 stop = false; i = 1;
00193 appends = 0; erases = 0;
00194 return true;
00195 }
00196 void step() {
00197 while (stop == false ) {
00198
00199 while ( mlst->append( Dummy(i,i,i) ) ) { ++i; ++appends; }
00200
00201 while ( mlst->erase( Dummy(i-1,i-1,i-1) ) ) { --i; ++erases; }
00202 }
00203
00204 }
00205
00206 void finalize() {}
00207
00208 bool breakLoop() {
00209 stop = true;
00210 return true;
00211 }
00212 };
00213
00214 struct LLFGrower : public RunnableInterface
00215 {
00216 volatile bool stop;
00217 typedef ListLockFree<Dummy> T;
00218 T* mlst;
00219 int i;
00220 LLFGrower(T* l ) : stop(false), mlst(l), i(1) {}
00221 bool initialize() {
00222 stop = false; i = 1;
00223 return true;
00224 }
00225 void step() {
00226
00227 while (stop == false && i < 2500 ) {
00228
00229 mlst->reserve(i);
00230 ++i;
00231 }
00232 }
00233
00234 void finalize() {}
00235
00236 bool breakLoop() {
00237 stop = true;
00238 return true;
00239 }
00240 };
00241
00245 template<class T>
00246 struct AQWorker : public RunnableInterface
00247 {
00248 static os::Mutex m;
00249 bool stop;
00250 T* mlst;
00251 int appends;
00252 int erases;
00253 Dummy* orig;
00254 AQWorker(T* l ) : stop(false), mlst(l),appends(0), erases(0) {
00255 orig = new Dummy( 1,2,3);
00256 }
00257 ~AQWorker() {
00258 delete orig;
00259 }
00260 bool initialize() {
00261 stop = false;
00262 return true;
00263 }
00264 void step() {
00265 Dummy* d = orig;
00266 while (stop == false ) {
00267
00268 if ( mlst->enqueue( d ) ) { ++appends; }
00269
00270 if ( mlst->dequeue( d ) ) {
00271 if( *d != *orig) {
00272 os::MutexLock lock(m);
00273 assert(*d == *orig);
00274 }
00275 ++erases;
00276 }
00277 }
00278
00279 }
00280
00281 void finalize() {}
00282
00283 bool breakLoop() {
00284 stop = true;
00285 return true;
00286 }
00287 };
00288
00289 template<class T>
00290 os::Mutex AQWorker<T>::m;
00291
00296 template<class T>
00297 struct AQGrower : public RunnableInterface
00298 {
00299 volatile bool stop;
00300 T* mlst;
00301 int appends;
00302 Dummy* orig;
00303 AQGrower(T* l ) : stop(false), mlst(l), appends(0) {
00304 orig = new Dummy( 1,2,3);
00305 }
00306 ~AQGrower() {
00307 delete orig;
00308 }
00309 bool initialize() {
00310 stop = false;
00311 return true;
00312 }
00313 void step() {
00314
00315 Dummy* d = orig;
00316 while (stop == false ) {
00317 if ( mlst->enqueue(d) ) {
00318 ++appends;
00319 }
00320 }
00321 }
00322
00323 void finalize() {}
00324
00325 bool breakLoop() {
00326 stop = true;
00327 return true;
00328 }
00329 };
00330
00335 template<class T>
00336 struct AQEater : public RunnableInterface
00337 {
00338 volatile bool stop;
00339 T* mlst;
00340 int erases;
00341 AQEater(T* l ) : stop(false), mlst(l), erases(0) {}
00342 bool initialize() {
00343 stop = false;
00344 return true;
00345 }
00346 void step() {
00347
00348 Dummy* d;
00349 while (stop == false ) {
00350 if ( mlst->dequeue(d) ) {
00351
00352
00353 ++erases;
00354 }
00355 }
00356 }
00357
00358 void finalize() {}
00359
00360 bool breakLoop() {
00361 stop = true;
00362 return true;
00363 }
00364 };
00365
00366
00367 BOOST_FIXTURE_TEST_SUITE( BuffersAtomicTestSuite, BuffersAQueueTest )
00368
00369 BOOST_AUTO_TEST_CASE( testAtomicQueue )
00370 {
00374 Dummy* d = new Dummy();
00375 Dummy* c = d;
00376
00377 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->capacity() );
00378 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(0), aqueue->size() );
00379 BOOST_CHECK( aqueue->isFull() == false );
00380 BOOST_CHECK( aqueue->isEmpty() == true );
00381 BOOST_CHECK( aqueue->dequeue(c) == false );
00382 BOOST_CHECK( c == d );
00383
00384 for ( int i = 0; i < QS; ++i) {
00385 BOOST_CHECK( aqueue->enqueue( d ) == true);
00386 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(i+1), aqueue->size() );
00387 }
00388 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->capacity() );
00389 BOOST_CHECK( aqueue->isFull() == true );
00390 BOOST_CHECK( aqueue->isEmpty() == false );
00391 BOOST_CHECK( aqueue->enqueue( d ) == false );
00392 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->size() );
00393
00394 aqueue->dequeue( d );
00395 BOOST_CHECK( aqueue->isFull() == false );
00396 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS-1), aqueue->size() );
00397
00398 for ( int i = 0; i < QS - 1 ; ++i) {
00399 BOOST_CHECK( aqueue->dequeue( d ) == true);
00400 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS - 2 - i), aqueue->size() );
00401 }
00402 BOOST_CHECK( aqueue->isFull() == false );
00403 BOOST_CHECK( aqueue->isEmpty() == true );
00404
00405 delete d;
00406 }
00407 BOOST_AUTO_TEST_SUITE_END()
00408
00409 BOOST_FIXTURE_TEST_SUITE( BuffersMWSRQueueTestSuite, BuffersAtomicMWSRQueueTest )
00410
00411 BOOST_AUTO_TEST_CASE( testAtomicMWSRQueue )
00412 {
00416 Dummy* d = new Dummy();
00417 Dummy* c = d;
00418
00419 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->capacity() );
00420 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(0), aqueue->size() );
00421 BOOST_CHECK( aqueue->isFull() == false );
00422 BOOST_CHECK( aqueue->isEmpty() == true );
00423 BOOST_CHECK( aqueue->dequeue(c) == false );
00424 BOOST_CHECK( c == d );
00425
00426 for ( int i = 0; i < QS; ++i) {
00427 BOOST_CHECK( aqueue->enqueue( d ) == true);
00428 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(i+1), aqueue->size() );
00429 BOOST_CHECK( d );
00430 }
00431 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->capacity() );
00432 BOOST_CHECK( aqueue->isFull() == true );
00433 BOOST_CHECK( aqueue->isEmpty() == false );
00434 BOOST_CHECK( aqueue->enqueue( d ) == false );
00435 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS), aqueue->size() );
00436 d = 0;
00437 aqueue->dequeue( d );
00438 BOOST_CHECK( d );
00439 BOOST_CHECK( aqueue->isFull() == false );
00440 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS-1), aqueue->size() );
00441
00442 for ( int i = 0; i < QS - 1 ; ++i) {
00443 BOOST_CHECK( aqueue->dequeue( d ) == true);
00444 BOOST_REQUIRE_EQUAL( AtomicQueue<Dummy*>::size_type(QS - 2 - i), aqueue->size() );
00445 BOOST_CHECK( d );
00446 }
00447 BOOST_CHECK( aqueue->isFull() == false );
00448 BOOST_CHECK( aqueue->isEmpty() == true );
00449 BOOST_CHECK( aqueue->dequeue(d) == false );
00450 BOOST_CHECK( d );
00451
00452 delete d;
00453 }
00454
00455 BOOST_AUTO_TEST_SUITE_END()
00456
00457 BOOST_FIXTURE_TEST_SUITE( BuffersDataFlowTestSuite, BuffersDataFlowTest )
00458
00459 BOOST_AUTO_TEST_CASE( testBufLockFree )
00460 {
00466 Dummy* d = new Dummy;
00467 Dummy* c = new Dummy(2.0, 1.0, 0.0);
00468 Dummy r;
00469
00470 BOOST_CHECK( lockfree->Pop(r) == false );
00471
00472 BOOST_CHECK( lockfree->Push( *d ) );
00473 BOOST_CHECK( lockfree->Pop(r) );
00474 BOOST_CHECK( r == *d );
00475
00476 BOOST_CHECK( lockfree->Push( *c ) );
00477 BOOST_CHECK( lockfree->Pop(r) );
00478 BOOST_CHECK( r == *c );
00479
00480 BOOST_CHECK( lockfree->Push( *d ) );
00481 BOOST_CHECK( lockfree->Push( *c ) );
00482 BOOST_CHECK( lockfree->Push( *d ) );
00483 BOOST_CHECK( lockfree->Push( *c ) );
00484 BOOST_CHECK( lockfree->Push( *d ) );
00485 BOOST_CHECK( lockfree->Push( *c ) );
00486 BOOST_CHECK( lockfree->Push( *d ) );
00487 BOOST_CHECK( lockfree->Push( *c ) );
00488 BOOST_CHECK( lockfree->Push( *d ) );
00489 BOOST_CHECK( lockfree->Push( *c ) );
00490 BOOST_CHECK( lockfree->Push( *c ) == false );
00491 BOOST_CHECK( lockfree->Push( *c ) == false );
00492 BOOST_CHECK( lockfree->Push( *c ) == false );
00493 BOOST_CHECK( lockfree->Push( *c ) == false );
00494 BOOST_CHECK( lockfree->Push( *c ) == false );
00495 BOOST_CHECK( lockfree->Push( *c ) == false );
00496 BOOST_CHECK( lockfree->Push( *c ) == false );
00497 BOOST_CHECK( lockfree->Push( *c ) == false );
00498 BOOST_CHECK( lockfree->Push( *c ) == false );
00499 BOOST_CHECK( lockfree->Push( *c ) == false );
00500 BOOST_CHECK( lockfree->Push( *c ) == false );
00501 BOOST_CHECK( lockfree->Push( *c ) == false );
00502 BOOST_CHECK( lockfree->Pop(r) );
00503 BOOST_CHECK( r == *d );
00504 BOOST_CHECK( lockfree->Pop(r) );
00505 BOOST_CHECK( r == *c );
00506 BOOST_CHECK( lockfree->Pop(r) );
00507 BOOST_CHECK( r == *d );
00508 BOOST_CHECK( lockfree->Pop(r) );
00509 BOOST_CHECK( r == *c );
00510 BOOST_CHECK( lockfree->Pop(r) );
00511 BOOST_CHECK( r == *d );
00512
00513
00514 BOOST_CHECK( lockfree->Push( *d ) );
00515 BOOST_CHECK( lockfree->Push( *c ) );
00516 BOOST_CHECK( lockfree->Push( *d ) );
00517 BOOST_CHECK( lockfree->Push( *c ) );
00518 BOOST_CHECK( lockfree->Push( *d ) );
00519
00520 BOOST_CHECK( lockfree->Pop(r) );
00521 BOOST_CHECK( r == *c );
00522 BOOST_CHECK( lockfree->Pop(r) );
00523 BOOST_CHECK( r == *d );
00524 BOOST_CHECK( lockfree->Pop(r) );
00525 BOOST_CHECK( r == *c );
00526 BOOST_CHECK( lockfree->Pop(r) );
00527 BOOST_CHECK( r == *d );
00528 BOOST_CHECK( lockfree->Pop(r) );
00529 BOOST_CHECK( r == *c );
00530 BOOST_CHECK( lockfree->Pop(r) );
00531 BOOST_CHECK( r == *d );
00532 BOOST_CHECK( lockfree->Pop(r) );
00533 BOOST_CHECK( r == *c );
00534 BOOST_CHECK( lockfree->Pop(r) );
00535 BOOST_CHECK( r == *d );
00536 BOOST_CHECK( lockfree->Pop(r) );
00537 BOOST_CHECK( r == *c );
00538 BOOST_CHECK( lockfree->Pop(r) );
00539 BOOST_CHECK( r == *d );
00540
00541 BOOST_CHECK( lockfree->Pop(r) == false );
00542 BOOST_CHECK( lockfree->Pop(r) == false );
00543 BOOST_CHECK( lockfree->Pop(r) == false );
00544 BOOST_CHECK( lockfree->Pop(r) == false );
00545 BOOST_CHECK( lockfree->Pop(r) == false );
00546 BOOST_CHECK( lockfree->Pop(r) == false );
00547 BOOST_CHECK( lockfree->Pop(r) == false );
00548 BOOST_CHECK( lockfree->Pop(r) == false );
00549 BOOST_CHECK( lockfree->Pop(r) == false );
00550 BOOST_CHECK( lockfree->Pop(r) == false );
00551 BOOST_CHECK( lockfree->Pop(r) == false );
00552
00553 BOOST_CHECK( lockfree->Push( *c ) );
00554 BOOST_CHECK( lockfree->Push( *d ) );
00555 BOOST_CHECK( lockfree->Push( *c ) );
00556 BOOST_CHECK( lockfree->Push( *d ) );
00557 BOOST_CHECK( lockfree->Push( *c ) );
00558
00559 std::vector<Dummy> v;
00560 BOOST_CHECK( 5 == lockfree->Pop(v) );
00561 BOOST_CHECK( v[0] == *c );
00562 BOOST_CHECK( v[1] == *d );
00563 BOOST_CHECK( v[2] == *c );
00564 BOOST_CHECK( v[3] == *d );
00565 BOOST_CHECK( v[4] == *c );
00566
00567 BufferBase::size_type sz = 10;
00568 BOOST_CHECK( lockfree->Push( *c ) );
00569 BOOST_CHECK( lockfree->Push( *d ) );
00570 BOOST_CHECK( lockfree->Push( v ) == (int)v.size() );
00571 BOOST_CHECK( lockfree->Push( *c ) );
00572 BOOST_CHECK( lockfree->Push( *d ) );
00573 BOOST_CHECK( lockfree->Push( v ) == 1 );
00574 BOOST_CHECK( lockfree->Push( v ) == 0 );
00575 BOOST_CHECK( lockfree->Push( v ) == 0 );
00576 BOOST_CHECK( lockfree->Push( v ) == 0 );
00577 BOOST_CHECK( lockfree->Push( v ) == 0 );
00578 BOOST_CHECK( lockfree->Push( v ) == 0 );
00579 BOOST_CHECK( lockfree->Push( v ) == 0 );
00580 BOOST_CHECK( lockfree->Push( v ) == 0 );
00581 BOOST_CHECK( lockfree->Push( v ) == 0 );
00582 BOOST_CHECK( lockfree->Push( v ) == 0 );
00583 BOOST_CHECK( lockfree->Push( v ) == 0 );
00584 BOOST_CHECK( lockfree->Push( v ) == 0 );
00585 BOOST_CHECK( lockfree->Push( v ) == 0 );
00586 BOOST_REQUIRE_EQUAL( sz, lockfree->Pop(v) );
00587 BOOST_CHECK( v[0] == *c );
00588 BOOST_CHECK( v[1] == *d );
00589 BOOST_CHECK( v[2] == *c );
00590 BOOST_CHECK( v[3] == *d );
00591 BOOST_CHECK( v[4] == *c );
00592 BOOST_CHECK( v[5] == *d );
00593 BOOST_CHECK( v[6] == *c );
00594 BOOST_CHECK( v[7] == *c );
00595 BOOST_CHECK( v[8] == *d );
00596 BOOST_CHECK( v[9] == *c );
00597 BOOST_CHECK( 0 == lockfree->Pop(v) );
00598 delete d;
00599 delete c;
00600 }
00601
00602 BOOST_AUTO_TEST_CASE( testDObjLockFree )
00603 {
00604 Dummy* c = new Dummy(2.0, 1.0, 0.0);
00605 Dummy d;
00606 dataobj->Set( *c );
00607 BOOST_REQUIRE_EQUAL( *c, dataobj->Get() );
00608 int i = 0;
00609 while ( i != 3.5*dataobj->MAX_THREADS ) {
00610 dataobj->Set( *c );
00611 dataobj->Set( d );
00612 ++i;
00613 }
00614 BOOST_REQUIRE_EQUAL( d , dataobj->Get() );
00615 BOOST_REQUIRE_EQUAL( d , dataobj->Get() );
00616
00617 delete c;
00618 }
00619
00620 BOOST_AUTO_TEST_SUITE_END()
00621 BOOST_FIXTURE_TEST_SUITE( BuffersMPoolTestSuite, BuffersMPoolTest )
00622
00623 BOOST_AUTO_TEST_CASE( testMemoryPool )
00624 {
00625
00626 TsPool<Dummy>::size_type sz = QS;
00627
00628 BOOST_REQUIRE_EQUAL( sz, mpool->capacity() );
00629 BOOST_REQUIRE_EQUAL( sz, vpool->capacity() );
00630 BOOST_CHECK_EQUAL( sz, mpool->size());
00631 BOOST_CHECK_EQUAL( sz, vpool->size());
00632
00633
00634 for (TsPool<Dummy>::size_type i = 0; i <3*sz; ++i ) {
00635
00636 std::vector<Dummy>* v = vpool->allocate();
00637 BOOST_CHECK_EQUAL( sz - 1, vpool->size());
00638 std::vector<Dummy>::size_type szv = QS;
00639 BOOST_REQUIRE_EQUAL( szv, v->size() );
00640 BOOST_REQUIRE_EQUAL( szv, v->capacity() );
00641 BOOST_CHECK(vpool->deallocate( v ));
00642 BOOST_CHECK_EQUAL( sz, vpool->size());
00643 }
00644 BOOST_CHECK_EQUAL( vpool->size(), QS);
00645
00646
00647 std::vector<Dummy*> mpv;
00648
00649 for (TsPool<Dummy>::size_type i = 0; i <sz; ++i ) {
00650 mpv.push_back( mpool->allocate() );
00651 BOOST_CHECK_EQUAL( sz - i - 1, mpool->size());
00652 BOOST_CHECK( mpv.back() );
00653 BOOST_REQUIRE_EQUAL( sz, mpool->capacity() );
00654 }
00655 BOOST_CHECK_EQUAL( mpool->size(), 0);
00656 BOOST_CHECK_EQUAL( mpool->allocate(), (Dummy*)0 );
00657 for (TsPool<Dummy>::size_type i = 0; i <sz; ++i ) {
00658 BOOST_CHECK_EQUAL( i , mpool->size());
00659 BOOST_CHECK(mpool->deallocate( mpv.front() ));
00660 BOOST_CHECK_EQUAL( i + 1, mpool->size());
00661 mpv.erase( mpv.begin() );
00662 BOOST_REQUIRE_EQUAL( sz, mpool->capacity() );
00663 }
00664 BOOST_CHECK_EQUAL( mpv.size(), 0 );
00665 BOOST_CHECK_EQUAL( mpool->size(), QS);
00666 }
00667
00668 #if 0
00669 BOOST_AUTO_TEST_CASE( testSortedList )
00670 {
00671
00672 mslist->reserve(7);
00673 BOOST_CHECK( mslist->empty() );
00674
00675
00676 BOOST_CHECK( mslist->hasKey(Dummy()) == false );
00677
00678
00679 BOOST_CHECK( mslist->erase(Dummy()) == false );
00680
00681
00682 BOOST_CHECK( mslist->insert(Dummy(1,2,1)) == true );
00683 BOOST_CHECK( mslist->hasKey(Dummy(1,2,1)) == true );
00684
00685 BOOST_CHECK( mslist->insert(Dummy(1,2,1)) == false );
00686 BOOST_CHECK( mslist->hasKey(Dummy(1,2,1)) == true );
00687
00688
00689 BOOST_CHECK( mslist->erase(Dummy(1,2,1)) == true );
00690 BOOST_CHECK( mslist->hasKey(Dummy(1,2,1)) == false );
00691 BOOST_CHECK( mslist->erase(Dummy(1,2,1)) == false );
00692 BOOST_CHECK( mslist->hasKey(Dummy(1,2,1)) == false );
00693
00694 BOOST_CHECK( mslist->insert(Dummy(1,2,1)) == true );
00695 BOOST_CHECK( mslist->insert(Dummy(1,2,2)) == true );
00696 BOOST_CHECK( mslist->insert(Dummy(1,2,3)) == true );
00697 BOOST_CHECK( mslist->insert(Dummy(1,2,4)) == true );
00698 BOOST_CHECK( mslist->insert(Dummy(1,2,5)) == true );
00699 BOOST_CHECK( mslist->insert(Dummy(1,2,6)) == true );
00700 BOOST_CHECK( mslist->insert(Dummy(1,2,7)) == true );
00701
00702 BOOST_CHECK( mslist->hasKey(Dummy(1,2,4)) == true );
00703 BOOST_CHECK( mslist->hasKey(Dummy(1,2,7)) == true );
00704
00705 BOOST_CHECK( mslist->erase(Dummy(1,2,7)) == true );
00706 BOOST_CHECK( mslist->hasKey(Dummy(1,2,7)) == false );
00707
00708 BOOST_CHECK( mslist->erase(Dummy(1,2,4)) == true );
00709 BOOST_CHECK( mslist->hasKey(Dummy(1,2,4)) == false );
00710
00711 mslist->applyOnData( &addOne );
00712 BOOST_CHECK( mslist->hasKey(Dummy(2,3,2)) == true );
00713 BOOST_CHECK( mslist->hasKey(Dummy(2,3,3)) == true );
00714 BOOST_CHECK( mslist->hasKey(Dummy(2,3,4)) == true );
00715 BOOST_CHECK( mslist->hasKey(Dummy(2,3,6)) == true );
00716 BOOST_CHECK( mslist->hasKey(Dummy(2,3,7)) == true );
00717
00718 mslist->applyOnData( &subOne );
00719 BOOST_CHECK( mslist->hasKey(Dummy(1,2,1)) == true );
00720 BOOST_CHECK( mslist->hasKey(Dummy(1,2,2)) == true );
00721 BOOST_CHECK( mslist->hasKey(Dummy(1,2,3)) == true );
00722 BOOST_CHECK( mslist->hasKey(Dummy(1,2,5)) == true );
00723 BOOST_CHECK( mslist->hasKey(Dummy(1,2,6)) == true );
00724
00725 BOOST_CHECK( mslist->erase(Dummy(1,2,1)) == true );
00726 BOOST_CHECK( mslist->erase(Dummy(1,2,6)) == true );
00727 BOOST_CHECK( mslist->erase(Dummy(1,2,5)) == true );
00728 BOOST_CHECK( mslist->erase(Dummy(1,2,2)) == true );
00729 BOOST_CHECK( mslist->erase(Dummy(1,2,3)) == true );
00730
00731 BOOST_CHECK( mslist->empty() );
00732 }
00733 #endif
00734
00735 #ifdef OROPKG_OS_GNULINUX
00736
00737 BOOST_AUTO_TEST_SUITE_END()
00738 BOOST_FIXTURE_TEST_SUITE( BuffersStressLockFreeTestSuite, BuffersAQueueTest )
00739
00740 BOOST_AUTO_TEST_CASE( testListLockFree )
00741 {
00742 LLFWorker* aworker = new LLFWorker( listlockfree );
00743 LLFWorker* bworker = new LLFWorker( listlockfree );
00744 LLFWorker* cworker = new LLFWorker( listlockfree );
00745 LLFGrower* grower = new LLFGrower( listlockfree );
00746
00747 {
00748 boost::scoped_ptr<Activity> athread( new Activity(ORO_SCHED_OTHER, 0, 0, aworker, "ActivityA" ));
00749 boost::scoped_ptr<Activity> bthread( new Activity(ORO_SCHED_OTHER, 0, 0, bworker, "ActivityB" ));
00750 boost::scoped_ptr<Activity> cthread( new Activity(ORO_SCHED_OTHER, 0, 0, cworker, "ActivityC" ));
00751 boost::scoped_ptr<Activity> gthread( new Activity(ORO_SCHED_OTHER, 0, 0, grower, "ActivityG" ));
00752
00753 athread->start();
00754 bthread->start();
00755 cthread->start();
00756
00757 sleep(5);
00758 gthread->start();
00759 sleep(10);
00760 gthread->stop();
00761 sleep(5);
00762
00763 athread->stop();
00764 bthread->stop();
00765 cthread->stop();
00766 }
00767
00768 #if 0
00769 cout << "Athread appends: " << aworker->appends<<endl;
00770 cout << "Athread erases: " << aworker->erases<<endl;
00771 cout << "Bthread appends: " << bworker->appends<<endl;
00772 cout << "Bthread erases: " << bworker->erases<<endl;
00773 cout << "Cthread appends: " << cworker->appends<<endl;
00774 cout << "Cthread erases: " << cworker->erases<<endl;
00775 cout << "List capacity: "<< listlockfree->capacity()<<endl;
00776 cout << "List size: "<< listlockfree->size()<<endl;
00777
00778
00779
00780
00781
00782 #endif
00783
00784 BOOST_CHECK( aworker->appends == aworker->erases );
00785 BOOST_CHECK( bworker->appends == bworker->erases );
00786 BOOST_CHECK( cworker->appends == cworker->erases );
00787
00788 delete aworker;
00789 delete bworker;
00790 delete cworker;
00791 delete grower;
00792 }
00793 #endif
00794
00795 #ifdef OROPKG_OS_GNULINUX
00796 BOOST_AUTO_TEST_CASE( testAtomicQueue )
00797 {
00798 QueueType* qt = new QueueType(QS);
00799 AQWorker<QueueType>* aworker = new AQWorker<QueueType>( qt );
00800 AQWorker<QueueType>* bworker = new AQWorker<QueueType>( qt );
00801 AQWorker<QueueType>* cworker = new AQWorker<QueueType>( qt );
00802 AQGrower<QueueType>* grower = new AQGrower<QueueType>( qt );
00803 AQEater<QueueType>* eater = new AQEater<QueueType>( qt );
00804
00805 {
00806 boost::scoped_ptr<Activity> athread( new Activity(20, aworker, "ActivityA" ));
00807 boost::scoped_ptr<Activity> bthread( new Activity(20, bworker, "ActivityB" ));
00808 boost::scoped_ptr<Activity> cthread( new Activity(20, cworker, "ActivityC" ));
00809 boost::scoped_ptr<Activity> gthread( new Activity(20, grower, "ActivityG"));
00810 boost::scoped_ptr<Activity> ethread( new Activity(20, eater, "ActivityE"));
00811
00812
00813 athread->thread()->setScheduler(ORO_SCHED_OTHER);
00814 bthread->thread()->setScheduler(ORO_SCHED_OTHER);
00815 cthread->thread()->setScheduler(ORO_SCHED_OTHER);
00816 gthread->thread()->setScheduler(ORO_SCHED_OTHER);
00817
00818 log(Info) <<"Stressing multi-read/multi-write..." <<endlog();
00819 athread->start();
00820 bthread->start();
00821 cthread->start();
00822 sleep(5);
00823 log(Info) <<"Stressing multi-read/multi-write...on full buffer" <<endlog();
00824 gthread->start();
00825 sleep(5);
00826 gthread->stop();
00827 log(Info) <<"Stressing multi-read/multi-write...on empty buffer" <<endlog();
00828 ethread->start();
00829 sleep(5);
00830 athread->stop();
00831 bthread->stop();
00832 cthread->stop();
00833 gthread->start();
00834 log(Info) <<"Stressing read&write..." <<endlog();
00835 sleep(5);
00836 gthread->stop();
00837 ethread->stop();
00838 }
00839
00840 cout <<endl
00841 << "Total appends: " << aworker->appends + bworker->appends + cworker->appends+ grower->appends<<endl;
00842 cout << "Total erases : " << aworker->erases + bworker->erases+ cworker->erases + qt->size() + eater->erases <<endl;
00843 if (aworker->appends + bworker->appends + cworker->appends+ grower->appends != aworker->erases + bworker->erases+ cworker->erases + int(qt->size()) + eater->erases) {
00844 cout << "Mismatch detected !" <<endl;
00845 }
00846 int i = 0;
00847 Dummy* d = 0;
00848 BOOST_CHECK( qt->size() <= QS );
00849 while( qt->size() != 0 ) {
00850 BOOST_CHECK( qt->dequeue(d) == true);
00851 BOOST_CHECK( d );
00852 i++;
00853 if ( i > QS ) {
00854 BOOST_CHECK( i <= QS);
00855 break;
00856 }
00857 }
00858 cout << "Left in Queue: "<< i <<endl;
00859 BOOST_CHECK( qt->dequeue(d) == false );
00860 BOOST_CHECK( qt->dequeue(d) == false );
00861 BOOST_CHECK( qt->isEmpty() );
00862 BOOST_CHECK_EQUAL( qt->size(), 0 );
00863
00864
00865 BOOST_CHECK_EQUAL( aworker->appends + bworker->appends + cworker->appends + grower->appends,
00866 aworker->erases + bworker->erases + cworker->erases + i + eater->erases );
00867 delete aworker;
00868 delete bworker;
00869 delete cworker;
00870 delete grower;
00871 delete eater;
00872 }
00873
00874 BOOST_AUTO_TEST_CASE( testAtomicMWSRQueue )
00875 {
00876 MWSRQueueType* qt = new MWSRQueueType(QS);
00877 AQGrower<MWSRQueueType>* aworker = new AQGrower<MWSRQueueType>( qt );
00878 AQGrower<MWSRQueueType>* bworker = new AQGrower<MWSRQueueType>( qt );
00879 AQGrower<MWSRQueueType>* cworker = new AQGrower<MWSRQueueType>( qt );
00880 AQGrower<MWSRQueueType>* grower = new AQGrower<MWSRQueueType>( qt );
00881 AQEater<MWSRQueueType>* eater = new AQEater<MWSRQueueType>( qt );
00882
00883 {
00884 boost::scoped_ptr<Activity> athread( new Activity(20, aworker, "ActivityA" ));
00885 boost::scoped_ptr<Activity> bthread( new Activity(20, bworker, "ActivityB" ));
00886 boost::scoped_ptr<Activity> cthread( new Activity(20, cworker, "ActivityC" ));
00887 boost::scoped_ptr<Activity> gthread( new Activity(20, grower, "ActivityG"));
00888 boost::scoped_ptr<Activity> ethread( new Activity(20, eater, "ActivityE"));
00889
00890
00891 athread->thread()->setScheduler(ORO_SCHED_OTHER);
00892 bthread->thread()->setScheduler(ORO_SCHED_OTHER);
00893 cthread->thread()->setScheduler(ORO_SCHED_OTHER);
00894 gthread->thread()->setScheduler(ORO_SCHED_OTHER);
00895 ethread->thread()->setScheduler(ORO_SCHED_OTHER);
00896
00897 log(Info) <<"Stressing multi-write/single-read..." <<endlog();
00898 athread->start();
00899 bthread->start();
00900 cthread->start();
00901 gthread->start();
00902 ethread->start();
00903 sleep(5);
00904 athread->stop();
00905 bthread->stop();
00906 cthread->stop();
00907 log(Info) <<"Stressing single-write/single-read..." <<endlog();
00908 sleep(5);
00909 gthread->stop();
00910 ethread->stop();
00911 }
00912
00913 cout <<endl
00914 << "Total appends: " << aworker->appends + bworker->appends + cworker->appends+ grower->appends<<endl;
00915 cout << "Total erases : " << eater->erases <<endl;
00916 if (aworker->appends + bworker->appends + cworker->appends+ grower->appends != int(qt->size()) + eater->erases) {
00917 cout << "Mismatch detected !" <<endl;
00918 }
00919 int i = 0;
00920 Dummy* d = 0;
00921 BOOST_CHECK( qt->size() <= QS );
00922 while( qt->size() != 0 ) {
00923 BOOST_CHECK( qt->dequeue(d) == true);
00924 BOOST_CHECK( d );
00925 i++;
00926 if ( i > QS ) {
00927 BOOST_CHECK( i <= QS);
00928 break;
00929 }
00930 }
00931 cout << "Left in Queue: "<< i <<endl;
00932 BOOST_CHECK( qt->dequeue(d) == false );
00933 BOOST_CHECK( qt->dequeue(d) == false );
00934 BOOST_CHECK( qt->isEmpty() );
00935 BOOST_CHECK_EQUAL( qt->size(), 0 );
00936
00937
00938 BOOST_CHECK_EQUAL( aworker->appends + bworker->appends + cworker->appends + grower->appends,
00939 i + eater->erases );
00940 delete aworker;
00941 delete bworker;
00942 delete cworker;
00943 delete grower;
00944 delete eater;
00945 }
00946 #endif
00947 BOOST_AUTO_TEST_SUITE_END()