I am trying to solve this synchronization problem in C to practice for my lectures of Operating Systems where we use POSIX and Linux. I've been trying for days to find an approach to this problem with no luck, and I can't seem to find similar problems.
To be more specific, I'm failing to see which mechanism would allow me to satisfy this 2 conditions at the same time: respect time of arrival (the first to come, has the greatest priority), and no customer waiting unnecessarily.
Notice the question should be solved without semaphores. So I'm left with mutexes, cond vars and shared variables in memory. This is my attempt so far:
#include <...>
/* there are 2 pumps and infinite customers */
// Mutexes protecting the resources
pthread_mutex_t mPump1;
pthread_mutex_t mPump2;
// Conditional variable to signal the use from different threads
pthread_cond_t Pump1release, Pump1lock;
pthread_cond_t Pump2release, Pump2lock;
// Initial values
bool p1InUse = false;
bool p2InUse = false;
int getUnusedPump()
{
while(true)
{
while(p1InUse)
{
//1. acquire critical section
pthread_mutex_lock(&mPump1);
//Release lock & sleep
pthread_cond_wait(Pump1release, mPump1);
p1InUse = true;
return 1;
}
while(p2InUse)
{
//1. acquire critical section
pthread_mutex_lock(&mPump2);
//Release lock & sleep
pthread_cond_wait(Pump2release, mPump2);
p2InUse = true;
return 2;
}
}
}
void releasePump(int pump)
{
if(pump==1) //Release pump1 from our thread
{
p1InUse = false;
//signal the other threads
pthread_cond_signal(Pump1release);
//1. release critical section
pthread_mutex_unlock(&mPump1);
}
else
{
p2InUse = false;
//signal the other threads
pthread_cond_signal(Pump1release);
//1. release critical section
pthread_mutex_unlock(&mPump2);
}
}
One of the problems I find is that, given a certain moment when the 2 pumps are busy, If I put one thread to cond_wait()
on, say pump 1, but then pump 2 is unlocked, I would be violating requirement 3 because that thread shouldn't be waiting while there's an available pump. Equally concerning, I cannot figure out, given the 2 pumps are available, how should I decide to which of them I send an arriving client(thread)?
Is it possible at all to solve this problem using just the mentioned mechanisms?