001 // ReleaseParameters.java, created by cata 002 // Copyright (C) 2001 Catalin Francu <cata@mit.edu> 003 // Licensed under the terms of the GNU GPL; see COPYING for details. 004 005 package javax.realtime; 006 007 import java.util.LinkedList; 008 import java.util.Iterator; 009 010 /** The abstract top-level class for release characteristics of threads. 011 * When a reference to a <code>ReleaseParameters</code> is given as a 012 * parameter to a constructor, the <code>ReleaseParameters</code> object 013 * becomes bound to the object being created. Changes to the values in 014 * the <code>ReleaseParameters</code> object affect the constructed 015 * object. If given to more than one constructor, then changes to the 016 * values in the <code>ReleaseParameters</code> object affect <i>all</i> 017 * of the associated objects. Note that this is a one-to-many relationship 018 * and <i>not</i> a many-to-many. 019 * <p> 020 * <b>Caution:</b> This class is explicitly unsafe in multihtreaded 021 * situations when it is being changed. No synchronizations is done. It is 022 * assumed that users of this class who are mutating instances will be 023 * doing their own synchronization at a higher level. 024 * <p> 025 * <b>Caution:</b> The <code>cost</code> parameter time should be 026 * considered to be measured against the target platform. 027 */ 028 public class ReleaseParameters { 029 RelativeTime cost; 030 RelativeTime deadline; 031 AsyncEventHandler overrunHandler; 032 AsyncEventHandler missHandler; 033 LinkedList schList = new LinkedList(); 034 035 /** Create a new instance of <code>ReleaseParameters</code>. */ 036 protected ReleaseParameters() {} 037 038 /** Makes a copy of the argument. */ 039 protected ReleaseParameters(ReleaseParameters release) { 040 this(release.cost, release.deadline, release.overrunHandler, release.missHandler); 041 } 042 043 /** Create a new instance of <code>ReleaseParameters</code> with 044 * the given parameter values. 045 * 046 * @param cost Processing time units per interval. On implementations 047 * which can measure the amount of time a schedulable 048 * object is executed, this value is the maximum amount 049 * of time a schedulable object receives per interval. 050 * On implementations which cannot measure execution time, 051 * this value is used as a hint to the feasibility 052 * algorithm. On such systems it is not possible to 053 * determine when any particular object exceeds cost. 054 * Equivalent to <code>RelativeTime(0, 0)</code> if null. 055 * @param deadline The latest permissible completion time measured 056 * from the release time of the associated invocation 057 * of the schedulable object. Changing the deadline 058 * might not take effect after the expiration of the 059 * current deadline. More detail provided in the 060 * subclasses. 061 * @param overrunHandler This handler is invoked if an invocation of 062 * the schedulable object exceeds cost. Not 063 * required for minimum implementation. If null, 064 * nothing happens on the overrun condition, and 065 * <code>waitForNextPeriod()</code> returns 066 * false immediately and updates the start time 067 * for the next period. 068 * @param missHandler This handler is invoked if the <code>run()</code> 069 * method of the schedulable object is still 070 * executing after the deadline has passed. Although 071 * minimum implementations do not consider deadlines 072 * in feasibility calculations, they must recognize 073 * variable deadlines and invoke the miss handler as 074 * appropriate. If null, nothing happens on the miss 075 * deadline condition. 076 */ 077 protected ReleaseParameters(RelativeTime cost, RelativeTime deadline, 078 AsyncEventHandler overrunHandler, 079 AsyncEventHandler missHandler) { 080 if (cost != null) 081 this.cost = new RelativeTime(cost); 082 else 083 this.cost = new RelativeTime(0, 0); 084 this.deadline = new RelativeTime(deadline); 085 this.overrunHandler = overrunHandler; 086 this.missHandler = missHandler; 087 } 088 089 /** Gets the value of the cost field. 090 * 091 * @return The value of cost. 092 */ 093 public RelativeTime getCost() { 094 return new RelativeTime(cost); 095 } 096 097 /** Gets a reference to the cost overrun handler. 098 * 099 * @return A reference to the associated cost overrun handler. 100 */ 101 public AsyncEventHandler getCostOverrunHandler() { 102 return overrunHandler; 103 } 104 105 /** Gets the value of the deadline field. 106 * 107 * @return The value of the deadline. 108 */ 109 public RelativeTime getDeadline() { 110 return new RelativeTime(deadline); 111 } 112 113 /** Gets a reference to the deadline miss handler. 114 * 115 * @return A reference to the deadline miss handler. 116 */ 117 public AsyncEventHandler getDeadlineMissHandler() { 118 return missHandler; 119 } 120 121 /** Sets the cost value. 122 * 123 * @param cost Processing time units per period or per minimum 124 * interarrival interval. On implementations which 125 * can measure the amount of time a schedulable 126 * object is executed, this value is the maximum 127 * amount of time a schedulable object receives per 128 * period or per minimum interarrival interval. On 129 * implementations which cannot measure execution 130 * time, this value is used as a hint to the 131 * feasibility algorithm. On such systems it is not 132 * possible to determine when any particular object 133 * exceeds or will exceed cost time units in a 134 * period or interval. Equivalent to 135 * <code>RelativeTime(0, 0)</code> if null. 136 */ 137 public void setCost(RelativeTime cost) { 138 this.cost.set(cost); 139 } 140 141 /** Sets the cost overrun handler. 142 * 143 * @param handler This handler is invoked if an invocation of the 144 * schedulable object attempts to exceed <code>cost</code> 145 * time units in a period. Not required for minimum 146 * implementation. See comments in <code>setCost()</code>. 147 */ 148 public void setCostOverrunHandler(AsyncEventHandler handler) { 149 this.overrunHandler = handler; 150 } 151 152 /** Sets the deadline value. 153 * 154 * @param deadline The latest permissible completion time measured from 155 * the release time of the associated invocation of the 156 * schedulable object. For a minimum implementation for 157 * purposes of feasibility analysis, the deadline is 158 * equal to the period or minimum interarrival interval. 159 * Other implementations may use this parameter to 160 * compute execution eligibility. 161 */ 162 public void setDeadline(RelativeTime deadline) { 163 this.deadline.set(deadline); 164 } 165 166 /** Sets the deadline miss handler. 167 * 168 * @param handler This handler is invoked if the <code>run()</code> method 169 * of the schedulable object is still executing after the 170 * deadline has passed. Although minimum implementations 171 * do not consider deadlines in feasibility calculations, 172 * they must recognize variable deadlines and invoke the 173 * miss handler as appropriate. 174 */ 175 public void setDeadlineMissHandler(AsyncEventHandler handler) { 176 this.missHandler = handler; 177 } 178 179 /** This method appears in many classes in the RTSJ and with various parameters. 180 * The parameters are either new scheduling characteristics for an instance 181 * <code>Schedulable</code> or an instance of <code>Schedulable</code>. The 182 * method first performs a feasibility analysis using the new scheduling 183 * characteristics as replacements for the matching scheduling characteristics 184 * of either <code>this</code> or the given instance of <code>Schedulable</code>. 185 * If the resulting system is feasible the method replaces the current scheduling 186 * characteristics, of either <code>this</code> or the given instance of 187 * <code>Schedulable</code> as appropriate, with the new scheduling characteristics. 188 * 189 * @param cost The poposed cost. 190 * @param deadline The proposed deadline. 191 * @return True, if the resulting system is feasible and the changes are made. 192 * False, if the resulting system is not feasible and no changes are made. 193 */ 194 public boolean setIfFeasible(RelativeTime cost, 195 RelativeTime deadline) { 196 boolean b = true; 197 Iterator it = schList.iterator(); 198 RelativeTime old_cost = this.cost; 199 RelativeTime old_deadline = this.deadline; 200 setCost(cost); 201 setDeadline(deadline); 202 while (b && it.hasNext()) 203 b = ((Schedulable)it.next()).setReleaseParametersIfFeasible(this); 204 if (!b) { // something is not feasible 205 setCost(old_cost); /// returning the values back 206 setDeadline(old_deadline); 207 for (it = schList.iterator(); it.hasNext(); ) // undoing all changes 208 ((Schedulable)it.next()).setReleaseParameters(this); 209 } 210 return b; 211 } 212 213 public boolean bindSchedulable(Schedulable sch) { 214 return schList.add(sch); 215 } 216 217 public boolean unbindSchedulable(Schedulable sch) { 218 return schList.remove(sch); 219 } 220 }