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 */