001 /*
002 * cs101 Graphical Counting Semaphore utility
003 * $Id: GCS.java,v 1.1.1.1 2002/06/05 21:56:32 root Exp $
004 *
005 * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group.
006 * For more information, see <a href="http://www.ai.mit.edu/projects/cs101/">the
007 * CS101 homepage</a> or email <las@ai.mit.edu>.
008 *
009 * Copyright (C) 1996 Massachusetts Institute of Technology.
010 * Please do not redistribute without obtaining permission.
011 */
012
013 package cs101.util.semaphore;
014
015 import java.awt.*;
016 import cs101.awt.ColorField;
017
018 /**
019 * cs101.util.GCS implements a counting semaphore of arbitrary size
020 * in java. <br>
021 * Interface is gcs.request(), gcs.release(). <br>
022 * It also provides a graphical display of the semaphores status.
023 * <p>
024 * The general design of this utility was influenced by the
025 * design of the cs101.util.BS (wrote by Lynn Stein).
026 * <br>
027 * Copyright 1996 Massachusetts Institute of Technology
028 *
029 * @author Todd C. Parnell, tparnell@ai.mit.edu
030 * @author Joshua R. Brown, reuben@ai.mit.edu
031 * @version $Id: GCS.java,v 1.1.1.1 2002/06/05 21:56:32 root Exp $
032 *
033 */
034 public class GCS extends GraphicalSemaphore {
035 /** the length of the semaphore */
036 private int size;
037 /** how much of the semaphore is in use */
038 private int busy; // i <= busy are busy
039 // ( ie if busy=size-1 then all busy )
040 private ColorField[] fields;
041
042 // GCS( int, int, String )
043 /**
044 * Constructs a counting semaphore with the size and initial value
045 * passed in.
046 * Uses the String past in to identfy the semaphore in the display.
047 *
048 * @param size The length of the semaphore (Probably the length
049 * of the buffer that it is associated with).
050 * @param busy The number of intially busy blocks in the semaphore
051 * (ie all busy = size, all free = 0).
052 * @param label An identfying string of text for the semaphore.
053 */
054 public GCS (int size, int busy, String label) {
055 super(label);
056 this.size = size;
057 this.busy = busy-1; // adjust for ease of use
058
059 // make sure busy < size
060 if (this.busy >= this.size)
061 this.busy = this.size-1;
062
063 // make sure busy >= -1
064 if (this.busy < -1)
065 this.busy = -1;
066
067 // now that everything is initialized setup the GUI
068 this.setupGUI();
069
070 }
071
072 /**
073 * Does all of the graphical setup on this level
074 * then calls the superclasses method to finish the setup.
075 *
076 * This method is primarly responsible for setting up the
077 * display Panel.
078 */
079 protected void setupGUI() {
080
081 // do setup on this level
082 this.fields = new ColorField[this.size];
083
084 display = new Panel();
085 GridBagLayout layout = new GridBagLayout();
086 display.setLayout(layout);
087
088 GridBagConstraints con = new GridBagConstraints();
089 con.gridwidth = 1; con.gridheight=1;
090 con.fill = GridBagConstraints.VERTICAL;
091 con.weightx = 0; con.weighty = 1/this.size;
092
093 for (int i = 0; i < this.size; i++) {
094 if (i <= this.busy)
095 this.fields[i] = new ColorField(true, new Dimension(25,10),
096 Color.red, Color.green);
097 else
098 this.fields[i] = new ColorField(false, new Dimension(25,10),
099 Color.red, Color.green);
100 con.gridx = 0; con.gridy = i;
101 layout.setConstraints(this.fields[i], con);
102 display.add(this.fields[i]);
103
104 }
105
106 // now that GUI setup on this level is finished
107 // call super-class method
108 super.setupGUI();
109
110 }
111
112 /**
113 * Requests the semaphore. If all of the locks in the semaphore are
114 * currently busy, causes the requesting process to wait() until
115 * the semaphore is release()d.
116 * Unlike java.lang.Object.wait(), the requesting process is not
117 * suspended if the semaphore is currently free.
118 *
119 * @see #release
120 * @see java.lang.Object#wait
121 */
122 synchronized public void request() {
123 while (this.busy == this.size-1) {
124 try {this.wait();} catch (InterruptedException e) {}
125 }
126 this.busy++;
127 this.showStatus();
128 }
129
130 /**
131 * Releases a lock of the semaphore (if any are currently busy).
132 * Any objects currently wait()ing on the
133 * semaphore are notify()d (and one of them will be granted the
134 * semaphore). Unlike java.lang.Object.notify(), the semaphore is
135 * also freed so that if there are no wait()ing objects, the next
136 * object to request() the semaphore will receive it.
137 *
138 * @see #request
139 * @see java.lang.Object#notifyAll()
140 */
141 synchronized public void release () {
142 if (this.busy >= 0) {
143 this.busy--;
144 this.notifyAll();
145 this.showStatus();
146 }
147 }
148
149 /**
150 * Prints out the current state of the semaphore.
151 * Changes the graphical display.
152 */
153 protected void showStatus() {
154 // tab over an approprate amount
155 for (int i = 0; i<this.myNumber; i++)
156 System.out.print(" ");
157
158 // now print the status
159 System.out.print(this.label.getText()+": ");
160 System.out.println(this.busy+1);
161
162 // update the status fields
163 for (int i = 0; i < this.size; i++) {
164 if (i <= this.busy)
165 this.fields[i] .changeState(true);
166 else
167 this.fields[i].changeState(false);
168 }
169
170 }
171
172 }
173
174 /* Comments:
175 *
176 * History:
177 * $Log: GCS.java,v $
178 * Revision 1.1.1.1 2002/06/05 21:56:32 root
179 * CS101 comes to Olin finally.
180 *
181 * Revision 1.1 2000/04/24 22:17:22 nathanw
182 * Bulk reorganization
183 *
184 * Revision 1.4 1998/07/24 17:19:27 tparnell
185 * Placate new javadoc behavior
186 *
187 * Revision 1.3 1998/07/22 18:18:56 tparnell
188 * migration from cs101.util to cs101.*
189 *
190 * Revision 1.2 1998/06/03 19:43:36 tparnell
191 * update from Java 1.0 to 1.1
192 *
193 * Revision 1.1 1998/03/13 22:18:13 tparnell
194 * Import from server crash. I think the src and class files match up.
195 *
196 * Revision 1.4 1996/08/01 18:26:24 reuben
197 * More javadoc tweaking (hopefully the final pass)
198 *
199 * Revision 1.3 1996/07/25 18:27:42 reuben
200 * Added all kinds of comments.
201 * Compiled and tested.
202 *
203 */