out = getchar(); putchar(out);
depends on who runs when.

while(true) {
semWait(s);
/*critical section*/
semPost(s);
}
void consumer() {
if (n==0) sem_wait(empty);
sem_wait(s);
take();
n--;
sem_post(s);
consume();
}
void producer() {
while(1) {
produce();
sem_wait(s);
append();
n++;
if (n==1) sem_post(empty);
sem_post(s);
}
}
This works better:
void consumer() {
sem_wait(n);
sem_wait(s);
take();
sem_post(s);
consume();
}
void producer() {
while(1) {
produce();
sem_wait(s);
append();
sem_post(s);
sem_post(n);
}
}
e = sizeofbuffer; n = 0;
void consumer() {
sem_wait(n);
sem_wait(s);
take();
sem_post(s);
sem_post(e);
consume();
}
void producer() {
while(1) {
produce();
sem_wait(e)
sem_wait(s);
append();
sem_post(s);
sem_post(n);
}
}
void append(x) {
if (count == n) wait(full);
buffer[next]= x;
next = (next+1)%N;
count++;
signal(empty);
}
void take(x) {
if (count == 0) wait(empty);
x = buffer[next];
next = (next-1)%N;
count--;
signal(full);
}
void producer() {
while (1) {
produce(x);
append(x);
}
void consumer() {
while (1) {
take(x);
consume(x);
}
| Process | Step | rsem | wsem | x | y | z | readcount | writecount | comment |
| none | n/a | 1 | 1 | 1 | 1 | 1 | 0 | 0 | |
| r1 | semWait(z) | 1 | 1 | 1 | 1 | 0 | 0 | 0 | |
| r1 | semWait(rsem) | 0 | 1 | 1 | 1 | 0 | 0 | 0 | |
| r1 | emWait(x) | 0 | 1 | 0 | 1 | 0 | 0 | 0 | |
| r1 | readcount++ | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |
| r1 | semWait(wsem) | 0 | 0 | 0 | 1 | 0 | 1 | 0 | lock out writers |
| r1 | semSignal(x) | 0 | 0 | 1 | 1 | 0 | 1 | 0 | |
| r1 | semSignal(rsem) | 1 | 0 | 1 | 1 | 0 | 1 | 0 | |
| r1 | semSignal(z) | 1 | 0 | 1 | 1 | 1 | 1 | 0 | |
| swap | r2 | semWait(z) | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
| r2 | semWait(rsem) | 0 | 0 | 1 | 1 | 0 | 1 | 0 | |
| r2 | semWait(x) | 0 | 0 | 0 | 1 | 0 | 1 | 0 | |
| r2 | readcount++ | 0 | 0 | 0 | 1 | 0 | 2 | 0 | |
| r2 | semSignal(x) | 0 | 0 | 1 | 1 | 0 | 2 | 0 | |
| r2 | semSignal(rsem) | 1 | 0 | 1 | 1 | 0 | 2 | 0 | |
| r2 | semSignal(z) | 1 | 0 | 1 | 1 | 1 | 2 | 0 | |
| swap | r3 | semWait(z) | 1 | 0 | 1 | 1 | 0 | 2 | 0 |
| r3 | semWait(rsem) | 0 | 0 | 1 | 1 | 0 | 2 | 0 | |
| r3 | semWait(x) | 0 | 0 | 0 | 1 | 0 | 2 | 0 | |
| r3 | readcount++ | 0 | 0 | 0 | 1 | 0 | 3 | 0 | |
| r3 | semSignal(x) | 0 | 0 | 1 | 1 | 0 | 3 | 0 | |
| r3 | semSignal(rsem) | 1 | 0 | 1 | 1 | 0 | 3 | 0 | |
| r3 | semSignal(z) | 1 | 0 | 1 | 1 | 1 | 3 | 0 | |
| swap | We now have 3 readers reading | ||||||||
| w1 | semWait(y) | 1 | 0 | 1 | 0 | 1 | 3 | 0 | |
| w1 | writecount++ | 1 | 0 | 1 | 0 | 1 | 3 | 1 | |
| w1 | semWait(rsem) | 0 | 0 | 1 | 0 | 1 | 3 | 1 | Am I first? Lock out new readers. |
| w1 | semSignal(y) | 0 | 0 | 1 | 1 | 1 | 3 | 1 | |
| w1 | semwait(wsem) | 0 | -1 | 1 | 1 | 1 | 3 | 1 | |
| block | readers have locked us out | ||||||||
| w2 | semwait(y) | 0 | -1 | 1 | 0 | 1 | 3 | 1 | |
| w2 | writecount++ | 0 | -1 | 1 | 0 | 1 | 3 | 2 | |
| w2 | semSignal(y) | 0 | -1 | 1 | 1 | 1 | 3 | 2 | |
| w2 | semWait(wsem) | 0 | -2 | 1 | 1 | 1 | 3 | 2 | |
| block | 2 writers waiting on the readers. | ||||||||
| r4 | semWait(z) | 0 | -2 | 1 | 1 | 0 | 3 | 2 | Oh no! will new readers starve our writers? |
| r4 | semWait(rsem) | -1 | -2 | 1 | 1 | 0 | 3 | 2 | |
| block | See how we're blocked before releasing z? | ||||||||
| r5 | semWait(z) | -1 | -2 | 1 | 1 | -1 | 3 | 2 | |
| block | Any new readers will block on z. | ||||||||
| r1 | semWait(x) | -1 | -2 | 0 | 1 | -1 | 3 | 2 | The early ones finish |
| r1 | readcount-- | -1 | -2 | 0 | 1 | -1 | 2 | 2 | |
| r1 | semSignal(x) | -1 | -2 | 1 | 1 | -1 | 2 | 2 | done | Still readers in there. |
| r2 | semWait(x) | -1 | -2 | 0 | 1 | -1 | 2 | 2 | |
| r2 | readcount-- | -1 | -2 | 0 | 1 | -1 | 1 | 2 | |
| r2 | semSignal(x) | -1 | -2 | 1 | 1 | -1 | 1 | 2 | done | One left. |
| r3 | semWait(x) | -1 | -2 | 0 | 1 | -1 | 1 | 2 | |
| r3 | readcount-- | -1 | -2 | 0 | 1 | -1 | 0 | 2 | |
| r3 | semSignal(wsem) | -1 | -1 | 0 | 1 | -1 | 0 | 2 | Last one out, wake up the writers |
| r3 | semSignal(x) | -1 | -1 | 1 | 1 | -1 | 0 | 2 | |
| done | Writers ready to go. | ||||||||
| w3 | semWait(y) | -1 | -1 | 1 | 0 | -1 | 0 | 2 | new writer, what order will they run? |
| w3 | writecount++ | -1 | -1 | 1 | 0 | -1 | 0 | 3 | |
| w3 | semSignal(y) | -1 | -1 | 1 | 1 | -1 | 0 | 3 | |
| w3 | semWait(wsem) | -1 | -2 | 1 | 1 | -1 | 0 | 3 | |
| block | |||||||||
| w1 | semSignal(wsem) | -1 | -1 | 1 | 1 | -1 | 0 | 3 | Writer completes, wakes next writer |
| w1 | semWait(y) | -1 | -1 | 1 | 0 | -1 | 0 | 3 | |
| w1 | writecount-- | -1 | -1 | 1 | 0 | -1 | 0 | 2 | |
| w1 | semSignal(y) | -1 | -1 | 1 | 1 | -1 | 0 | 2 | |
| done | |||||||||
| w2 | semSignal(wsem) | -1 | 0 | 1 | 1 | -1 | 0 | 2 | |
| w2 | semWait(y) | -1 | 0 | 1 | 0 | -1 | 0 | 2 | |
| w2 | writecount-- | -1 | 0 | 1 | 0 | -1 | 0 | 1 | |
| w2 | semSignal(y) | -1 | 0 | 1 | 1 | -1 | 0 | 1 | |
| done | Readers still blocked. | ||||||||
| w3 | semSignal(wsem) | -1 | 1 | 1 | 1 | -1 | 0 | 1 | |
| w3 | semWait(y) | -1 | 1 | 1 | 0 | -1 | 0 | 1 | |
| w3 | writecount-- | -1 | 1 | 1 | 0 | -1 | 0 | 0 | |
| w3 | semSignal(rsem) | 0 | 1 | 1 | 0 | -1 | 0 | 0 | Last writer out, wake the readers |
| w3 | semSignal(y) | 0 | 1 | 1 | 1 | -1 | 0 | 0 | |
| done | Remaining readers go. | ||||||||
| r4 | semWait(x) | 0 | 1 | 0 | 1 | -1 | 0 | 0 | |
| r4 | readcount++ | 0 | 1 | 0 | 1 | -1 | 1 | 0 | |
| r4 | semWait(wsem) | 0 | 0 | 0 | 1 | -1 | 1 | 0 | |
| r4 | semSignal(x) | 0 | 0 | 1 | 1 | -1 | 1 | 0 | |
| r4 | semSignal(rsem) | 1 | 0 | 1 | 1 | -1 | 1 | 0 | |
| r4 | semSignal(z) | 1 | 0 | 1 | 1 | 0 | 1 | 0 | Waking other reader |
| r4 | semWait(x) | 1 | 0 | 0 | 1 | 0 | 1 | 0 | |
| r4 | readcount-- | 1 | 0 | 0 | 1 | 0 | 0 | 0 | |
| r4 | semSignal(wsem) | 1 | 1 | 0 | 1 | 0 | 0 | 0 | |
| r4 | semSignal(x) | 1 | 1 | 1 | 1 | 0 | 0 | 0 | |
| done | Last one. | ||||||||
| r4 | semWait(rsem) | 0 | 1 | 1 | 1 | 0 | 0 | 0 | |
| r4 | semWait(x) | 0 | 1 | 0 | 1 | 0 | 0 | 0 | |
| r4 | readcount++ | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |
| r4 | semWait(wsem) | 0 | 0 | 0 | 1 | 0 | 1 | 0 | |
| r4 | semSignal(x) | 0 | 0 | 1 | 1 | 0 | 1 | 0 | |
| r4 | semSignal(rsem) | 1 | 0 | 1 | 1 | 0 | 1 | 0 | |
| r4 | semSignal(z) | 1 | 0 | 1 | 1 | 1 | 1 | 0 | |
| r4 | semWait(x) | 1 | 0 | 0 | 1 | 1 | 1 | 0 | |
| r4 | readcount-- | 1 | 0 | 0 | 1 | 1 | 0 | 0 | |
| r4 | semSignal(wsem) | 1 | 1 | 0 | 1 | 1 | 0 | 0 | |
| r4 | semSignal(x) | 1 | 1 | 1 | 1 | 1 | 0 | 0 | |
| done | and done. |