OS Concepts · Chapter 6
A Producer and Consumer share a fixed-size circular buffer, synchronized with mutex, full and empty semaphores.
empty counts free slots, full counts filled slots, mutex guards the buffer itself. The Producer blocks on wait(empty) when the buffer is full; the Consumer blocks on wait(full) when it's empty.