Tom Kelliher, CS 311
Mar 19, 2012
Announcements:
From last time:
Outline:
Assignment: Read Chapter 6.
What is a critical section?
The overlapping portion of cooperating processes, where shared variables are being accessed.Not all processes share variables: independent processes.
Cooperating/independent processes.
Necessary conditions for a solution to the c.s. problem:
Assumptions:
Classic example: the producer/consumer problem (aka bounded buffer):
Global data:
const int N = 10; int buffer[N]; int in = 0; int out = 0; int full = 0; int empty = N;
Producer:
while (1) { while (empty == 0) ; buffer[in] = inData; in = ++in % N; --empty; ++full; }
Consumer:
while (1) { while (full == 0) ; outData = buffer[out]; out = ++out % N; --full; ++empty; }Is there potential for trouble here?
(for processes, )
Pi: do { mutexbegin(); /* CS entry */ CSi; mutexend(); /* CS exit */ non-CS } while (!done);
TAS: Test And Set. Semantics:
int TAS(int& val) { int temp; temp = val; // Body performed atomically. val = 1; return temp; }
A partial solution to the critical section problem for processes:
// Initialization int lock = 0; void MutexBegin() { while (TAS(lock)) // Ugh. A spin lock. ; } void MutexEnd() { lock = 0; }Prove that this is a solution to the C. S. problem.
wait(s) { while (s == 0) ; s--; }
Test and (possible) decrement executed atomically (usually achieved through hardware means).
signal(s) { s++; }
semaphore mutex = 1; mutexbegin: wait(mutex); mutexend: signal(mutex);
semaphore sig = 0; int_hndl: signal(sig); driver: startread(); wait(sig);
semaphore flag = 0; process1() { p1Part1(); // This will complete before p2part2() begins. signal(flag); p1Part2(); } process2() { p2part1(); wait(flag); p2part2();
Producer/Consumer problem:
semaphore count = N; semaphore mutex = 1; getbuf: wait(count); /* order important here */ wait(mutex); <grab unallocated buffer> signal(mutex); return(buffer); relbuf: wait(mutex); <release buffer> signal(mutex); signal(count);
Associate a ``blocked'' queue with each semaphore.
typedef struct semaphore { int value; pcb *head; }
Semaphore creation:
semaphore *createsem(int value) { semaphore *sem; sem = get_next_sem(); sem->value = value; sem->head = NULL; return (sem); } void wait(semaphore *sem) { /* need mutex goo here */ if (--sem->value < 0) { <update status of current process> insqu(sem->head->prev, current); scheduler(); } } void signal(semaphore *sem) { /* mutex */ pcb *proc; if (++sem->value <= 0) { proc = remqu(sem->head->next); <update status of proc> ordinsqu(ready, proc); if (proc->prio > current->prio) scheduler(); } }