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();
}
}