-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCommunicator.java
114 lines (97 loc) · 2.95 KB
/
Communicator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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 {
/* this is the word to be listened by listened
* the words from other speakers are hidden and
* put to this variable when the owner(speaker) are wakened
*/
private int wordToBeListened;
/*
* if this varialbe is turned on, then the newly coming speaker
* goes to sleep
**/
private boolean isWordToBeListened;
private Condition2 speakerCondition;
private Condition2 listenerCondition;
/*
* this condition variable is used to pair a speaker and a listener
* */
private Condition2 listenerSpeakerHandShake;
// private handshake
private Lock lock;
/**
* Allocate a new communicator.
*/
public Communicator() {
this.isWordToBeListened = false;
this.lock = new Lock();
this.speakerCondition = new Condition2(lock);
this.listenerCondition = new Condition2(lock);
this.listenerSpeakerHandShake = new Condition2(lock);
}
/**
* 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) {
lock.acquire();
while(isWordToBeListened)
speakerCondition.sleep();
this.isWordToBeListened = true;
this.wordToBeListened = word;
/*
* try to wake up one listener if there is one
* but what if on listener?
* well, that is why listenerSpeakerHandShake is present
**/
listenerCondition.wake();
/*
* 1. if there is no listener
* goes to sleep in listenerSpeakerHandShake
*
* 2. if there is at least one listener
* still goes to sleep in listenerSpeakerHandShake
* however, at least one listener is in ready queue due to
*
* listenerCondition.wake()
*
* that listener will immediately wake this speaker up
**/
listenerSpeakerHandShake.sleep();
lock.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 wordTransferred;
lock.acquire();
while(!isWordToBeListened)
listenerCondition.sleep();
wordTransferred = this.wordToBeListened;
this.isWordToBeListened = false;
/*
* wake up the speaker who shout `word` out
**/
speakerCondition.wake();
listenerSpeakerHandShake.wake();
lock.release();
return wordTransferred;
}
}