UNIVERSITY OF WISCONSIN-MADISON
Computer Sciences Department
CS 537
Spring 2003
A. Arpaci-Dusseau
Question 4: Readers and Writers/b>

Name: Student ID #:

Readers and Writers with Semaphores

The following code implements the readers-writers problem with semaphores. It should be identical to that given to you in the Lecture Notes (no tricks here).

The main thread of the program (not shown) creates many reader and writer threads, starts each of them, and then waits forever for them to terminate by calling each thread's join() method.


class ReaderOrWriter implements Runnable {
     private static int sharedBuffer[] = new int[1000];     

     private static Semaphore mutex = new Semaphore(??);
     private static Semaphore OKToRead = new Semaphore(??);
     private static Semaphore OKToWrite = new Semaphore(??);
     private static int ActiveWriters = 0; 
     private static int WaitingWriters = 0;
     private static int ActiveReaders = 0; 
     private static int WaitingReaders = 0;

     public static final int READER = 0; 
     public static final int WRITER = 1;

     private int whichAmI;

ReaderOrWriter(int ReaderOrWriter) {
    whichAmI = ReaderOrWriter;
}
public void run() {
    while (true) {
        if (whichAmI == READER) {
             reader();
        } else {
             writer();
        }
    }
}
private void reader() {

     mutex.P();
     if ((ActiveWriters + WaitingWriters) == 0){
         OKToRead.V();
         ActiveReaders++;
     } else {
         WaitingReaders++;
     }
     mutex.V();
     OKToRead.P();

     // Perform read of sharedBuffer

     mutex.P();
     ActiveReaders--;
     if ((ActiveReaders == 0) && (WaitingWriters > 0)) {
          OKToWrite.V();
          ActiveWriters++;
          WaitingWriters--;
     }
     mutex.V();
}
private void writer() {

     mutex.P();
     if ((ActiveWriters + ActiveReaders + WaitingWriters) == 0) {
          OKToWrite.V();
          ActiveWriters++;
     } else {
          WaitingWriters++;
     }
     mutex.V();
     OKToWrite.P();

     // Perform write of dataBuffer 

     mutex.P();
     ActiveWriters--;
     if (WaitingWriters > 0) {
         OKToWrite.V();
         ActiveWriters++;
         WaitingWriters--;
     } else {
         while (WaitingReaders > 0) {
             OKToRead.V();
             ActiveReaders++;
             WaitingReaders--;
         }
     }
     mutex.V();
}

You should assume that semaphores have been implemented in Java in a reasonable way. This could be done by building on synchronized methods. You should assume that all semaphores are implemented with a First-in-First-out (FIFO) list of processes; that is, the process that has been waiting the longest for a semaphore will be the next one woken up.

You need to answer five questions about this code segment. Each will be worth the same number of points. No partial credit will be given for a question, so just state your final answer -- no need to explain your reasoning.

  1. What values should each of the semaphores be initialized to?
    a) mutex:
    b) OKToRead:
    c) OKToWrite:

  2. a) Assume a reader is currently using the buffer.
    If there are both waiting writers and waiting readers, will a writer or a reader get access to the buffer first?


    b) Assume a writer is currently using the buffer.
    If there are both waiting writers and waiting readers, will a writer or a reader get access to the buffer first?


  3. a) Is it possible for readers to starve with this code? b) Is it possible for writers?




  4. a) Can the semaphore OKToRead have a value greater than 1?
    b) Can OKToWrite?



  5. Assume there are many readers currently accessing the buffer.
    a) Is the first writer to execute mutex.P() guaranteed to be the first writer to use the buffer?



    b) Is the first writer to execute OKToWrite.P() guaranteed to be the first writer to use the buffer?