Deadlock
A deadlock is the permanent blocking of a set of processes that either compete for system resources or communicate with each other.
Why does it happen?
Every process in the set is waiting on a resource another member of the set holds. No one can release, so no one can proceed. In ECE459 terms: the program stops making progress without crashing.
I first learned about this when preparing for my AMD interview, as well as CS348. Taught in detail through SE350.
Coffman conditions — all four must hold simultaneously for a deadlock. Break any one and deadlock cannot occur:
- Mutual exclusion: a resource belongs to at most one process at a time
- Hold-and-wait: a process holding resources can request more and be forced to wait
- No preemption: a resource cannot be taken; only the holder releases it
- Circular wait: a cycle in the resource allocation graph

Figure 6.5d has the same topology as 6.5c but there is no deadlock, because multiple units of each resource are available.
Minimal deadlock
In (c) above, P1 holds Rb and wants Ra; P2 holds Ra and wants Rb. Neither process can continue.
Dealing with Deadlocks
Three approaches:

Practical rules
- Avoid nested locks, the main cause of deadlock, don’t take a second lock while holding the first if you can help it
- Avoid unnecessary locks, lock only what actually needs protection
- Enforce a global lock order so cycles can’t form
Rust’s Mutex auto-releases on drop but does not prevent deadlock: thread 1 acquiring A then B while thread 2 acquires B then A still deadlocks.
Avoiding deadlock with multiple locks
Two options from ECE459 L11:
- Consistent ordering: assign each resource an integer
f(R). A process holdingR_imay only requestR_jiff(R_j) > f(R_i). If it needs one with a smaller value, it releases everything at or above that value first. Makes circular wait impossible - Trylock: attempt the second lock; on failure release the first and retry. Breaks hold-and-wait
Bank transfer deadlock
Two concurrent transfers can deadlock if one locks sender-then-receiver while the other locks receiver-then-sender. Fix by ordering on the immutable account number (kept outside the mutex), or use trylock.