CS452 - Real-Time Programming - Spring 2009
Lecture 27 - Pathologies
1. Deadlock
2. Livelock (Deadly Embrace)
3. Critical Races
Critical race
- the order in which internal variables are changed determines the
eventual state that the state machine will end up in.
- Example: A and (not A)
Non-critical race
- the order in which internal variables are changed does not alter the
eventual state
- more than one internal state variable must be changed at once,
- but no matter in what order these internal state variables change,
- the resultant state will be the same
- Example, correcting the example with flip-flops
General solution
- Set synchronization points at which state must be consistent
- Change critical races to non-critical ones
Races exist when more than one thing changes at once
- Multiple signals in logic
- Multiple threads of control in software
- locks/monitors/semaphors used to set synchronization points
It's better to design out races if you can.
A second description
Theory of relativity and the event horizon
One task tests a condition
- takes an action based on that condition
- which will remedy it
Another task tests the same condition
- takes an action to remedy the condition
And the two actions are incompatible.
That is, information about the action of the first task did not spread
instantaneously:
- that race between the information and the second task's test was won by
the test.
Concrete example.
Engineer sends to switchDetective
- gets back, 'No such task.'
- Creates a switchDetective
- starts interacting with switchDetective using the Tid returned by
Create
Before switchDetective does RegisterAs, a second Engineer sends to
switchDetective
- gets back, 'No such task.'
- Creates a switchDetective
- starts interacting with switchDetective using the Tid returned by
Create
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
- consider having two copies of a task that does track reservations.
Symptoms
- Small changes in priorities change execution unpredictably, and
drastically.
- Debugging output changes execution drastically.
- Changes in train speeds change execution drastically.
Define `drastically'.
Solutions
- A protocol for using the name server
- e.g. RegisterAs returns the Tid of an existing task
- if it's the one that is known to be bad, then do
ForceRegisterAs
- otherwise use the existing one.
- At initialization it's a programming bug,
- which can be discovered by gating
4. Performance
The hardest problem to solve
- You just don't know what is possible
- Ask a question like:
- Is my kernel code at the limit of what is possible in terms of
performance?
Priority
The hardest thing to get right
- Sizing stacks used to be harder, but now we have lots of memory
- NP-hard for the human brain
- Practical method starts with all priorities the same, then adjusts
- symptoms of good priority assignment
- The higher priority, the more likely the ready queue is to be
empty
- The shorter the run time in practice the higher the priority
Problems with priority
- Priority inversion
- One resource, many clients
- Tasks try to do too much
Congestion
- Too many tasks
- blocked tasks don't count,
- lowest priority tasks almost don't count
- Not enough tasks
- priority doesn't work any more
Layered abstraction are costly
e.g. Notifier -> SerialServer -> InputAccumulater -> Parser ->
TrackServer
Hardware
- Turn on optimization, but be careful
- There are places where you have done register allocation by
hand
- Turn on caches
- Size & align calibration tables by size & alignment of cache
lines
- Slowing and stopping
- each train has a built in velocity profile when stopping
- you can create your own velocity profile
Return to: