90 lines
2.1 KiB
Java
90 lines
2.1 KiB
Java
package nachos.threads;
|
|
|
|
import nachos.machine.*;
|
|
|
|
/**
|
|
* A <i>communicator</i> allows threads to synchronously exchange 32-bit
|
|
* messages. Multiple threads can be waiting to <i>speak</i>,
|
|
* and multiple threads can be waiting to <i>listen</i>. But there should never
|
|
* be a time when both a speaker and a listener are waiting, because the two
|
|
* threads can be paired off at this point.
|
|
*/
|
|
public class Communicator
|
|
{
|
|
/**
|
|
* Allocate a new communicator.
|
|
*/
|
|
public Communicator()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Wait for a thread to listen through this communicator, and then transfer
|
|
* <i>word</i> to the listener.
|
|
*
|
|
* <p>
|
|
* Does not return until this thread is paired up with a listening thread.
|
|
* Exactly one listener should receive <i>word</i>.
|
|
*
|
|
* @param word the integer to transfer.
|
|
*/
|
|
public void speak(int word)
|
|
{
|
|
condLock.acquire();
|
|
if(protect==1) condProtect.sleep();
|
|
speakers++;
|
|
protect=1;
|
|
if(listeners==0)
|
|
{
|
|
condSpeaker.sleep();
|
|
message=word;
|
|
condPaired.wake();
|
|
}
|
|
else
|
|
{
|
|
message=word;
|
|
listeners--;
|
|
speakers--;
|
|
condListener.wake();
|
|
}
|
|
condLock.release();
|
|
}
|
|
|
|
/**
|
|
* Wait for a thread to speak through this communicator, and then return
|
|
* the <i>word</i> that thread passed to <tt>speak()</tt>.
|
|
*
|
|
* @return the integer transferred.
|
|
*/
|
|
public int listen()
|
|
{
|
|
int ret=0;
|
|
condLock.acquire();
|
|
listeners++;
|
|
if(speakers==0) condListener.sleep();
|
|
else
|
|
{
|
|
speakers--;
|
|
listeners--;
|
|
condSpeaker.wake();
|
|
condPaired.sleep();
|
|
}
|
|
ret=message;
|
|
protect=0;
|
|
condProtect.wake();
|
|
condLock.release();
|
|
return ret;
|
|
}
|
|
|
|
private int speakers=0;
|
|
private int listeners=0;
|
|
private int protect=0;
|
|
private int message=0;
|
|
private Lock condLock=new Lock();
|
|
private Condition condProtect=new Condition(condLock);
|
|
private Condition condSpeaker=new Condition(condLock);
|
|
private Condition condListener=new Condition(condLock);
|
|
private Condition condPaired=new Condition(condLock);
|
|
}
|
|
|