CS452 - Real-Time Programming - Spring 2010

Lecture 20 - Task Structure

Public Interest Announcements

  1. Halt: read 0x80930008
    Standby: read 0x8093000c

Anthropomorphic Programming

We all, most programmers included, have effective intuitions about human relations

Tasks are independent entities


Servers and Attendant Tasks

1. Proprietor with a Notifier

2. Using a Courier

3. Using a Warehouse

Add a warehouse between the courier and the notifier.

Notifier Code

Warehouse Code

Courier Code

Proprietor Code

Note

This structure clears up problems when the notifier runs too fast for the server.

Two issues:

  1. Handles bottlenecks of all sizes.

    Define `bottleneck'.

  2. Server could be buffered on the other side

    Called a secretary

4. The Secretary

Proprietor

Secretary

FOREVER {
    Receive( );
    switch ( )
    case courier && XMIT { (Reply, Reply) or enqueue }
    case courier && RCV { enqueue or (Reply, Reply) }
    case client && XMIT { (Reply, Reply) or enqueue }
    case client && RCV { enqueue or (Reply, Reply) }

Courier

FOREVER {
    Send( secretary )
    Send( prop )
}

5. Administrator, Worker

Generalization of proprietor

Administrator maintains an array of records

Administrator works as he can on any one of the tasks.

Real administrators manage workers

Worker code

  FOREVER {
    Send( administrator, workResult, workOrder );
    doWork( workOrder );
  }

Administrator code

Administrator( ) {
  Initialize( );
  for ( i = 0; i < NUM_WORKERS; i++ ) worker[i] = Create( workerCode );
  for ( i = 0; i < NUM_WORKERS; i++ ) Send( worker[i], ... , ... );
    // Initialize orderQueue, workerQueue
    // RegisterAs
  FOREVER {
    error = Receive( requester, request );
    switch( request.type ) {
    case CLIENT: // enqueue w/o or Reply w/o
       workOrder = {client = requester, request};
       if( worker = dequeue( workerQueue ) && resources( ) ) Reply( worker, workOrder );
       else enqueue( orderQueue, workOrder );
       break;
    case NOTIFIER: // or courier: Reply not, store, Reply w/o's
       // Acquire data
       // Update state
       // for each queued client
       //    if complete data available && worker available
       //       workorder = {client, request}
       //       Reply( worker, workOrder );
       //    else enqueue client 
       break;
    case WORKER: // Reply result, enqueue w'r or Reply w/o
      Reply( request.client, request.result );
      if( ( workOrder = deQueue( orderQueue) ) ) {
        workOrder = {workOrder.client, workOrder.request};
        Reply( requester, workOrder );
      } else enqueue( workerQueue, requester );
    }
  }
}

Alternative Administrator Code

Administrator( ) {
  Initialize( );
  for ( i = 0; i < NUM_WORKERS; i++ ) worker[i] = Create( workerCode );
  for ( i = 0; i < NUM_WORKERS; i++ ) Send( worker[i], ... , ... );
    // Initialize orderQueue, workerQueue
    // RegisterAs
  FOREVER {
    error = Receive( requester, request );
    switch( request.type ) {
    case CLIENT:
       enqueue ( workfifo, workorder );
       while ( !empty( workfifo ) )
          if ( complete ( workorder, data ) && workerTid = next( workerQ ) ) { 
             Reply( client, workerTid, ... );
             Reply( worker, workorder );
          }
       break;
    case NOTIFIER:
       // Acquire data
       // Update state
       // for each queued client
       //    if complete data available && worker available
       //       workorder = {client, request}
       //       Reply( worker, workOrder );
       //    else requeue client 
       break;
    case WORKER:
      if( ( workOrder = deQueue( orderQueue) ) ) {
        workOrder = {workOrder.client, workOrder.request};
        Reply( requester, workOrder );
      } else enqueue( workerQueue, requester );
    }
  }
}

8. The Detective

Simple Events

The notifier is a task that waits on events.

You could call a notifier a detective,

Complex Events

In an application there is likely to be lots of waiting on combinations of events.

We use the detective to discover that a complex event has occurred.

Conjunction

Code could be

FOREVER {
  Send( part1 );
  Send( part2 );
  ...
  Send( master );
}

Disjunction

Code above doesn't work! Try instead

// InitializeDB;
// Create workers and synchronize;
// Synchronize with client;
FOREVER {
  Receive( *requester, request );
  if ( request.type == CLIENT ) {
    parsedRequest = parse( request );
    if ( happened( parsedRequest, DB ) ) Reply( requester );
    else enqueue( parsedRequest );
  }
  else if (request.type == WORKER ) {
    updateDB ( request );
    Reply( requester );
    foreach ( queuedRequest )
      if ( happened( parsedRequest, DB ) ) {
        dequeue( parsedRequest );
        Reply( client );
      }
  }
}

FOREVER {
  Receive
  switch
  case CLIENT: Reply c't or hold
  case WORKER: Reply w'r, Reply held
}

This is the code of a detective.

Not

We can say that an event has not happened yet.

Only at the end of the universe can we say that an event simply has not happened.

Time-outs are needed for NOT

Who is the client of the detective

  1. Initiator of a normal action

Housekeeper of the system who will clean up pathologies (Idletask?))


Return to: