001 package javax.realtime; 002 003 /** An object that represents a time interval millis/1E3+nanos/1E9 004 * seconds long that is divided into subintervals by some frequency. 005 * This is generally used in periodic events, threads, and 006 * feasibility analysis to specify periods where there is a basic 007 * period that must be adhered to strictly (the interval), but 008 * within that interval the periodic events are supposed to happen 009 * <code>frequency</code> times, as u niformly spaced as possible, 010 * but clock and scheduling jitter is moderately acceptable. 011 * <p> 012 * If the value of any of the millisecond or nanosecond fields is 013 * negative the variable is set to negative value. Although logically 014 * this may represent time before the epoch, invalid results may 015 * occur if an instance of <code>AbsoluteTime</code> representing 016 * time before the epoch is given as a parameter to a method. 017 * <p> 018 * <b>Caution:</b> This class is explicitly unsafe in multithreaded 019 * situations when it is being changed. No synchronization is done. It 020 * is assumed that users of this class who are mutating instances will 021 * be doing their own synchronization at a higher level. 022 */ 023 public class RationalTime extends RelativeTime { 024 025 private int frequency; 026 027 /** Constructs an instance of <code>RationalTime</code>. Equivalent to 028 * <code>new RationalTime(frequency, 1000, 0)</code> -- essentially a 029 * cycle-per-seconds value. 030 * 031 * @param frequency The frequency value. 032 */ 033 public RationalTime(int frequency) { 034 // I think they messed up the order of the parameters in the spec. 035 this(frequency, 1000, 0); 036 } 037 038 /** Constructs an instance of <code>RationalTime</code>. All arguments 039 * must be greater than or equal to zero. 040 * 041 * @param frequency The frequency value. 042 * @param millis The milliseconds value. 043 * @param nanos The nanoseconds value. 044 * @throws java.lang.IllegalArgumentException If any of the argument values 045 * are less than zero. 046 */ 047 public RationalTime(int frequency, long millis, int nanos) 048 throws IllegalArgumentException { 049 super(millis, nanos); 050 this.frequency = frequency; 051 } 052 053 /** Constructs an instance of <code>RationalTime</code> from the given 054 * <code>RelativeTime</code>. 055 * 056 * @param frequency The frequency value. 057 * @param interval The given instance of <code>RelativeTime</code>. 058 * @throws java.lang.IllegalArgumentException If any of the argument values 059 * are less than zero. 060 */ 061 public RationalTime(int frequency, RelativeTime interval) 062 throws IllegalArgumentException { 063 this(frequency, interval.getMilliseconds(), 064 interval.getNanoseconds()); 065 } 066 067 /** Convert this time to an absolute time. 068 * 069 * @param clock The reference clock. If null, <code>Clock.getRealTimeClock()</code> 070 * is used. 071 * @param destination A reference to the destination istance. 072 */ 073 public AbsoluteTime absolute(Clock clock, AbsoluteTime destination) { 074 if (destination == null) 075 destination = new AbsoluteTime(); 076 if (clock == null) 077 clock = Clock.getRealtimeClock(); 078 079 destination.set(clock.getTime().add(this)); 080 return destination; 081 } 082 083 /** Add this time to an <code>AbsoluteTime</code>. It is almost the same as 084 * <code>destination.add(this, destination)</code> except that it accounts 085 * for (ie. divides by) the frequency. 086 */ 087 public void addInterarrivalTo(AbsoluteTime destination) { 088 destination.add(this, destination); 089 } 090 091 /** Gets the value of <code>frequency</code>. 092 * 093 * @return The value of <code>frequency</code> as an integer. 094 */ 095 public int getFrequency() { 096 return frequency; 097 } 098 099 /** Gets the interarrival time. This time is 100 * <code>(milliseconds/10^3 + nanoseconds/10^9)/frequency<code> rounded 101 * down to the nearest expressible value of the fields and their types 102 * of <code>RelativeTime</code>. 103 */ 104 public RelativeTime getInterarrivalTime() { 105 RelativeTime temp = new RelativeTime(); 106 long t = Math.round((1000000 * getMilliseconds() + getNanoseconds()) / 107 getFrequency()); 108 temp.set(t / 1000000, (int) (t % 1000000)); 109 return temp; 110 } 111 112 /** Gets the interarrival time. This time is 113 * <code>(milliseconds/10^3 + nanoseconds/10^9)/frequency<code> rounded 114 * down to the nearest expressible value of the fields and their types 115 * of <code>RelativeTime</code>. 116 * 117 * @param dest Result is stored in <code>dest</code> and returned; if null, 118 * a new object is returned. 119 */ 120 public RelativeTime getInterarrivalTime(RelativeTime dest) { 121 if (dest == null) dest = new RelativeTime(); 122 long t = Math.round((1000000 * getMilliseconds() + getNanoseconds()) / 123 getFrequency()); 124 dest.set(t / 1000000, (int) (t % 1000000)); 125 return dest; 126 } 127 128 /** Sets the indicated fields to the given values. 129 * 130 * @param millis The new value for the millisecond field. 131 * @param nanos The new value for the nanosecond field. 132 * @throws java.lang.IllegalArgumentException 133 */ 134 public void set(long millis, int nanos) 135 throws IllegalArgumentException { 136 super.set(millis, nanos); 137 } 138 139 /** Sets the value of the <code>frequency</code> field. 140 * 141 * @param frequency The new value for the <code>frequency</code>. 142 * @throws java.lang.ArithmeticException 143 */ 144 public void setFrequency(int frequency) throws ArithmeticException { 145 this.frequency = frequency; 146 } 147 }