/* * cs101 Graphical Counting Semaphore utility * $Id: GCS.java,v 1.1.1.1 2002/06/05 21:56:32 root Exp $ * * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group. * For more information, see the * CS101 homepage or email . * * Copyright (C) 1996 Massachusetts Institute of Technology. * Please do not redistribute without obtaining permission. */ package cs101.util.semaphore; import java.awt.*; import cs101.awt.ColorField; /** * cs101.util.GCS implements a counting semaphore of arbitrary size * in java.
* Interface is gcs.request(), gcs.release().
* It also provides a graphical display of the semaphores status. *

* 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