Lecture 12 - More on Dining Philosophers
Help for Assignment 3
The idea for assignment 3 is via:
for(int i = 0; i < 5; i++)
{
create(fun, &i); // Problem: giving address of i is wrong here.
}
Devices/IO
Remember dev/fd0
? It is a device special file:
We divide into two categories: major and minor
Other categories:
- block: Block oriented addresses (ex: disk)
- character: byte oriented (often not Random Access, more stream oriented) (ex: terminal).
But these are just rough characterizations. What type of device would a printer be? A network?
There are two types of devices:
- pre-emptable: can take without harm
- non-preemptable: can't take without some harm
The non-preemptable resources are the interesting one since we have to consider synchronization here. To use it:
- Request
- Wait for it to be granted
- Use it
- Release it
We can model this with a Resource Allocation Graph.
To handle this, let's look at this example:
In this case we have a problem; deadlock! How do we generalized the criteria for this deadlock to know if it's about to happen?
To have deadlock, you must have all:
- Mutual-Exclusion
- Holds and Waits
- No-preemption
- You must have circular wait (like shown in the figure)
Some approaches to not deadlock:
- Don't bother. If its happens rarely and the "badness" isn't bad, then don't bother.
- Detect and Recover.
- If you have tasks that can restart, why not restart them.
- Make it impossible
- Let's get rid of mutual-exclusion! ... uh wait no that's stupid.
- Let's not let processes hold and wait! Require processes to ask for all their resources at once.
- The problem is processes don't know how much they need.
- We can modify to instead ask only when you are ready to drop everything and use it. This isn't super convenient.
- Having preemption is not going to work.
- Remove circular waits (don't let them be possible).
Let's tackle not letting circular waits happen. If we order the resources, then there won't be any cycle. What is this order?
- Use higher numbers for the higher use/lower time items
- Use lower numbers for the lower use/longer time items
We can modify that requests to lower resources require releasing everything above in numbers.
... or, Don't Deadlock
Let's look at Dijkstra's Banking Algorithm, which is a way to not allow deadlocks from happening in the first place. This approach only grants resources when it is safe to do so.
Model Resources like a line of credit.
Process declare max need in advance.
Test states for safety.
test:
do{
pick a satisfiable process
pretend we lit it finish
release resources
} until (all finish or stuck)
if all finish
safe
else
unsafe
The only problem is that there is only one type of resource. How about having different types of resources?