CS452 - Real-Time Programming - Winter 2016

Lecture 21 - Anthropomorphic Programming

Public Service Annoucements

  1. Train Control I demo on Wednesday, 11 March.
  2. Choosing a time for the exam: start with 12.30, 19 April.
  3. PDF on Acceleration Mathematics.

Anthropomorphic Programming

We all, even most programmers (!), have effective intuitions about human relations

Tasks are independent entities

Servers and Attendant Tasks

Why do servers need attendant tasks?

1. Proprietor with a Notifier

Proprietor `owns' a service, which usually means a resource.


  1. Notifier is usually of higher priority than server
  2. We assume that interrupts get turned on and/or off in the kernel.
  3. The server buffers both clients and data from the notifier. In this implementation client and data buffering are duals of each other. Our server code should

2. Using a Courier

We can handle two interrupts coming very close together using a courier. Simplest is best, so we shouldn't go beyond a courier unless we expect more than two.

Transmit Notifier Code

Transmit Courier Code

Transmit Proprietor Code


This gets you through a bottleneck where at most than two events come too fast.

Remember that all the calls provide error returns. You can/should use them for error recovery

Another possible arrangement for task creation

Another possible arrangement for initialization

Distributed gating

I am showing you collections of tasks implemented together because sets of related tasks is a level of organization above the individual task.

E.g., the decision to add a courier requires revision of code within the group, but not outside it.

3. The Warehouse

Add a warehouse between the courier and the notifier.


The initialization given for the courier, above, generalizes to include the warehouse, essentially without change.


The notifier is now talking directly to a server and has the shape given above for the proprietor. The warehouse cannot talk directly to the proprietor because both are servers.


This structure clears up most problems when a burst of requests to the server would leave the notifier waiting in a long sendQ.


  1. Handles bottlenecks of all sizes. Give a precise and quantitative definition of `bottleneck'.

What this amounts to is that a server should be lean and hungry

4. Secretary, Receptionist

The warehouse guards the notifier from the effect of multiple clients on the server. Another method of guarding the notifier is to guard the proprietor so that its sendQ is always empty. The secretary/receptionist does so.

The secretary receives requests from many clients and forwards them one at a time to the proprietor. Because the secretary Receives it cannot Send. It communicates with the Proprietor using a Courier.


  1. When all the clients have been given service
  2. The Courier is almost always Reply-blocked. If it spends a significant amount of time Receive-blocked the system is overloaded.
  3. If there is a temporary overload of Client requests, the Courier may sit for a while in the Secretary's SendQ while the Proprietor continues to interact with the Notifier.
  4. If there is a permanent overload of requests you are in trouble.

5. Administrator, Worker

Administrator is a proprietor who does no work but only assigns work to others

Where do the workers come from?

Most workers prefer employee status to consultant status.

Worker code

	Send( administrator, nil, workOrder );
    	  Send( administrator, workResult, workOrder );
          workResult = doWork( workOrder );

doWork might require further sends to servers or warehouses, which is harmless in this context.

What kind of work might a worker do?

Administrator code

	Administrator( ) {
  	  for ( i = 0; i < NUM_WORKERS; i++ )
		  worker[i] = Create( mypriority - 1, workerCode );
  	  FOREVER {
    	    Receive( requester, request );
    	    switch( request.type ) {
    	    case CLIENT:
      	      enqueue( orderQ, {order = {client, request}} );
      	      if ( !empty( employeeQ ) )
		  Reply( dequeue( employeeQ ) ), dequeue( orderQ ) ); 
    	    case WORKER:
      	      enqueue( emploeeQ, requester);
              if ( !empty( orderQ ) )
		  Reply( dequeue( employeeQ ), { dequeue( orderQ ) );
      	      if ( request != nil )
		  Reply( request.client, request.request );

Note: Tid of the client is usually included in the workorder to the administrator does not have to maintain and search a list of jobs being done. (Administrators are by nature lazy!)

Alternative Worker/Administrator Model

  1. As above, Administrator includes Tid of the client in the order.
  2. Worker replies directly to client with result and to administrator with request for another order to process.


  1. The administrator can add a little more value.

Return to: