* The general design of this utility was influenced by the
* design of the cs101.util.BS (wrote by Lynn Stein).
*
* Copyright 1996 Massachusetts Institute of Technology
*
* @author Todd C. Parnell, tparnell@ai.mit.edu
* @author Joshua R. Brown, reuben@ai.mit.edu
* @version $Id: GCS.java,v 1.1.1.1 2002/06/05 21:56:32 root Exp $
*
*/
public class GCS extends GraphicalSemaphore {
/** the length of the semaphore */
private int size;
/** how much of the semaphore is in use */
private int busy; // i <= busy are busy
// ( ie if busy=size-1 then all busy )
private ColorField[] fields;
// GCS( int, int, String )
/**
* Constructs a counting semaphore with the size and initial value
* passed in.
* Uses the String past in to identfy the semaphore in the display.
*
* @param size The length of the semaphore (Probably the length
* of the buffer that it is associated with).
* @param busy The number of intially busy blocks in the semaphore
* (ie all busy = size, all free = 0).
* @param label An identfying string of text for the semaphore.
*/
public GCS (int size, int busy, String label) {
super(label);
this.size = size;
this.busy = busy-1; // adjust for ease of use
// make sure busy < size
if (this.busy >= this.size)
this.busy = this.size-1;
// make sure busy >= -1
if (this.busy < -1)
this.busy = -1;
// now that everything is initialized setup the GUI
this.setupGUI();
}
/**
* Does all of the graphical setup on this level
* then calls the superclasses method to finish the setup.
*
* This method is primarly responsible for setting up the
* display Panel.
*/
protected void setupGUI() {
// do setup on this level
this.fields = new ColorField[this.size];
display = new Panel();
GridBagLayout layout = new GridBagLayout();
display.setLayout(layout);
GridBagConstraints con = new GridBagConstraints();
con.gridwidth = 1; con.gridheight=1;
con.fill = GridBagConstraints.VERTICAL;
con.weightx = 0; con.weighty = 1/this.size;
for (int i = 0; i < this.size; i++) {
if (i <= this.busy)
this.fields[i] = new ColorField(true, new Dimension(25,10),
Color.red, Color.green);
else
this.fields[i] = new ColorField(false, new Dimension(25,10),
Color.red, Color.green);
con.gridx = 0; con.gridy = i;
layout.setConstraints(this.fields[i], con);
display.add(this.fields[i]);
}
// now that GUI setup on this level is finished
// call super-class method
super.setupGUI();
}
/**
* Requests the semaphore. If all of the locks in the semaphore are
* currently busy, causes the requesting process to wait() until
* the semaphore is release()d.
* Unlike java.lang.Object.wait(), the requesting process is not
* suspended if the semaphore is currently free.
*
* @see #release
* @see java.lang.Object#wait
*/
synchronized public void request() {
while (this.busy == this.size-1) {
try {this.wait();} catch (InterruptedException e) {}
}
this.busy++;
this.showStatus();
}
/**
* Releases a lock of the semaphore (if any are currently busy).
* Any objects currently wait()ing on the
* semaphore are notify()d (and one of them will be granted the
* semaphore). Unlike java.lang.Object.notify(), the semaphore is
* also freed so that if there are no wait()ing objects, the next
* object to request() the semaphore will receive it.
*
* @see #request
* @see java.lang.Object#notifyAll()
*/
synchronized public void release () {
if (this.busy >= 0) {
this.busy--;
this.notifyAll();
this.showStatus();
}
}
/**
* Prints out the current state of the semaphore.
* Changes the graphical display.
*/
protected void showStatus() {
// tab over an approprate amount
for (int i = 0; i