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

EHM4.cc

//                              -*- Mode: C++ -*- 
// 
// uC++ Version 5.0.1, Copyright (C) Roy Krischer 2002
// 
// EHM4.cc -- 
// 
// Author           : Roy Krischer
// Created On       : Tue Mar 26 23:01:30 2002
// Last Modified By : Peter A. Buhr
// Last Modified On : Fri Aug 27 08:13:25 2004
// Update Count     : 121
// 

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


#define MAX 1000
#define NTASK 5
#define ROUNDS 10000


uTask worker {
    int id, round;

      void main();
  public:
    worker ( int id ) : id(id), round(ROUNDS) {
            uCout << uAcquire << "task " << this << " creation" << endl << uRelease;
      } 
    ~worker() {
            uCout << uAcquire << "task " << this << " destruction" << endl << uRelease;
    }
}; // worker


uMonitor atomicCnt {
    int c;
  public:
    atomicCnt( int c = -1 ) : c(c) {}

    int inc() {
            c += 1;
            return c;
    } // inc
}; // atomicCnt


atomicCnt cnt;                                                                // atomic counter
int array[NTASK*((NTASK-1)*ROUNDS+1)] = {0};                // check for duplicate handling
int handled[NTASK] = {0};                                               // count events handled per task
uBarrier b( NTASK + 1 );                                                // control start and finish of main/worker tasks
worker *f[NTASK];                                                       // shared resource controlled by barrier


uRaiseEvent rev {
  public:
    int ticket;
    rev( const char *msg, int ticket ) : uRaiseClass(msg), ticket(ticket) {};
};
uInitEvent(rev);

class Arg {
    int &id, &round;
  public:
    Arg( int &id, int &round ) : id(id), round(round) {}
      void operator()( rev &r ) {
            handled[id] += 1;                                           // count events handled by each task
            //uCerr << uAcquire << "handler, exception id: " << e.ticket << endl << uRelease;
            uAssert( r.ticket < NTASK*((NTASK-1)*ROUNDS+1) ); // subscript error ?
            array[r.ticket] += 1;
            if ( array[r.ticket] > 1 ) uAbort( "error - same event handled twice");
            if ( round != 0 ) {                                               // only a subset of events raise more
                  round -= 1;
                  if ( round % 2 == 0 ) {                               // generate 1/2 of the events
                        for ( int i = 0; i < NTASK; i += 1 ) {    // send events to other tasks
                              if ( i != id ) {                          // except myself
                                    uRaise rev( "other", cnt.inc() ) uAt *f[i];
                              } // if
                        } // for
                  } // if
            } // if
      }
}; // Arg


void worker::main() {
      Arg arg( id, round );

    b.block();                                                                // wait for all tasks to start
      uCout << uAcquire << "task " << this << " starting" << endl << uRelease;
      uYield( NTASK );

      try <rev, arg> {
            uEnable {
                  uRaise rev( "self", cnt.inc() ) uAt *this;      // initial resume at myself
                  for ( int n = 0; n < ROUNDS / 2; n += 1 ) {     // generate other 1/2 of the events
                        uYield();                                             // allow delivery of concurrent resumes
                        for ( int i = 0; i < NTASK; i += 1 ) {    // send events to other tasks
                              if ( i != id ) {                          // except myself
                                    uRaise rev( "other", cnt.inc() ) uAt *f[i];
                              } // if
                        } // for
                  } // for
            } // uEnable
      } // try

    b.block();                                                                // wait for all tasks to finish
      uCout << uAcquire << "task " << this << " finishing" << endl << uRelease;
} // worker::main


void uMain::main () {
    uProcessor p[4];

    for ( int i = 0; i < NTASK; i += 1 ) {
            f[i] = new worker( i );
    } // for
    b.block();                                                                // wait for all tasks to start

    b.block();                                                                // wait for all tasks to finish
      int total = 0;
    for ( int i = 0; i < NTASK; i += 1 ) {
            delete f[i];
            total += handled[i];                                        // sum events handled by each task
    } // for
      uCout << uAcquire << "cnt:" << cnt.inc() << "  handled:" << total << endl << uRelease;
} // uMain::main


// Local Variables: //
// tab-width: 4 //
// End: //

Generated by  Doxygen 1.6.0   Back to index