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    }