Outline for 1/16/98


Eliminating Circular Wait Conditionn

while (food available)
{	 if (me == 0) {P(fork[left(me)]); P(fork[right(me)]);}
	 else {(P(fork[right(me)]); P(fork[left(me)]); }
	eat;
	 V(fork[left(me)]); V(fork[right(me)]); 			
	think awhile;
}
Assuming the semaphore implementation gives us "fair" semaphores, does this solution have starvation?


Eliminating Hold and Wait Condition

while (food available)
{	P(mutex);
 	while (forks [me] != 2) 
		{blocking[me] = true; V(mutex); P(sleepy[me]); P(mutex);}
	forks [leftneighbor(me)] --;  forks [rightneighbor(me)]--;
	V(mutex):
	eat;
	P(mutex); forks [leftneighbor(me)] ++;  forks [rightneighbor(me)]++;
	if (blocking[leftneighbor(me)]) V(sleepy[leftneighbor(me)]); 
	if (blocking[rightneighbor(me)]) V(sleepy[rightneighbor(me)]); V(mutex);
	think awhile;
}

Starvation

The difference between deadlock and starvation is subtle:

Monitor Abstraction


Condition Variables


5DP - Monitor Style

Boolean eating [5];
Lock forkMutex;
Condition forksAvail;

void PickupForks (int i) {
	forkMutex.Acquire( );
	while ( eating[(i-1)%5] || eating[(i+1)%5] ) 
	     forksAvail.Wait(&forkMutex);
	eating[i] = true;
	forkMutex.Release( );
}

void PutdownForks (int i) {
	forkMutex.Acquire( );
	eating[i] = false;
	forksAvail.Broadcast(&forkMutex);
	forkMutex.Release( );
}

What about this?

while (food available)
{	forkMutex.Acquire( );
 	while (forks [me] != 2) {blocking[me]=true;
		forkMutex.Release( ); sleep( ); forkMutex.Acquire( );}
	forks [leftneighbor(me)]--;  forks [rightneighbor(me)]--;
	 forkMutex.Release( ):
	eat;
	 forkMutex.Acquire( );
	forks[leftneighbor(me)] ++;  forks [rightneighbor(me)]++;
	if (blocking[leftneighbor(me)] || blocking[rightneighbor(me)]) wakeup ( );  forkMutex.Release( );
	think awhile;
}