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.