Changes

Jump to: navigation, search

Computer Science/162/proj1

216 bytes added, 23:45, 4 October 2008
Communicator: formatting + copyedit
==Communicator==
===Implementation===
;New state variablesWe add new state variables (a lock, four counters, and two condition variables): . {{c|<pre>Lock lock = new Lock()int activeSpeakers= 0int waitingSpeakers= 0int activeListeners= 0int waitingListeners= 0Condition speakers
Condition listeners
Condition return</pre>}} * The first lone speaker or listener will be counted as ''active'', or in the process of exchanging a message and returning, and will sleep on the {{c|return }} condition variable until its counterpart wakes it up so that they can both return. * A second thread performing the same action as a currently active thread will be counted as ''waiting'', and be put to sleep on its respective condition variable. Otherwise, it will check if there is an ''active '' thread of its counterpart action waiting on the {{c|return }} condition variable. If there isn’tisn't, it will attempt to wake waiting threads of its counterpart action prior to going to sleep on the return condition variable. If there is a counterpart ''active '' thread, it will wake it up and they both will return. Prior to returning, a the counterpart action will also attempt to wake sleeping ''waiting '' threads of its type.* Any interjecting threads that execute in between an exchange of message will be stopped by the ''active '' counters, which do not decrement until BOTH '''both''' counterparts in the exchange have returned.
===Testing===
Our original solution exhibited non-deterministic behavior, so after rewriting it, we decided to stress it exceptionally to make sure that it was working correctly. We tested our communicator in three main ways.
First, we set up a manual sequence of {{c|speak() }} and {{c|listen() }} actions on different threads and executed them in a particular order, verifying that the resulting sequence of messages was correct, monitored via print statements to the console
Second, we set off a random number of speakers, followed by a random number of listeners, and verified that the limiting resource was completely used up, i.e. that a matching number of speakers and listeners returned and that this was equal to the smaller of numbers of created speakers/listeners.
Finally, we repeated the same procedure, but intermingled the creation of speakers and listeners via .fork(), such that listeners would start listening before all the speakers were queued up.
ThirdFinally, we used testing functions: MassSpeaker and MassListener are designed to be run by a single thread each. These runnables iterate until a given limitrepeated the same procedure, and on each iteration, there is a 50% chance that a speak (or listen) is called. After each iteration, the thread yields to the opposite thread to do but intermingled the same. Debug statements will display what threads are doing at each iteration and how messages are being exchanged. With this we can generate large amounts creation of calls with randomized orders between two threads, speakers and will be able to verify all speaks are correctly received by a listenlisteners via {{c|.A second set of runnables, MassTSpeaker and MassTListener, are designed to fork off several threads themselves()}}, with each of these forked threads performing a single speak or listen. These forked threads are also executed with 50% chance on each iteration to provide random ordering. We can also verify if such that listeners would start listening before all threads are correctly paired off via print statements to consolethe speakers were queued up.
The latter two tests were run with up to 500 threads of speakers and listeners each (with a temporary override on the number of max threads in Nachos) and the number of listen and speak operations was analyzed via script. The speakers and listeners would print statements while executing code, which allowed us to perform this analysis.
The latter two To be able to perform these tests were run with up to 500 threads , we created a number of speakers helper classes. {{c|MassSpeaker}} and listeners {{c|MassListener}} are designed to be run by a single thread each (with . These runnables iterate until a temporary override given limit, and on each iteration, there is a 50% chance that a speak (or listen) is called. After each iteration, the number thread yields to the opposite thread to do the same. Debug statements will display what threads are doing at each iteration and how messages are being exchanged. With this we can generate large amounts of max calls with randomized orders between two threads in Nachos) , and the number will be able to verify all speaks are correctly received by a listen. A second set of listen runnables, {{c|MassTSpeaker}} and {{c|MassTListener}}, are designed to fork off several threads themselves, with each of these forked threads performing a single speak operations was analyzed or listen. These forked threads are also executed with 50% chance on each iteration to provide random ordering. We can also verify if all threads are correctly paired off via script. The speakers and listeners would print statements while executing code, which allowed us to perform this analysisconsole.
===Pseudocode==={|| style="vertical-align: top;"| speak(int word) {
Acquire the lock;
while (There is an active speaker) {
}
}
||
listen() {
Acquire the lock;
}
}
|}
==Priority Scheduler==
1,277
edits

Navigation menu