001 // RelativeTime.java, created by cata 002 // Copyright (C) 2001 Catalin Francu <cata@mit.edu> 003 // taking over Bryan Fink's code 004 // Licensed under the terms of the GNU GPL; see COPYING for details. 005 006 // Class Invariant: 007 // - Times are consistent at any time. That is, 0<=nanos<1000000. If not, 008 // we normalize them, e.g 3ms 3200000ns --> 6ms 200000ns 009 010 package javax.realtime; 011 import java.lang.Math; 012 013 /** Class <code>HighResolutiontime</code> is the base class for 014 * <code>AbsoluteTime, RelativeTime, RationalTime</code>. 015 */ 016 public abstract class HighResolutionTime implements Comparable { 017 018 private long millis; 019 private int nanos; 020 static protected Clock defaultClock = Clock.getRealtimeClock(); 021 022 /** Convert the time of <code>this</code> to an absolute time, relative to 023 * the given instance of <code>Clock</code>. Convenient for situations 024 * where you really need an absolute time. Aloocates a destination object 025 * if necessary. 026 * 027 * @param clock An instance of <code>Clock</code> is used to convert the 028 * time of <code>this</code> into absolute time. 029 */ 030 public abstract AbsoluteTime absolute(Clock clock); 031 032 /** Convert the time of <code>this</code> to an absolute time, relative to 033 * the given instance of <code>Clock</code>. Convenient for situations 034 * where you really need an absolute time. Aloocates a destination object 035 * if necessary. 036 * 037 * @param clock An instance of <code>Clock</code> is used to convert the 038 * time of <code>this</code> into absolute time. 039 * @param dest If null, a new object is created and returned as result, 040 * else <code>dest</code> is returned. 041 */ 042 public abstract AbsoluteTime absolute(Clock c, AbsoluteTime dest); 043 044 /** Compares this <code>HighResolutionTime</code> with the specified 045 * <code>HighResolutionTime</code>. 046 * 047 * @param time Compares with the time of <code>this</code>. 048 */ 049 public int compareTo(HighResolutionTime b) { 050 if (millis > b.getMilliseconds()) 051 return 1; 052 053 if (millis < b.getMilliseconds()) 054 return -1; 055 056 if (nanos > b.getNanoseconds()) 057 return 1; 058 059 if (nanos < b.getNanoseconds()) 060 return -1; 061 062 return 0; 063 } 064 065 /** Compares this <code>HighResolutionTime</code> with the specified 066 * <code>HighResolutionTime</code>. 067 */ 068 public int compareTo(Object b) { 069 return compareTo((HighResolutionTime) b); 070 } 071 072 /** Returns true if the argument object has the same values as this. */ 073 public boolean equals(HighResolutionTime b) { 074 return (millis == b.getMilliseconds() && 075 nanos == b.getNanoseconds()); 076 } 077 078 /** Returns true if the argument object has the same values as <code>this<code>. 079 * 080 * @param b Value compared to <code>this</code>. 081 */ 082 public boolean equals(Object b) { 083 return equals((HighResolutionTime) b); 084 } 085 086 /** Returns the milliseconds component of <code>this</code>. 087 * 088 * @return The milliseconds component of the time past the epoch 089 * represented by <code>this</code>. 090 */ 091 public final long getMilliseconds() { 092 return millis; 093 } 094 095 /** Returns the nanoseconds component of <code>this</code>. */ 096 public final int getNanoseconds() { 097 return nanos; 098 } 099 100 public int hashCode() { 101 return (int)(nanos+millis*1000000); 102 } 103 104 /** Convert the time of <code>this</code> to a relative time, with 105 * respect to the given instance of <code>Clock</code>. Convenient 106 * for situations where you really need a relative time. Allocates 107 * a destination object if necessary. 108 * 109 * @param clock An instance of <code>Clock</code> is used to convert 110 * the time of <code>this</code> into realtive time. 111 */ 112 public abstract RelativeTime relative(Clock clock); 113 114 /** Convert the time of <code>this</code> to a relative time, with 115 * respect to the given instance of <code>Clock</code>. Convenient 116 * for situations where you really need a relative time. Allocates 117 * a destination object if necessary. 118 * 119 * @param clock An instance of <code>Clock</code> is used to convert 120 * the time of <code>this</code> into realtive time. 121 * @param time If null, a new object is created and returned as result, 122 * else <code>time</code> is returned. 123 */ 124 public abstract RelativeTime relative(Clock clock, 125 HighResolutionTime time); 126 127 /** Change the value represented by <code>this</code> to that of the given 128 * time. If the type of <code>this</code> and the type of the given time 129 * are not the same this method will throw IllegalArgumentException. 130 * 131 * @param t The new value for <code>this</code>. 132 */ 133 public void set(HighResolutionTime t) { 134 millis = t.getMilliseconds(); 135 nanos = t.getNanoseconds(); 136 } 137 138 /** Sets the millisecond component of <code>this</code> to the given argument. 139 * 140 * @param millis This value will be the value of the milliseconds component 141 * of <code>this</code> at the completion of the call. If 142 * <code>millis</code> is negative the millisecond value of 143 * <code>this</code> is set to negative value. Although 144 * logically this may represent time before the epoch, invalid 145 * results may occur if a <code>HighResolutionTime</code> 146 * representing time before the epoch is given as a parameter 147 * to the method. 148 */ 149 public void set(long millisecs) { 150 millis = millisecs; 151 nanos = 0; 152 } 153 154 /** Sets the millisecond and nanosecond compenonets of <code>this</code>. 155 * 156 * @param millis Value to set millisecond part of <code>this</code>. If 157 * <code>millis</code> is negative the millisecond value 158 * of <code>this</code> is set to negative value. Although 159 * logically this may represent time before the epoch, 160 * invalid results may occur if a <code>HighResolutionTime</code> 161 * representing time before the epoch is given as a parameter 162 * to the method. 163 * @param nanos Value to set nanosecond part of <code>this</code>. If 164 * <code>nanos</code> is negative, the nanosecond valur of 165 * <code>this</code> is set to negative value. Although 166 * logically this may represent time before the epoch, invalid 167 * results may occur if a <code>HighResolutionTime</code> 168 * representing time before the epoch is given as a paramter 169 * to the method. 170 */ 171 public void set(long millisecs, int nanosecs) { 172 // Do we have negative nanos? Java cannot take negative moduli properly 173 if (nanosecs < 0) { 174 nanos = Math.abs(nanosecs); 175 millis = millisecs - nanos/1000000; 176 nanos %= 1000000; 177 if (nanos > 0) { 178 millis--; 179 nanos = 1000000 - nanos; 180 } 181 } 182 else { 183 millis = millisecs + nanosecs/1000000; 184 nanos = nanosecs%1000000; 185 } 186 } 187 188 /** Behaves exactly like <code>target.wait()</code> but with the enhacement 189 * that it waits with a precision of <code>HighResolutionTime</code>. 190 * 191 * @param target The object on which to wait. The current thread must have 192 * a lock on the object. 193 * @param time The time for which to wait. If this is 194 * <code>RelativeTime(0, 0)</code> then wait indefinetly. 195 * @throws java.lang.InterruptedException If another thread interrupts this 196 * thread while it is waiting. 197 */ 198 public static void waitForObject(Object target, HighResolutionTime time) 199 throws InterruptedException { 200 target.wait(time.getMilliseconds(), time.getNanoseconds()); 201 } 202 203 /** Returns <code>millis * 1000000 + nanos</code>. */ 204 public long time() { 205 return (millis * 1000000 + nanos); 206 } 207 }