CS452 - Real-Time Programming - Winter 2016

Lecture 29 - Pathologies III.

Public Service Annoucements

  1. Train Control II demo on Wednesday, 11 July.
  2. Lecture menu:
  3. The exam has three start times. The end times are 26.5 hours after the start time.
    Answers to questions asked from 20.30, 4 August to 22.00, 4 August will be answered on the newsgroup, whether they arrive by e-mail or on the newsgroup.


1. Deadlock

One or more tasks will never run again.

2. Livelock (Deadly Embrace)


Two or more tasks are READY. For each task, the state of other tasks prevents progress being made regardless of which task is ACTIVE.

3. Critical Races

Symptoms of a critical race

In all these cases changing the order of execution either creates or reveals a bug. It is usually straightforward to remove the bug; what's hard is finding it.

A common bug that shares some symptoms is something uninitialed. You can have success run after run, and then suddenly it doesn't run: the program runs when the group before you has left the thing in an initialized state, and doesn't run when it hasn't. I do not consider this to be a critical race because there is no change in execution order.


  1. Sensitive areas in the code: usually two instructions that should be atomic. Most should be fixed by reprogramming.
  2. Execution order that is assumed to be invariant, but isn't, such as querying the name server without thinking that the task about which you are querying might not yet have registered.
  3. Order of actions on the track, that change as the performance of trains changes. One example would be switching a turn-out just before or just after the safety threshold for an oncoming train. This example demonstrates how touchy timing can be in a real-time system. Another might be assuming that one train's sensor report will come before or after, but not simultaneous to another train's report.
  4. Changing task priorities to improve performanance.


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

4. Performance

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

The hardest problem to solve

Symptoms of performance problems

In general it's hard to figure out when a problem is caused by bad performance and when it's possible to remedy performance. (Sometimes there's no solution but buying a more capable processor or more memory.) Here are some symptoms I have seen more than once.

  1. Percentage of time used by the idle task falling significantly below 90%.
  2. Buffers filling up. They are almost always empty.
  3. Negative, zero or close to zero delay arguments.
  4. Unintended close calls on the track.
  5. Stale sensor data.
  6. Low priority tasks falling behind.
Most often performance problems build gradually during execution. The symptoms above often indicate that the system will fail in the immediate future.


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

Layered abstraction are costly

e.g. Notifier -> SerialServer -> InputAccumulater -> Parser -> TrackServer


  1. Too much terminal output interferes with train controller communication
  2. Requests to poll the sensors get backed up in the serial server, or whoever provides output buffering.


  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.

Return to: