I want to know whether we should do the checking of the state of a shared-resource atomically or no. e.g. Consider the following code which demonstrates the classic Bounded-Buffer problem;
lock buf_lock = <initially unlocked>
condition producer_CV = <initially empty>
condition consumer_CV = <initially empty>
Producer(item) {
acquire(&buf_lock);
while (buffer full) {
cond_wait(&producer_CV, &buf_lock);
}
enqueue(item);
cond_signal(&consumer_CV);
release(&buf_lock);
}
Consumer() {
acquire(buf_lock);
while (buffer empty) {
cond_wait(&consumer_CV, &buf_lock);
}
item = dequeue();
cond_signal(&producer_CV);
release(buf_lock);
return item;
}
In particular I want to know whether the statements “buffer full” or “buffer empty” being evaluated and checked atomically in the while-loops or not.
My guess: I think they should be checked atomically because for sake of contradictory assume this scenario:
- Only one item exists in the queue
- Now some Consumer thread has been signaled and has acquired the lock as well. Now it goes to queue an item from the queue but it’s been preempted and got out of the CPU. Now assume another Consumer thread checking if the queue is not empty (notice that it doesn’t need to have acquired the lock if we are assuming the checking is not atomic.). It’s not empty so it would go to dequeue an item. Obviously we would have a conflict here…
7