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

AlarmClock.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Peter A. Buhr 1994
// 
// AlarmClock.cc -- 
// 
// Author           : Peter A. Buhr
// Created On       : Wed Oct 23 16:10:01 1991
// Last Modified By : Peter A. Buhr
// Last Modified On : Wed Jan 28 23:28:14 2004
// Update Count     : 82
// 

#include <uC++.h>
#include <uIOStream.h>

class Node : public uSeqable {
      Node( Node & );                                                         // no copy
      Node &operator=( Node & );                                        // no assignment
  public:
      int ticks;
      uCondition block;
      Node( int t ) { ticks = t; };
};

class OrderedList : public uSequence<Node> {
      OrderedList( OrderedList & );                               // no copy
      OrderedList &operator=( OrderedList & );              // no assignment
  public:
      OrderedList() {}
      void insert( Node *np ) {
            Node *lp;
            for ( lp = uHead();                                               // insert in ascending order by time
                   lp != 0 && lp->ticks < np->ticks;
                   lp = uSucc( lp ) );
            uSequence<Node>::uInsertBef( np, lp );
      } // OrderedList::insert
}; // OrderedList

uTask Clock;                                                                  // forward declaration

uMonitor Alarm {
      friend uTask Clock;                                                     // so Clock can call private Mutex member
      int ticks;                                                              // current time
      OrderedList TimeReq;                                              // ordered list of time requests

      uMutex void tick() {
            Node *client;

            ticks += 1;
            for ( uSeqGen<Node> gen(TimeReq); gen >> client && client->ticks <= ticks; ) {
                  uCout << uAcquire << "ticks = " << ticks << ", signalling!" << endl << uRelease;
                  TimeReq.uRemove( client );
                  uSignal client->block;
            } // for
      }; // Alarm::tick
  public:
      Alarm() {
            ticks = 0;
      } // Alarm::Alarm

      uNoMutex int time() {
            return ticks;
      } // Alarm::time

      void sleep_until( int t ) {
            Node time( t );

            TimeReq.insert( &time );
            uWait time.block;
      } // Alarm::sleep_until

      void sleep_for( int n ) {
            Node time( ticks + n );

            TimeReq.insert( &time );
            uWait time.block;
      } // Alarm::sleep_for
}; // Alarm

uTask Clock {
      Alarm &alarm;

      void main() {
            for ( ;; ) {
                  uAccept( ~Clock ) {                                         // destructor called ?
                        break;
                  } uElse {                                                   // don't block
                        uYield( 100 );                                        // should be a fixed period of time
                        alarm.tick();                                         // advance the clock
                  } // uAccept
            } // for
      } // Clock::main
  public:
      Clock(Alarm &alarm) : alarm( alarm ) {
      } // Clock::Clock
}; // Clock

uTask SampleUser {
      Alarm &alarm;

      void main() {
            int ticks;
            
            ticks = rand() % 17;      
            uCout << uAcquire << "Task " << this << " : Current Time = " << alarm.time() << ", Going to sleep for " << ticks << " ticks" << endl << uRelease;
            alarm.sleep_for( ticks );
            uCout << uAcquire << "Task " << this << " : Now awake!  Current Time = " << alarm.time() << endl << uRelease;
            
            ticks = rand() % 13 + alarm.time();      
            uCout << uAcquire << "Task " << this << " : Current Time = " << alarm.time() << ", Going to sleep until time " << ticks << endl << uRelease;
            alarm.sleep_until( ticks );
            uCout << uAcquire << "Task " << this << " : Now awake!  Current Time = " << alarm.time() << endl << uRelease;
            uCout << uAcquire << "Task " << this << " : All done, now dying" << endl << uRelease;
      }; // SampleUser::main
  public:
      SampleUser( Alarm &alarm ) : alarm( alarm ) {
      }; // SampleUser::SampleUser
}; // SampleUser

void uMain::main() {
      const int NoOfUsers = 8;
      Alarm alarm;
      Clock clock( alarm );

      SampleUser *sample_users = new SampleUser[NoOfUsers]( alarm );
      delete [] sample_users;

      uCout << uAcquire << "successful completion" << endl << uRelease;
} // uMain::main

// Local Variables: //
// tab-width: 4 //
// compile-command: "u++ AlarmClock.cc" //
// End: //

Generated by  Doxygen 1.6.0   Back to index