001    // ProcessingGroupParameters.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    import java.util.Date;
007    import java.util.LinkedList;
008    import java.util.Iterator;
009    
010    /** This is associated with one or more schedulable objects for which the
011     *  system guarantees that the associated objects will not be fiven more
012     *  time per period than indicated by cost. For all threads with a 
013     *  reference to an instance of <code>ProcessingGroupParameters p</code>
014     *  and a reference to an instance of <code>AperiodicParameters</code> no
015     *  more than p.cost will be allocated to the execution of these threads
016     *  in each interval of time given by p.period after the time indicated
017     *  by p.start. When a reference to a <code>ProcessingGroupParameters</code>
018     *  object is given as a parameter to a constructor the
019     *  <code>ProcessingGroupParameters</code> object becomes bound to the
020     *  object being created. Changes to the values in the
021     *  <code>ProcessingGroupParameters</code> object affect the constructed
022     *  object. If given to more than one constructor, then changes to the
023     *  values in the <code>ProcessingGroupParameters</code> object affect
024     *  <i>all</i> of the associated objects. Note that this is a one-to-many
025     *  relationship and <i>not</i> a many-to-many.
026     *  <p>
027     *  <b>Caution:</b> This class is explicitly unsafe in multithreaded
028     *  situations when it is being changed. No synchronization is done. It is
029     *  assumed that users of this class who are mutating instances will be
030     *  doing their own synchronization at a higher level.
031     *  <p>
032     *  <b>Caution:</b> The <code>cost</code> parameter time should be
033     *  considered to be measured against the target platform.
034     */
035    public class ProcessingGroupParameters {
036        HighResolutionTime start;
037        RelativeTime period;
038        RelativeTime cost;
039        RelativeTime deadline;
040        AsyncEventHandler overrunHandler;
041        AsyncEventHandler missHandler;
042        LinkedList schList = new LinkedList();
043    
044        /** Create a <code>ProcessingGroupParameters</code> objects.
045         *
046         *  @param start Time at which the first period begins.
047         *  @param period The period is the interval between successive unblocks
048         *                of <code>waitForNextPeriod()</code>.
049         *  @param cost Processing time per period.
050         *  @param deadline The latest permissible completion time measured from
051         *                  the start of the current period. Changing the 
052         *                  deadline might not take effect after the expiration
053         *                  of the current deadline.
054         *  @param overrunHandler This handler is invoked if the <code>run()</code>
055         *                        method of the schedulable object of the previous
056         *                        period is still executing at the start of the
057         *                        current period.
058         *  @param missHandler This handler is invoked if the <code>run()</code>
059         *                     method of the schedulable object is still executing
060         *                     after the deadline has passed.
061         */
062        public ProcessingGroupParameters(HighResolutionTime start,
063                                         RelativeTime period, RelativeTime cost,
064                                         RelativeTime deadline,
065                                         AsyncEventHandler overrunHandler,
066                                         AsyncEventHandler missHandler) {
067            this.start = start;
068            this.period = period;
069            this.cost = cost;
070            this.deadline = deadline;
071            this.overrunHandler = overrunHandler;
072            this.missHandler = missHandler;
073        }
074    
075        /** Gets the value of <code>cost</code>.
076         *
077         *  @return The value of <code>cost</code>.
078         */
079        public RelativeTime getCost() {
080            return new RelativeTime(cost);
081        }
082    
083        /** Get the cost overrun handler.
084         *
085         *  @return A reference to an instance of <code>AsyncEventHandler</code>
086         *          that is cost overrun handler of <code>this</code>.
087         */
088        public AsyncEventHandler getCostOverrunHandler() {
089            return overrunHandler;
090        }
091    
092        /** Gets the value of <code>deadline</code>.
093         *
094         *  @return A reference to an instance of <code>RelativeTime</code> that
095         *          is the deadline of <code>this</code>.
096         */
097        public RelativeTime getDeadline() {
098            return new RelativeTime(deadline);
099        }
100    
101        /** Gets the deadline missed handler.
102         *
103         *  @return A reference to an instance of <code>AsynchEventHandler</code>
104         *          that is deadline miss handler of <code>this</code>.
105         */
106        public AsyncEventHandler getDeadlineMissHandler() {
107            return missHandler;
108        }
109    
110        /** Gets the value of <code>period</code>.
111         *
112         *  @return A reference of an instance of <code>RelativeTime</code> that
113         *          represents the value of <code>period</code>.
114         */
115        public RelativeTime getPeriod() {
116            return new RelativeTime(period);
117        }
118    
119        /** Gets the value of <code>start</code>.
120         *
121         *  @return A reference to an instance of <code>HighResolutionTime</code>
122         *          that represents the value of <code>start</code>.
123         */
124        public HighResolutionTime getStart() {
125            return start;
126        }
127    
128        /** Sets the value of <code>cost</code>.
129         *
130         *  @param cost The new value for <code>cost</code>.
131         */
132        public void setCost(RelativeTime cost) {
133            this.cost = cost;
134        }
135    
136        /** Sets the cost overrun handler.
137         *
138         *  @param handler This handler is invoked if the <code>run()</code>
139         *                 method of any of the schedulable objects attempt to
140         *                 execute for more than <code>cost</code> time units
141         *                 in any period.
142         */
143        public void setCostOverrunHandler(AsyncEventHandler handler) {
144            overrunHandler = handler;
145        }
146    
147        /** Sets the value of <code>deadline</code>.
148         *
149         *  @param deadline The new value for <code>deadline</code>.
150         */
151        public void setDeadline(RelativeTime deadline) {
152            this.deadline = deadline;
153        }
154    
155        /** Sets the deadline miss handler.
156         *
157         *  @param handler This handler is invoked if the <code>run()</code>
158         *                 method of any of the schedulable objects still
159         *                 expect to execute after the deadline has passed.
160         */
161        public void setDeadlineMissHandler(AsyncEventHandler handler) {
162            missHandler = handler;
163        }
164    
165        /** Sets the value of <code>period</code>.
166         *
167         *  @param period The new value for <code>period</code>.
168         */
169        public void setPeriod(RelativeTime period) {
170            this.period = period;
171        }
172    
173        /** Sets the value of <code>start</code>.
174         *
175         *  @param start The new value for <code>start</code>.
176         */
177        public void setStart(HighResolutionTime start) {
178            this.start = start;
179        }
180    
181        /** This method appears in many classes in the RTSJ and with various parameters.
182         *  The parameters are either new scheduling characteristics for an instance
183         *  <code>Schedulable</code> or an instance of <code>Schedulable</code>. The
184         *  method first performs a feasibility analysis using the new scheudling
185         *  characteristics as replacements for the matching scheduling characteristics
186         *  of either <code>this</code> or the given instance of <code>Schedulable</code>
187         *  as appropriate, with the new scheduling characteristics.
188         *
189         *  @param period The proposed period.
190         *  @param cost The proposed cost.
191         *  @param deadline The proposed deadline.
192         *  @return True, if the resulting system is feasible and the changes are made.
193         *          False, if the resulting system is not feasible and no changes are made.
194         */
195        public boolean setIfFeasible(RelativeTime period,
196                                     RelativeTime cost,
197                                     RelativeTime deadline) {
198            boolean b = true;
199            for (Iterator it = schList.iterator(); it.hasNext(); ) {
200                Schedulable sch = (Schedulable)it.next();
201                Scheduler sched = sch.getScheduler();
202                if (!sched.isFeasible(sch, new PeriodicParameters(getStart(), period, cost, deadline,
203                                                                  overrunHandler, missHandler))) {
204                    b = false;
205                    break;
206                }
207            }
208    
209            if (b) {
210                setPeriod(period);
211                setCost(cost);
212                setDeadline(deadline);
213            }
214            return b;
215    
216    //      boolean b = true;
217    //      Iterator it = schList.iterator();
218    //      RelativeTime old_period = this.period;
219    //      RelativeTime old_cost = this.cost;
220    //      RelativeTime old_deadline = this.deadline;
221    //      setPeriod(period);
222    //      setCost(cost);
223    //      setDeadline(deadline);
224    //      while (b && it.hasNext())
225    //          b = ((Schedulable)it.next()).setProcessingGroupParametersIfFeasible(this);
226    //      if (!b) {   // something is not feasible
227    //          setPeriod(old_period);   // returning the values back
228    //          setCost(old_cost);
229    //          setDeadline(old_deadline);
230    //          for (it = schList.iterator(); it.hasNext(); )   // undoing all changes
231    //              ((Schedulable)it.next()).setProcessingGroupParameters(this);
232    //      }
233    //      return b;
234        }
235    
236        /** Informs <code>this</code> that there is one more instance of <code>Schedulable</code>
237         *  that uses <code>this</code> as its <code>ReleaseParameters</code>.
238         */
239        public boolean bindSchedulable(Schedulable sch) {
240            return schList.add(sch);
241        }
242    
243        /** Informs <code>this</code> that <code>Schedulable sch</code>
244         *  that uses <code>this</code> as its <code>ReleaseParameters</code>.
245         */
246        public boolean unbindSchedulable(Schedulable sch) {
247            return schList.remove(sch);
248        }
249    }