CS452 - Real-Time Programming - Winter 2015

Lecture 27 - Pathologies II

Public Service Annoucements

  1. Exam: 16.00 14 April to 18.30 15 April
  2. Milestone 2: 25 March, 2015
  3. Two more trains in the lab yesterday; three more almost ready.
  4. Looks like the problem was a broken line driver in the train controller. Testing chip replacement, today or tomorrow.
  5. Final demos. 6,7 April, 2015.
  6. Be able to do whatever causes trouble from the keyboard


1. Deadlock

2. Livelock (Deadly Embrace)

Three cases:

  1. Really a deadlock.
  2. True livelock.
  3. Really a critical race.
In one sense these are really all critical races. Why? Because in each case there is an order of execution in which everything is fine. In fact, most of the deadlocks we saw could also be called critical races.

3. Critical Races


  1. Two tasks, A & B, at the same priority.
  2. You make an insignificant change to A (or B) and it stops working.
  3. You add debugging statements to A and it works again.
  4. You remove the debugging statements and it stops working once again.
  5. You realize that when A runs more slowly than B, A works.
  6. You lower the priority of A, and A works without debugging code. Sounds good.
  7. But C, which is at the new priority of A, stops working properly with D.
  8. You put debugging statements into C and it starts working again.
  9. ...
  10. If you can remember what the original priorities were you put them back and put the debugging statements back in.
  11. If you can't remember you experiment with priorities and debugging statements until you find a combination that works.

What might be happening?

  1. Originally B was reserving a piece of track before A could ask for it.
  2. After you changed A it got the track before B, which didn't work.
  3. Debugging statements or change of priorities slowed down A restoring the order that worked.
  4. But changing priorities slowed down C, so that D got something before C.
  5. And so on.

Attempting to resolve a priority problem with tweaks often leads to a cascade of problems.


The order in which parts of a computation occur affects the result of the computation.

Critical races, like Livelock can be


  1. Small changes in priorities change execution unpredictably, and drastically.
  2. Debugging output changes execution drastically.
  3. Changes in train speeds change execution drastically.

`Drastically' usually means chaos in both senses of the term

  1. Sense one: a small change in the initial conditions produces an exponentially growing divergence in the execution.
  2. Sense two: exercise for the reader.


  1. Explicit synchronization
  2. Gating is a technique of global synchronization


  1. Gossip
  2. Use bits
  3. Progress counter
  4. Idle task

4. Performance

Changes in performance of one task with respect to another often give rise to critical races

The hardest problem to solve

In practice, how do you know you have performance problems? Here are a few sources of performance problems


The hardest thing to get right

Problems with priority

  1. Priority inversion
  2. One resource, many clients
  3. Tasks try to do too much


  1. Too many tasks
  2. Layered abstractions are costly

Limited resources

  1. Bandwidth to the train controller
  2. Bandwidth to the terminal
  3. Any server with clients, workers, notifiers or couriers in its sendQ


  1. Turn on optimization, but be careful
  2. Turn on caches

Size & align calibration tables by size & alignment of cache lines

I think that this is stretching it.

Symptoms of performance problems

Return to: