Tom Kelliher, CS 318
Feb. 4, 1998
Announcements:
From last time:
Outline:
Assignment: Read Chapters 4 and 6.
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 n 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(); } }