CS452 - Real-Time Programming - Fall 2008

Lecture 20 - The Detective


Questions & Comment

  1. projects
  2. next Monday

Server Structure

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 );
      }
  }
}

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
  2. Housekeeper of the system who will clean up pathologies (Idletask?))

Pathologies

1. Deadlock

One or more tasks will never run again. For example

  1. Task sends to itself (local: rest of system keeps running, task itself will never run)
  2. Every task does Receive( ) (global: nothing is running)
  3. Cycle of tasks sending around the cycle (local: other tasks keep running)

Kernel can detect such things

Possible send-blocking can be detected at compile time

Solutions

2. Livelock (Deadly Embrace)

Usually occurs in the context of resource contention. For example

Kernel cannot easily detect this

Possible solutions

  1. both resources in one proprietor
  2. global order on resource requests
  3. ethernet algorithm

Could consider this a form of critical race.

3. Critical Races

Theory of relativity and the event horizon

One task tests a condition

Another task tests the same condition

And the two actions are incompatible.

That is, information about the action of the first task did not spread instantaneously:

Concrete example.

Engineer sends to switchDetective

Before switchDetective does RegisterAs, a second Engineer sends to switchDetective

Each switchDetective, or its courier, does Put and Get to find out about switches.

This is only a little bad, you probably won't even notice it, except your performance will be bad.

But it can be much worse

Symptoms

  1. Small changes in priorities change execution unpredictably, and drastically.
  2. Debugging output changes execution drastically.

Solutions

  1. A protocol for using the name server
  2. At initialization it's a programming bug,

4. Performance


Return to: