Examining uC++
by Peter A. Buhr and Richard C. Bilson


Listing One

_Coroutine C {
  void main() { // distinguished member / executes on coroutine's stack
    ...suspend()... // restart last resume
  }
public:
  void m1(...) {... resume();...} // restart last suspend
  void m2(...) {... resume();...} // restart last suspend
};


Listing Two

_Coroutine Phone {
public:
  enum status { MORE, GOOD, BAD };
private:
  char ch;
  status stat;
  void main() {
    int i;
    stat = MORE; // continue passing characters
    if ( ch == '(') { // optional area code ?
      for ( i = 0; i < 3; i += 1 ) {
        suspend();
        if ( ! isdigit(ch) ) { stat = BAD; return; }
      }
        suspend();
        if ( ch != ')') { stat = BAD; return; }
          suspend();
      }
      for ( i = 0; i < 3; i += 1 ) { // region code ?
         if ( ! isdigit(ch) ) { stat = BAD; return; }
           suspend();
      }
      if ( ch != '-') { stat = BAD; return; } // separator ?
      for ( i = 0; i < 4; i += 1 ) { // local code ?
        suspend();
        if ( ! isdigit(ch) ) { stat = BAD; return; }
      }
      stat = GOOD;
  }
public:
  status next( char c ) { // pass one character at a time to FSM
    ch = c;
    resume(); // activate coroutine
    return stat;
  }
};


Listing Three

_Mutex class M { // default MES for public member routines
  // SHARED DATA ACCESSED BY MULTIPLE THREADS
  uCondition c1, c2[10], *c3 = new uCondition; //different condition variables
  // default for private/protected is no MES
  void m1(...) {... /* MES statements */...} // no MES
  _Mutex void m2(...) {... /* MES statements */...}; // MES
public:
  void m3(...) {.../* MES statements */...} // MES
  _Nomutex void m4(...) {...} // no MES
  ... // destructor is ALWAYS mutex
};


Listing Four

(a)
_Mutex class DatingService {
    uCondition Girls[20], Boys[20];
    int GirlPhoneNo, BoyPhoneNo;
  public:
    int Girl( int PhoneNo, int code ) {
        if ( Boys[code].empty() ) {
             Girls[code].wait();
             GirlPhoneNo = PhoneNo;
    } else {
             GirlPhoneNo = PhoneNo;
             Boys[code].signalBlock();
    }
    return BoyPhoneNo;
  }
  int Boy( int PhoneNo, int code ) {
    if ( Girls[code].empty() ) {
         Boys[code].wait();
         BoyPhoneNo = PhoneNo;
    } else {
         BoyPhoneNo = PhoneNo;
         Girls[code].signalBlock();
    }
    return GirlPhoneNo;
  }
};

(b)
_Mutex class ReadersWriter {
    int rcnt, wcnt;
public:
    void ReadersWriter() {
        rcnt = wcnt = 0;
    }
    void EndRead() {
        rcnt -= 1;
    }
    void EndWrite() {
        wcnt -= 1;
    }
    void StartRead() {
        if ( wcnt == 1 ) _Accept( EndWrite );
        rcnt += 1;
    }
    void StartWrite() {
        if ( wcnt == 1 ) _Accept( EndWrite );
        else while ( rcnt > 0 )
            _Accept( EndRead );
        wcnt += 1;
    }
};


Listing Five

_Mutex _Coroutine CM { // default MES for public member routines
   uCondition c1,c2[10],*c3 = new uCondition; // different condition variables
   void m1(...) {.../* MES statements */ ...} // no MES
   _Mutex void m2(...) { .../* MES statements */ ...}; // MES
   void main() {...} // distinguished member / has its own stack
public:
   void m3(...) { ...resume()/* MES statements */ ...} // MES
   _Nomutex void m4(...) { ...resume(); ...} // no MES
   ...// destructor is ALWAYS mutex
};


Listing Six

_Task T { // default MES for public member routines
   uCondition c1,c2[10],*c3 = new uCondition; // different condition variables
   void m1( ... ) {.../* MES statements */ ... } // no MES
   _Mutex void m2(...) {.../* MES statements */...}; // MES
   void main() {...} // distinguished member/has own stack/thread starts here
public:
   void m3(...) {.../* MES statements */ ...} // MES
   _Nomutex void m4(...) {...} // no MES
   ...// destructor is ALWAYS mutex
};


Listing Seven

(a)
const int rows = 10, cols = 10;
int M[rows][cols], ST[rows];

_Task Adder { // add specific row
    static int row; // sequential access
    int myrow, c;
    void main() {
        ST[myrow] = 0; // subtotal location
        for ( c = 0; c < cols; c += 1 )
             ST[myrow] += M[myrow][c];
    }
  public:
    Adder() { myrow = row++; } // choose row
};
int Adder::row = 0;
void uMain::main() {
    // read matrix
    {
        Adder adders[rows]; // create threads
    } // wait for threads to terminate
    int total = 0; // sum subtotals
    for ( int r = 0; r < rows; r += 1 )
         total += ST[r];
    cout << total << endl;
}

(b)
_Task Server {
    uCondition delay;
    void main() {
        for ( ;; ) { // for each client request
            _Accept( ~Server ) { // terminate ?
              break;
            // service each kind of client request
            } else _Accept( workReq1 ) {
              ...
              delay.signalBlock(); // restart client
              ...
            } else _Accept( workReq2 ) {
              ...
            }
        }
        // shut down
  }
public:
  void workReq1( Req1_t req ) {
       ...delay.wait();...// service not immediate?
       // otherwise service request
    }
    void workReq2( Req2_t req ) { ... }
    ...
};


Listing Eight

(a)
_Throw [ throwable-exception [ _At coroutine/task-id ] ] ; // termination
_Resume [ resumable-exception [ _At coroutine/task-id ] ] ; // resumption

(b)
_Enable <E1><E2>... {
    // exceptions E1, E2, ... delivered
}
_Disable <E1><E2>... {
    // exceptions E1, E2, ... not delivered
}


