001 // PeriodicParameters.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.Date; 008 import java.util.LinkedList; 009 import java.util.Iterator; 010 011 /** This release parameter indicates that the <code>waitForNextPeriod()</code> 012 * method on the associated <code>Schedulable</code> object will be unblocked 013 * at the start of each period. When a reference to a 014 * <code>PeriodicParameters</code> object is given as a parameter to a 015 * constructor, the <code>PeriodicParameters</code> object becomes bound to 016 * the object being created. Changes to the values in the 017 * <code>PeriodicParameters</code> object affect the constructed object. If 018 * given to more than one constructor then changes to the values in the 019 * <code>PeriodicParameters</code> object affect <i>all</i> the associated objects. 020 * Note that this is a one-to-many relationship, <i>not</i> many-to-many. 021 * <p> 022 * <b>Caution:</b> This class is explicitly unsafe in multithreaded situations 023 * when it is being changed. No synchronizations is done. It is assumed that users 024 * of this class who are mutating instances will be doing their own synchronization 025 * at a higher level. 026 */ 027 public class PeriodicParameters extends ReleaseParameters { 028 029 HighResolutionTime start; 030 RelativeTime period; 031 LinkedList schList = new LinkedList(); 032 033 /** Create a <code>PeriodicParameters</code> object. 034 * 035 * @param start Time at which the first period begins. If a 036 * <code>RelativeTime</code>, this time is relative to the 037 * first time the schedulable object becomes schedulable 038 * (<i>schedulable time</i>) (e.g., when <code>start()</code> 039 * is called on a thread). If an <code>AbsoluteTime</code> 040 * and it is before the schedulable time, start is equivalent 041 * to the schedulable time. 042 * @param period The period is the interval between successive unblocks 043 * of <code>RealtimeThread.waitForNextPeriod()</code>. Must 044 * be greater than zero when entering feasibility analysis. 045 * @param cost Processing time per period. On implementations which can 046 * measure the amount of time a schedulable object is executed, 047 * this value is the maximum amount of time a schedulable object 048 * receives per period. On implementations which cannot measure 049 * execution time, this value is used as a hint to the feasibility 050 * algorithm. On such systems it is not possible to determine when 051 * any particular object exceeds or will exceed cost time units in 052 * a period. Equivalent to <code>RelativeTime(0, 0)</code> if null. 053 * @param deadline The latest permissible completion time measured from the 054 * release time of the associated invocation of the schedulable 055 * object. For a minimum implementation for purposes of 056 * feasibility analysis, the deadline is equal to the period. 057 * Other implementations may use this parameter to compute 058 * execution eligibility. If null, deadline will equal the period. 059 * @param overrunHandler This handler is invoked if an invocation of the 060 * schedulable object exceeds cost in the given period. 061 * Not required for minimum implementation. If null, 062 * nothing happens on the overrun condition. 063 * @param missHandler This handler is invoked if the <code>run()</code> method of 064 * the schedulable object is still executing after the deadline 065 * has passed. Although minimum implementations do not consider 066 * deadlines in feasibility calculations, they must recognize 067 * variable deadlines and invoke the miss handler as appropriate. 068 * If null, nothing happens on the miss deadline condition. 069 */ 070 public PeriodicParameters(HighResolutionTime start, RelativeTime period, 071 RelativeTime cost, RelativeTime deadline, 072 AsyncEventHandler overrunHandler, 073 AsyncEventHandler missHandler) { 074 super(cost, (deadline == null) ? period : deadline, 075 overrunHandler, missHandler); 076 077 // For now, we leave start as it is. When start() is called on a thread, 078 // then we will set start accordingly. The problem is what do we do when 079 // several threads share the same ReleaseParameters. 080 this.start = start; 081 this.period = new RelativeTime(period); 082 } 083 084 /** Gets the period. 085 * 086 * @return The current value in <code>period</code>. 087 */ 088 public RelativeTime getPeriod() { 089 return period; 090 } 091 092 /** Gets the start time. 093 * 094 * @return The current value in <code>start</code>. 095 */ 096 public HighResolutionTime getStart() { 097 return start; 098 } 099 100 /** This method appears in many classes in the RTSJ and with various parameters. 101 * The parameters are either new scheduling characteristics for an instance 102 * <code>Schedulable</code> or an instance of <code>Schedulable</code>. The 103 * method first performs a feasibility analysis using the new scheduling 104 * characteristics as replacements for the matching scheduling characteristics 105 * of either <code>this</code> or the given instance of <code>Schedulable</code>. 106 * If the resulting system is feasible the method replaces the current scheduling 107 * characteristics, of either <code>this</code> or the given instance of 108 * <code>Schedulable</code> as appropriate, with the new scheduling characteristics. 109 * 110 * @param period The proposed period. 111 * @param cost The proposed cost. 112 * @param deadline The proposed deadline. 113 * @return True, if the resulting system is feasible and the changes are made. 114 * False, if the resulting system is not feasible and no changes are made. 115 */ 116 public boolean setIfFeasible(RelativeTime period, 117 RelativeTime cost, 118 RelativeTime deadline) { 119 boolean b = true; 120 for (Iterator it = schList.iterator(); it.hasNext(); ) { 121 Schedulable sch = (Schedulable)it.next(); 122 Scheduler sched = sch.getScheduler(); 123 if (!sched.isFeasible(sch, new PeriodicParameters(getStart(), period, cost, deadline, 124 overrunHandler, missHandler))) { 125 b = false; 126 break; 127 } 128 } 129 130 if (b) { 131 setPeriod(period); 132 setCost(cost); 133 setDeadline(deadline); 134 } 135 return b; 136 } 137 138 /** Sets the period. 139 * 140 * @param period The value to which <code>period</code> is set. 141 */ 142 public void setPeriod(RelativeTime period) { 143 this.period.set(period); 144 } 145 146 /** Sets the start time. 147 * 148 * @param start The value to which <code>start</code> is set. 149 */ 150 public void setStart(HighResolutionTime start) { 151 this.start.set(start); 152 } 153 154 /** Informs <code>this</code> that there is one more instance of <code>Schedulable</code> 155 * that uses <code>this</code> as its <code>ReleaseParameters</code>. 156 */ 157 public boolean bindSchedulable(Schedulable sch) { 158 return schList.add(sch); 159 } 160 161 /** Informs <code>this</code> that <code>Schedulable sch</code> 162 * that uses <code>this</code> as its <code>ReleaseParameters</code>. 163 */ 164 public boolean unbindSchedulable(Schedulable sch) { 165 return schList.remove(sch); 166 } 167 }