Critical Section: Example Problem [76]
program code: global variable x:
x=0; 0
x++; 1
printf x; 1 <=== output
PID 1 PID 2 PID 3 x:
x=0; 0
x++; 1
x=0; 0
x=0; 0
printf x; 0 <=== output
x++; 1
printf x; 1 <=== output
x++; 2
printf x; 2 <=== output
Critical Section: Attempted Solution [77]
Shared Variable:
int v=0; /* v==0 => critical section OPEN; v==1 => critical section CLOSED */
Code: At p_i in {1,...,n}:
while (1) {
/* trying region */
while (v == 1) /* do nothing */ ;
v = 1;
/* critical section (region) */
x = 0;
x++;
printf x;
v = 0;
/* remainder region */
}
Critical Section: General Problem [78]
Semaphore: wait and signal [79]
Semaphore: wait and signal [80]
while(1) {
pm_wait(sem);
/* critical section or region */
pm_signal(sem);
}
while(1) {
pm_wait(sem);
x=0;
x++;
printf x;
pm_signal(sem);
}
Semaphore: wait and signal [81]
struct {
int count=1;
FIFO queue;
} semaphore;
>= 0 IMPLIES queue is empty
wait(semaphore) : if (--semaphore.count<0){
put_at_tail(pid,semaphore.queue);
suspend(pid) }
signal(semaphore) : if (semaphore.count++<0){
pid=get_at_head(semaphore.queue);
ready(pid) }
Semaphore: Initialization [82]
Semaphore: Count [83]
PID 1 PID 2 count
sem=pm_seminit(1); 1
pm_wait(sem); 0
| pm_wait(sem); -1
(critical) |
v
pm_signal(sem); 0
pm_wait(sem); | -1
| (critical)
v
pm_signal(sem); 0
| pm_wait(sem); -1
(critical) |
v
pm_signal(sem); 0
Critical Section Solution [84]
Here is a summary:
| DEFINITION | PROOF TECHNIQUE | |
| MUTEX | at most 1 proc in C.S. | can't prove not mutex |
| NOT MUTEX | at least 2 procs in C.S. | slice before locking |
| PROGRESS | at least 1 proc does work, liveness | can't prove not progress |
| NOT PROGRESS | 0 procs do work, deadlock, but not starvation | all spinning (or blocked on semaphores) |
| FAIRNESS | all procs do work | can't prove not fairness |
| NOT FAIRNESS | 1 proc does work at expense of another not doing work, starvation, asymmetrical relationship | one proc releases but retakes lock, other proc just misses |
Of course, it's impossible to enumerate every possible proof of NOT MUTEX. So you really don't prove that it has MUTEX. But you always try NOT MUTEX first and, if you can't find such a proof and you feel more confident about the code, you very carefully say that it does guarantee MUTEX.
This is not a proof technique of unfairness: I pick a priority scheduler, always run P0, but never run P1. P1 starves.Well, what happens if you are given some different code? Are you going to repeat the same proof? Then you are given some more code. You repeat the same argument? You're not analyzing the code you're given - and that's the main point. You have to give P1 some opportunities to run on the CPU. But you can choose those opportunities (devil's advocate), and choose these such that P0 has taken the lock back, and P1 just misses everytime.
All of the following is older detail about this topic, but the table above is the simplest way of viewing this topic.
IMPORTANT: If two processes are deadlocked, i.e., no progress, this is NOT a proof of unfairness (starvation). Admittedly, they are not getting any work done, but unfairness results from ASYMMETRY, i.e., one process is getting work done at the expense of another process not getting work done.
Just remember this: progress means at least one process gets some work done; fairness means that all processes get work done.
To prove NO with respect to safety, progress or fairness, you need to make a counter example, i.e., a proof by contradiction. And if you can prove, say NO to safety, then that has no bearning on progress or fairness. That is, all three are independent and there are no rules of thumb to help correlate the answers.
And this is NOT a proof: assume a priority scheduler which never runs process 2 (a low priority process). Hence, process 2 is starving. But that would be a proof that could be used against ANY code example, regardless of the code. You have to at least let process 2 get some CPU time and attempt the critical section. But usually the proofs follow this pattern: process 2 gets the CPU but just at the wrong instant to be granted the critical section.
To prove YES is more difficult. You can't try every possible counter example. But if you try hard to answer NO but can't find a proof, then you carefully answer YES, after examining the logic of the code.
Critical Section: Deadlock [85]
Kansas legislature:
When two trains approach each other at a crossing,
both shall come to a full stop
and neither shall start up again until the other has gone.
Semaphores: Deadlock [86]
pm_wait(S);
pm_wait(Q);
/* critical section */
pm_signal(S);
pm_signal(Q);
pm_wait(Q);
pm_wait(S);
/* critical section */
pm_signal(Q);
pm_signal(S);