semaphore resource = 1; // Controls access to the shared resource (1 = free, 0 = locked)
semaphore readTry = 1; // Semaphore to allow or block readers (writer will lock this to get priority)
semaphore rmutex = 1; // Mutex for protecting read_count
semaphore wmutex = 1; // Mutex for protecting write_count
int read_count = 0; // Number of readers currently reading
int write_count = 0; // Number of writers waiting or in critical section
void reader() {
// Entry Section (attempt to enter read)
wait(readTry); // Attempt to enter the "readers gate". If a writer has locked this, reader waits here.
wait(rmutex); // Lock rmutex to safely update read_count
read_count++;
if (read_count == 1) {
wait(resource); // If this is the first reader, lock the resource for readers (blocks writers).
}
signal(rmutex);
signal(readTry); // Release the gate so others can try to enter (allows other readers or a waiting writer to proceed accordingly)
// Critical Section (Reading happens here)
// ... (read the shared data) ...
// Exit Section (finished reading)
wait(rmutex); // Lock rmutex to update read_count safely
read_count--;
if (read_count == 0) {
signal(resource); // If this was the last reader, release the resource lock (so writers can use it)
}
signal(rmutex);
}
void writer() {
// Entry Section (attempt to enter write)
wait(wmutex); // Lock wmutex to update write_count safely
write_count++;
if (write_count == 1) {
wait(readTry); // If this is the first waiting writer, lock the readers gate.
// (This blocks new readers from entering while writers are waiting.)
}
signal(wmutex);
wait(resource); // Lock the resource for exclusive access to write
// Critical Section (Writing happens here)
// ... (write to the shared data) ...
signal(resource); // Release the resource after writing is done
// Exit Section (finished writing)
wait(wmutex);
write_count--;
if (write_count == 0) {
signal(readTry); // If this was the last writer, open the gate for readers again.
}
signal(wmutex);
}