semaphore mutex(1) // int in_cr = 0
// mutex.cnt() + in_cr = 1
co
mutex.lock() // in_cr++
// mutex.cnt() + in_cr = 1
mutex.unlock() // in_cr--
||
mutex.lock() // in_cr++
// mutex.cnt() + in_cr = 1
mutex.unlock() // in_cr--
oc
{ 0 <= mutex.cnt() <= 1 } - implied by the
binary semaphore invariant
semaphore mutex(0)
doesn't satisfy the invariant
semaphore buffer_full(0)
semaphore buffer_empty(1)
// int using_buffer = 0
// buffer_full.cnt + buffer_empty.cnt + using_buffer = 1
co
// producer
while (true)
buffer_empty.wait() // using_buffer++
buffer = ...
buffer_full.signal() // using_buffer--
||
// consumer
while (true)
buffer_full.wait() // using_buffer++
buffer = ...
buffer_empty.signal() // using_buffer--
oc
resource buffer[n]
int newest = 0, oldest = 0
semaphore empty_slots(n)
semaphore full_slots(0)
// int slots_inuse = 0
// empty_slots.cnt + full_slots.cnt + slots_inuse = n
co
// producer
while true
empty_slots.take() // slots_inuse++
buffer[newest] = ...
newest = newest + 1 mod n
full_slots.put() // slots_inuse--
||
// consumer
while true
full_slots.take()
r = buffer[oldest] // slots_inuse++
oldest = oldest + 1 mod n
empty_slots.put() // slots_inuse--
co
n - 2 <= empty_slots.cnt + full_slots.cnt <= 2
oldest and newest
become critical references - none of the statements satisfy at most once
resource buffer[n]
int newest = 0, oldest = 0
semaphore empty_slots(n)
semaphore full_slots(0)
semaphore mutex(1)
// empty_slots.cnt + full_slots.cnt + slots_inuse = n
co
// producer i
while true
empty_slots.take() // slots_inuse++
mutex.lock()
buffer[newest] = ...
newest = newest + 1 mod n
mutex.unlock()
full_slots.put() // slots_inuse--
||
// consumer j
while true
full_slots.take()
mutex.lock()
r = buffer[oldest] // slots_inuse++
oldest = oldest + 1 mod n
mutex.unlock()
empty_slots.put() // slots_inuse++
co
take()s fork i and i + 1 mod
(n)
This page last modified on 27 June 2002.