Deadlocks resources -- can be both hardware devices and software (table entries or records in a database) processes need exclusive access to most resources preemptible -- can be taken away and given back later. e.g. swap in and out of memory, usually not involved in deadlocks non-preemptible -- process must keep resource until done with it, e.g. printer, tape drive deadlock definition set of processes, each waiting (blocked) for an event, e.g. resource release, only another in the set can cause necessary conditions for there to be a deadlock each resource is used exclusively by one process at a time process holding resources already allocated to them can request other resources while holding those already granted resources cannot be taken away (preempted) from a process; the process must release the resources when done with them a circular chain or cycle of processes, each holding a resource and waiting for a resource it has requested that is held by next process in the cycle resource allocation graphs, Fig 6-1 processes are circles, resources are squares, dots inside of a square mean multiple instances of that resource type arrowed arc from process to resource means a request blocking process arrowed arc from resource to process means an allocation deadlock ==> cycle in graph; cycle in graph only ==> deadlock if there is only one instance of each resource type dealing with deadlocks ostrich algorithm -- if deadlocks don't occur very often, what me worry? detect if system is currently deadlocked and if so then recover from it one resource of each type: deadlocked if and only if graph contains a cycle, e.g. Fig 6-3 use a graph cycle detection algorithm multiple resource instances of each type, Fig 6-4 n processes, P1, P2, ..., Pn m resource types, with Ej instances of each, j = 1, 2, ..., m E = existing resource vector A = available resource vector, there are Aj unallocated of type j C = current allocation matrix, process Pi has Cij of resource type j R = current request matrix, what processes are asking for now, Pi has requested Rij of resource type j (not yet allocated) for each j = 1, 2, ..., m, Ej = Aj + sum i from 1 to n Cij all processes are initially unmarked while("markable" processes exist) { for an unmarked process such that its row of R is <= A (component-wise) add its row of C to A (pretend to allocate its request and run it to to completion) mark the process } if there are unmarked processes, they are deadlocked example in Fig 6-5 recovery, from among deadlocked processes: suspend process, temporarily reallocate its resources (preempt) may or may not be possible, depending on resource type, e.g. printer, tape drive roll back process to earlier checkpoint and take some resources away kill process, i.e. roll back to its beginning, and reclaim resources may have to undo some earlier updates made by the process avoid deadlock by careful resource allocation processes may not ask for all they need all at once but may ask for a resource, get it, and then later ask for something else suppose we do know, though, how much maximum of each resource type that each process will ever ask for safe and unsafe states is there a serial order processes can finish if they all make now their maximum demands? if yes, current state is safe, else unsafe always stay in a safe state and never grant a request unless it leaves you in a safe state (leave the process blocked if granting request would lead to an unsafe state) E = existing resource vector A = available resource vector C = current allocation matrix R = future request matrix, still needed eventually (max demand) P = possessed vector = E - A assume processes ask for at once now all resources they will ever need while("markable" processes exist) { for an unmarked process such that its row of R is <= A add its row of C to A (pretend to allocate its max demand and run to completion) mark the process } if there are unmarked processes, state is not safe single instance of each resource example, Fig 6-7,8,9 (Fig 6-8 does not match text, and needs to be changed to be Fig 6-7 with process A allocated one more unit) multiple instances of each resource example, Fig 6-10 order that processes are chosen for marking does not matter: if some order leads to being able to choose no more processes then any order would also lead to being able to choose no more processes (no need to backtrack in the algorithm) problems with banker's algorithm you may not know all process max demands in advance existing resources may break, making a safe state immediately unsafe new processes may join system starvation of processes making requests that cannot be safely granted prevent a priori let resources be used simultaneously (but can't always) e.g. spool printer output rather than actually allocate printer require a process to ask in advance for everything it will ever need process may not know everything it will ever need when it starts may end up allocating resources that sit idle for long periods or, require a process to release all it holds if it ever needs to ask for something new (and ask for old+new) let resources be taken away (but can't always) use a global numbering of resource types and require processes to request resources in this order, Fig 6-11 can never have a cycle may result in some inefficiencies, i.e. resources being held but not being used can relax this to: a process cannot request a resource numbered lower that what is already currently has