Logo Search packages:      
Sourcecode: u++ version File versions

Locks.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Peter A. Buhr 2001
// 
// Locks.cc -- 
// 
// Author           : Peter A. Buhr
// Created On       : Mon Dec 10 15:08:22 2001
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue Aug  3 23:45:11 2004
// Update Count     : 17
// 

#include <uC++.h>
#include <uSemaphore.h>
#include <uOStream.h>
#include <pthread.h>

const int NoOfTimes = 50000;

uOwnerLock sharedLock;
volatile uBaseTask *checkID;
uSemaphore start(0);

uTask testerOL_AR {
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          sharedLock.acquire();
          checkID = &uThisTask();
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          sharedLock.acquire();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          sharedLock.release();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          sharedLock.release();
          uYield(2);
      } // for
    }
};

uTask testerOL_TAR {
    void main() {
      for ( int i = 0; i < 100; i += 1 ) {
          while ( ! sharedLock.tryacquire() ) uYield();
          checkID = &uThisTask();
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          if ( ! sharedLock.tryacquire() )  uAbort( "interference" );
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          sharedLock.release();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          uYield();
          if ( checkID != &uThisTask() ) uAbort( "interference" );
          sharedLock.release();
          uYield(2);
      } // for
    }
};

class monitor {
    uCondLock cond1, cond2;
    uOwnerLock lock;
    int cnt;
  public:
    monitor() { cnt = 0; }
    void mS2W1() {
      lock.acquire();
      lock.acquire();
      lock.acquire();
      if ( ! cond2.empty() ) {
//        uCerr << "signal2" << endl;
          cond2.signal();
      } else {
//        uCerr << "wait1" << endl;
          cond1.wait( lock );
      }
      lock.release();
      lock.release();
      lock.release();
    }
    void mLS1W2() {
      lock.acquire();
      if ( ! cond1.empty() ) {
//        uCerr << "signal1" << endl;
          cond1.signal();
      } else {
//        uCerr << "wait2" << endl;
          cond2.wait( lock );
      }
      lock.release();
    }
    void mLB() {
      lock.acquire();
      lock.acquire();
      lock.acquire();
      cond1.broadcast();
      lock.release();
      lock.release();
      lock.release();
    }
    void mLWSem() {
      lock.acquire();
      lock.acquire();
      cnt += 1;
      if ( cnt == 3 ) start.V();
      cond1.wait( lock );
      cnt -= 1;
      lock.release();
      lock.release();
    }
    void mLW() {
      lock.acquire();
      lock.acquire();
      cond1.wait( lock );
      lock.release();
      lock.release();
    }
    void mS() {
      cond1.signal();
    }
    void mB() {
      cond1.broadcast();
    }
};

uTask testerCL_S2W1 {
    monitor &m;
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          m.mS2W1();
          uYield(2);
      } // for
    }
  public:
    testerCL_S2W1( monitor &m ) : m(m) {}
};

uTask testerCL_S1W2 {
    monitor &m;
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          m.mLS1W2();
          uYield(2);
      } // for
    }
  public:
    testerCL_S1W2( monitor &m ) : m(m) {}
};

uTask testerCL_LB {
    monitor &m;
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          start.P();
          m.mLB();
          uYield(2);
      } // for
    }
  public:
    testerCL_LB( monitor &m ) : m(m) {}
};

uTask testerCL_LWSem {
    monitor &m;
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          m.mLWSem();
          uYield(2);
      } // for
    }
  public:
    testerCL_LWSem( monitor &m ) : m(m) {}
};

uTask testerCL_LW {
    monitor &m;
    void main() {
      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          m.mLW();
          uYield(2);
      } // for
    }
  public:
    testerCL_LW( monitor &m ) : m(m) {}
};

uTask testerCL_S {
    monitor &m;
    void main() {
      for ( ;; ) {
          uAccept( ~testerCL_S ) {              // poll for destructor call
            break;
          } uElse;
          m.mS();
          uYield( 2 );
      } // for
    }
  public:
    testerCL_S( monitor &m ) : m(m) {}
};

uTask testerCL_B {
    monitor &m;
    void main() {
      for ( ;; ) {
          uAccept( ~testerCL_B ) {              // poll for destructor call
            break;
          } uElse;
          m.mB();
          uYield( rand() % 5 );
      } // for
    }
  public:
    testerCL_B( monitor &m ) : m(m) {}
};

void uMain::main() {
    uProcessor p;
#if 1
    {                                     // test uOwnerLock
      testerOL_AR t1[2] __attribute__ (( unused ));
      testerOL_TAR t2[2] __attribute__ (( unused ));

      for ( int i = 0; i < NoOfTimes; i += 1 ) {
          sharedLock.acquire();
          uYield();
          sharedLock.release();
          uYield(2);
      } // for
    }
    uCout << "completion uOwnerLock test" << endl;
#endif
    {                                     // test uCondLock
      monitor m;
#if 1
      {                                   // signal/wait
          testerCL_S2W1 t1( m );
          testerCL_S1W2 t2( m );
      }
      uCout << "completion uCondLock test: signal/wait, locked signal" << endl;
#endif
#if 1
      {                                   // signal/wait
          const int N = 5;
          testerCL_S t1( m );
          testerCL_LW *ti[N];
          for ( int i = 0; i < N; i += 1 ) {
            ti[i] = new testerCL_LW(m);
          } // for
          for ( int i = 0; i < N; i += 1 ) {
            delete ti[i];
          } // for
      }
      uCout << "completion uCondLock test: signal/wait, unlocked signal" << endl;
#endif
#if 1
      {                                   // broadcast/wait
          const int N = 3;
          testerCL_LB t1( m );
          testerCL_LWSem *ti[N];
          for ( int i = 0; i < N; i += 1 ) {
            ti[i] = new testerCL_LWSem(m);
          } // for
          for ( int i = 0; i < N; i += 1 ) {
            delete ti[i];
          } // for
      }
      uCout << "completion uCondLock test: broadcast/wait, locked broadcast" << endl;
#endif
#if 1
      {                                   // broadcast/wait
          const int N = 5;
          testerCL_B t1( m );
          testerCL_LW *ti[N];
          for ( int i = 0; i < N; i += 1 ) {
            ti[i] = new testerCL_LW(m);
          } // for
          for ( int i = 0; i < N; i += 1 ) {
            delete ti[i];
          } // for
      }
      uCout << "completion uCondLock test: broadcast/wait, unlocked broadcast" << endl;
#endif
    }
}


// Local Variables: //
// compile-command: "u++ -g Locks.cc" //
// End: //

Generated by  Doxygen 1.6.0   Back to index