Readings

You may wish to go through the readings after you have digested the remainder of these lecture notes. It is very important that you complete the readings and understand the solutions for the next class, as we will be doing some exercises related to this material.

The Readers/Writers Problem


- consider a file that may be accessed simultaneously by multiple users
- can allow any number of readers at a time
- can only allow one writer at a time (no readers)
- how do we provide synchronization?

Solution #1: pg. 207
	- first reader waits for all writers to complete
	- any number of readers may access
	- only one writer allowed to enter critical section
	- writer must wait for all readers to complete
	- problem: possible writer starvation

Solution #2: pg. 209
	- when writer indicates intention to access, no new readers
	  may enter


int readCount = 0, writeCount = 0;	/* # of readers, writers */
semaphore readBlock = 1;		/* first writer blocks new readers */
semaphore writePending = 1;		/* reader can proceed only
					 * if no writer pending */
semaphore writeBlock = 1;		/* first reader blocks writers */
semaphore mutex1 = 1, mutex2 = 1;	/* for variable update critical sections */

reader() {
	while (TRUE) {
	   
	   P(writePending);		/* block if writer pending:
					 * occurs if previous reader doesn't
					 * make it past next line */
	      P(readBlock);		/* block if writer active or pending */
		P(mutex1);		/* for variable update */
		   readCount++;
		   if (readCount == 1)
		      P(writeBlock);	/* prevent writers from starting */
		V(mutex1);
	      V(readBlock);
	   V(writePending);

	   access(resource);		/* READ AWAY */

	   P(mutex1);			/* for variable update */
	      readCount--;
	      if (readCount == 0)
		V(writeBlock);		/* signal writer it can start */
	   V(mutex1);
	}
}

writer() {
	while (TRUE) {
	   
	   P(mutex2);			/* for variable update */
	      writeCount++;
	      if (writeCount == 1)
		P(readBlock);		/* first writer arrives... 
					 * don't allow any more readers */
	   V(mutex2);
	   P(writeBlock);		/* block if reader(s) or
					 * other writer already active */
					
	   access(resource);		/* WRITE AWAY */

	   V(writeBlock);		/* next writer can start */
	   P(mutex2);			/* for variable update */
	      writeCount--;
	      if (writeCount == 0)	/* last writer is done */
		V(readBlock);		/* signal reader it can start */
	   V(mutex2);
	}
}

Monitors

- monitors provide simplified paradigm for synchronization
- exactly same power as semaphores, but hide details in ADT
- ADT:
	- caller only sees interface
	- hidden implementation controls data structure
- monitor implementation likely uses semaphore to synchronize access
- only process can use monitor at a time; granted exclusive access
  through the monitor semaphore


monitor myMon {
	semaphore mutex = 1;
	
	...

   public:
	proc_i(...) {
		P(mutex);
		  
		V(mutex);
	}
	...
}

Solving the Readers/Writers problem with Monitors:

monitor ReaderWriter {
	int numberOfReaders = 0;
	int numberOfWriters = 0;
	boolean busy = FALSE;

   public:
	startRead() {
		while (numberOfWriters != 0);
		numberOfReaders++;
	}
	finishRead() {
		numberOfReaders--;
	}

	startWrite() {
		numberOfWriters++;
		while (busy || (numberOfReaders > 0));
		busy = TRUE;
	}
	finishWrite() {
		numberOfWriters--;
		busy = FALSE;
	}
}

- problem: look at implementation -- exclusive access granted to one process
- what happens when reader active and writer wants to start?
- pg. 230: solution requires waiting process to temporarily relinquish the monitor
  while maintaining its intent to detect a state change in the monitor at a later time
- read pp. 230-233 for solution
- read pp. 235-236 for Monitor solution to Dining Philosopher's problem
	- note that solution avoids deadlock but doesn't prevent starvation