4. Necessary Conditions for Deadlock
Mutual exclusion
Resources cannot be shared
e.g., buffers, locks
Hold and wait (subset property)
A thread must hold a subset of its resource needs
And, the thread is waiting for more resources
No preemption
Resources cannot be taken away
Circular wait
A needs a resource that B has
B has a resource that A has
6. Cycle Without Deadlock
P => R: request edge
R => P: assignment edge
Why is there no deadlock
here?
7. Graph Reduction
A graph can be reduced by a thread if all of that
thread’s requests can be granted
Eventually, all resources by the reduced thread will be freed
Miscellaneous theorems (Holt, Havender):
There are no deadlocked threads iff the graph is completely
reducible
The order of reductions is irrelevant
(Detail: resources with multiple units)
9. Approaches to Deadlock
1. Avoid threads
2. Deadlock prevention
Break up one of the four necessary conditions
1. Deadlock avoidance
Stay live even in the presence of the four conditions
1. Detect and recover
10. Approach #1: Avoid Threads
Brain dead solution: avoid deadlock by avoiding
threads
Example: GUI frameworks
Typically use a single event-dispatch thread
Operating System
GUI Framework
Application
mouse
click
change
background
color
11. Approach #2: Prevention
Can we eliminate:
Mutual exclusion?
Hold and wait (subset property)?
No Preemption?
Circular waiting?
12. Lock Ordering
We can avoid circular waiting by acquiring resources
in a fixed order
Example: Linux rename operation
Each open file has a semaphore
Both semaphores must be held during file operations
Linux always uses the same order for down operations
Semaphore at the lowest memory address goes first
13. Rename Example
Process 1: rename (“foo.txt”,”bar.txt”);
Process 2: rename (“bar.txt”,”foo.txt”);
down()
foo semaphore
down()
bar semaphore
up()
bar semaphore
up()
foo semaphore
down()
foo semaphore
down()
bar semaphore
up()
bar semaphore
up()
foo semaphore
14. Approach #3: Avoidance
Intuition: the four
conditions do not always
lead to deadlock
“necessary but not sufficient”
We can stay live if we know
the resource needs of the
processes
15. Bankers Algorithm Overview
Basic idea: ensure that we always have an “escape
route”
The resource graph is reducible
This can be enforced with the bankers algorithm:
When a request is made
Pretend you granted it
Pretend all other legal requests were made
Can the graph be reduced?
If so, allocate the requested resource
If not, block the thread
16. Deadlock Avoidance in Practice
Static provisioning
Ensure that each active process/thread can acquire some
minimum set of resources
Use admission control to maintain this invariant
This is closely related to the idea of thrashing
Each thread needs some minimum amount of resources to run
efficiently
17. Approach #4: Detection and Recovery
Not commonly used
Detection is expensive
Recovery is tricky
Possible exception: databases
18. Deadlock Detection
Detection algorithm (sketch)
Keep track of who is waiting for resources
Keep track of who holds resources
Assume that all runnable processes release all their resources
Does this unblock a waiting process?
If yes, release that process’s resources
If processes are still blocked, we are deadlocked
Editor's Notes
TODO: print handouts for AspectRatio
Buffer pool:
Buffers cannot be shared
Each thread can allocate some (but not all) of its resource
No way for resources to be taken away
Thread A needs the buffers of thread B (and vice versa)