TL;DR
I have a homework where i need to implement thread synchronization. During implementation i was concerned if pthread_cond_wait()
also locks mutex if it spuriously wakes up and not just if it successfully wakes up.
Task
The task is a worker/delivery problem where there are worker threads and management threads which provide orders for the workers. For this purpose there is an order list from which the workers get orders and the management thread deposits orders. The order list is a shared object and needs to be synchronized.
My solution so far
I thought for this problem i need a monitor for the list to protect it from accesses on emptiness or from deposits when its full.
void deposit_order(order_list* ol, order* o){
pthread_mutex_lock(&(ol->mut_order_access));
while(get_count(ol) >= MAX_ORDERS) {
pthread_cond_wait(&(ol->cond_not_full), &(ol->mut_order_access));
}
ol->orders[ol->head] = o;
ol->head = (ol->head+1)%MAX_ORDERS;
ol->count++;
pthread_cond_signal(&(ol->cond_not_empty));
pthread_mutex_unlock(&(ol->mut_order_access));
}
order* get_order(order_list* ol) {
pthread_mutex_lock(&(ol->mut_order_access));
while(get_count(ol) <= 0) {
pthread_cond_wait(&(ol->cond_not_empty), &(ol->mut_order_access));
}
order* o;
o = ol->orders[ol->tail];
ol->tail = (ol->tail+1)%MAX_ORDERS;
ol->count--;
pthread_cond_signal(&(ol->cond_not_full));
pthread_mutex_unlock(&(ol->mut_order_access));
return o;
}
I believe it is not that important what the structures contain since the topic is how to synchronize the access. Obviously the structure order_list
holds a mutex
and two condition variables to signal the other thread. So if a worker removes a task from the list, it signals "not empty" to the management thread so it can deposit an additional order. If the management deposits an order is signals "not empty" to the worker threads so one thread can remove an order from the list.
My Concerns
So far so good but now i think there is that one event where the above solution may be critical and that is a "spurious wakeup". From this thread i learned that a thread can not spuriously wakeup if the corresponding mutex namely mut_order_access
is locked by another thread. But what if there is for example only one order in the list so that get_count(ol) >= MAX_ORDERS
is not fulfilled and a thread spuriously wakes up from the wait, checks the condition and marks it as not true and jumps out of the loop. Then another thread receives the signal and wakes up normally locking the mutex after the previous thread is already in the critical area. So now both threads would be in the critical area which would be a failure.
Question
So the above could only happen if a thread does not lock the mutex when it spuriously wakes up so does it lock the mutex on spurious wakeup or not?