1 /* 2 * Copyright (c) 1982, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)time.h 8.5 (Berkeley) 5/4/95 34 * $FreeBSD: src/sys/sys/time.h,v 1.42 1999/12/29 04:24:48 peter Exp $ 35 */ 36 37 #ifndef _SYS_TIME_H_ 38 #define _SYS_TIME_H_ 39 40 #include <sys/types.h> 41 42 /* 43 * Structure returned by gettimeofday(2) system call, 44 * and used in other calls. 45 */ 46 struct timeval { 47 long tv_sec; /* seconds */ 48 long tv_usec; /* and microseconds */ 49 }; 50 51 #ifndef _TIMESPEC_DECLARED 52 #define _TIMESPEC_DECLARED 53 struct timespec { 54 time_t tv_sec; /* seconds */ 55 long tv_nsec; /* and nanoseconds */ 56 }; 57 #endif 58 59 #define TIMEVAL_TO_TIMESPEC(tv, ts) \ 60 do { \ 61 (ts)->tv_sec = (tv)->tv_sec; \ 62 (ts)->tv_nsec = (tv)->tv_usec * 1000; \ 63 } while (0) 64 #define TIMESPEC_TO_TIMEVAL(tv, ts) \ 65 do { \ 66 (tv)->tv_sec = (ts)->tv_sec; \ 67 (tv)->tv_usec = (ts)->tv_nsec / 1000; \ 68 } while (0) 69 70 struct timezone { 71 int tz_minuteswest; /* minutes west of Greenwich */ 72 int tz_dsttime; /* type of dst correction */ 73 }; 74 #define DST_NONE 0 /* not on dst */ 75 #define DST_USA 1 /* USA style dst */ 76 #define DST_AUST 2 /* Australian style dst */ 77 #define DST_WET 3 /* Western European dst */ 78 #define DST_MET 4 /* Middle European dst */ 79 #define DST_EET 5 /* Eastern European dst */ 80 #define DST_CAN 6 /* Canada */ 81 82 /* 83 * Structure used to interface to the machine dependent hardware support 84 * for timekeeping. 85 * 86 * A timecounter is a (hard or soft) binary counter which has two properties: 87 * * it runs at a fixed, known frequency. 88 * * it must not roll over in less than (1 + delta)/HZ seconds. "delta" 89 * is expected to be less than 20 msec, but no hard data has been 90 * collected on this. 16 bit at 5 MHz (31 msec) is known to work. 91 * 92 * get_timecount() reads the counter. 93 * 94 * counter_mask removes unimplemented bits from the count value. 95 * 96 * frequency is the counter frequency in hz. 97 * 98 * name is a short mnemonic name for this counter. 99 * 100 * cost is a measure of how long time it takes to read the counter. 101 * 102 * adjustment [PPM << 16] which means that the smallest unit of correction 103 * you can apply amounts to 481.5 usec/year. 104 * 105 * scale_micro [2^32 * usec/tick]. 106 * scale_nano_i [ns/tick]. 107 * scale_nano_f [(ns/2^32)/tick]. 108 * 109 * offset_count is the contents of the counter which corresponds to the 110 * rest of the offset_* values. 111 * 112 * offset_sec [s]. 113 * offset_micro [usec]. 114 * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365... 115 * attoseconds (10E-18) and before you ask: yes, they are in fact 116 * called attoseconds, it comes from "atten" for 18 in Danish/Swedish. 117 * 118 * Each timecounter must supply an array of three timecounters, this is needed 119 * to guarantee atomicity in the code. Index zero is used to transport 120 * modifications, for instance done with sysctl, into the timecounter being 121 * used in a safe way. Such changes may be adopted with a delay of up to 1/HZ, 122 * index one & two are used alternately for the actual timekeeping. 123 * 124 * 'tc_avail' points to the next available (external) timecounter in a 125 * circular queue. This is only valid for index 0. 126 * 127 * `tc_other' points to the next "work" timecounter in a circular queue, 128 * i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER. 129 * We also use it to point from index 0 to index 1. 130 * 131 * `tc_tweak' points to index 0. 132 */ 133 134 struct timecounter; 135 typedef unsigned timecounter_get_t __P((struct timecounter *)); 136 typedef void timecounter_pps_t __P((struct timecounter *)); 137 138 struct timecounter { 139 /* These fields must be initialized by the driver. */ 140 timecounter_get_t *tc_get_timecount; 141 timecounter_pps_t *tc_poll_pps; 142 unsigned tc_counter_mask; 143 u_int32_t tc_frequency; 144 char *tc_name; 145 void *tc_priv; 146 /* These fields will be managed by the generic code. */ 147 int64_t tc_adjustment; 148 u_int32_t tc_scale_micro; 149 u_int32_t tc_scale_nano_i; 150 u_int32_t tc_scale_nano_f; 151 unsigned tc_offset_count; 152 u_int32_t tc_offset_sec; 153 u_int32_t tc_offset_micro; 154 u_int64_t tc_offset_nano; 155 struct timeval tc_microtime; 156 struct timespec tc_nanotime; 157 struct timecounter *tc_avail; 158 struct timecounter *tc_other; 159 struct timecounter *tc_tweak; 160 }; 161 162 #ifdef _KERNEL 163 164 /* Operations on timespecs */ 165 #define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) 166 #define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) 167 #define timespeccmp(tvp, uvp, cmp) \ 168 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 169 ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ 170 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 171 #define timespecadd(vvp, uvp) \ 172 do { \ 173 (vvp)->tv_sec += (uvp)->tv_sec; \ 174 (vvp)->tv_nsec += (uvp)->tv_nsec; \ 175 if ((vvp)->tv_nsec >= 1000000000) { \ 176 (vvp)->tv_sec++; \ 177 (vvp)->tv_nsec -= 1000000000; \ 178 } \ 179 } while (0) 180 #define timespecsub(vvp, uvp) \ 181 do { \ 182 (vvp)->tv_sec -= (uvp)->tv_sec; \ 183 (vvp)->tv_nsec -= (uvp)->tv_nsec; \ 184 if ((vvp)->tv_nsec < 0) { \ 185 (vvp)->tv_sec--; \ 186 (vvp)->tv_nsec += 1000000000; \ 187 } \ 188 } while (0) 189 190 /* Operations on timevals. */ 191 192 #define timevalclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 193 #define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) 194 #define timevalcmp(tvp, uvp, cmp) \ 195 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 196 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 197 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 198 199 /* timevaladd and timevalsub are not inlined */ 200 201 #endif /* _KERNEL */ 202 203 #ifndef _KERNEL /* NetBSD/OpenBSD compatable interfaces */ 204 205 #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 206 #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) 207 #define timercmp(tvp, uvp, cmp) \ 208 (((tvp)->tv_sec == (uvp)->tv_sec) ? \ 209 ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ 210 ((tvp)->tv_sec cmp (uvp)->tv_sec)) 211 #define timeradd(tvp, uvp, vvp) \ 212 do { \ 213 (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 214 (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 215 if ((vvp)->tv_usec >= 1000000) { \ 216 (vvp)->tv_sec++; \ 217 (vvp)->tv_usec -= 1000000; \ 218 } \ 219 } while (0) 220 #define timersub(tvp, uvp, vvp) \ 221 do { \ 222 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 223 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 224 if ((vvp)->tv_usec < 0) { \ 225 (vvp)->tv_sec--; \ 226 (vvp)->tv_usec += 1000000; \ 227 } \ 228 } while (0) 229 #endif 230 231 /* 232 * Names of the interval timers, and structure 233 * defining a timer setting. 234 */ 235 #define ITIMER_REAL 0 236 #define ITIMER_VIRTUAL 1 237 #define ITIMER_PROF 2 238 239 struct itimerval { 240 struct timeval it_interval; /* timer interval */ 241 struct timeval it_value; /* current value */ 242 }; 243 244 /* 245 * Getkerninfo clock information structure 246 */ 247 struct clockinfo { 248 int hz; /* clock frequency */ 249 int tick; /* micro-seconds per hz tick */ 250 int tickadj; /* clock skew rate for adjtime() */ 251 int stathz; /* statistics clock frequency */ 252 int profhz; /* profiling clock frequency */ 253 }; 254 255 /* CLOCK_REALTIME and TIMER_ABSTIME are supposed to be in time.h */ 256 257 #ifndef CLOCK_REALTIME 258 #define CLOCK_REALTIME 0 259 #endif 260 #define CLOCK_VIRTUAL 1 261 #define CLOCK_PROF 2 262 263 #define TIMER_RELTIME 0x0 /* relative timer */ 264 #ifndef TIMER_ABSTIME 265 #define TIMER_ABSTIME 0x1 /* absolute timer */ 266 #endif 267 268 #ifdef _KERNEL 269 extern struct timecounter *timecounter; 270 extern time_t time_second; 271 272 void getmicrouptime __P((struct timeval *tv)); 273 void getmicrotime __P((struct timeval *tv)); 274 void getnanouptime __P((struct timespec *tv)); 275 void getnanotime __P((struct timespec *tv)); 276 void init_timecounter __P((struct timecounter *tc)); 277 int itimerdecr __P((struct itimerval *itp, int usec)); 278 int itimerfix __P((struct timeval *tv)); 279 void microuptime __P((struct timeval *tv)); 280 void microtime __P((struct timeval *tv)); 281 void nanouptime __P((struct timespec *ts)); 282 void nanotime __P((struct timespec *ts)); 283 void set_timecounter __P((struct timespec *ts)); 284 void timevaladd __P((struct timeval *, struct timeval *)); 285 void timevalsub __P((struct timeval *, struct timeval *)); 286 int tvtohz __P((struct timeval *)); 287 void update_timecounter __P((struct timecounter *tc)); 288 #else /* !_KERNEL */ 289 #include <time.h> 290 291 #include <sys/cdefs.h> 292 293 __BEGIN_DECLS 294 int adjtime __P((const struct timeval *, struct timeval *)); 295 int futimes __P((int, const struct timeval *)); 296 int getitimer __P((int, struct itimerval *)); 297 int gettimeofday __P((struct timeval *, struct timezone *)); 298 int lutimes __P((const char *, const struct timeval *)); 299 int setitimer __P((int, const struct itimerval *, struct itimerval *)); 300 int settimeofday __P((const struct timeval *, const struct timezone *)); 301 int utimes __P((const char *, const struct timeval *)); 302 __END_DECLS 303 304 #endif /* !_KERNEL */ 305 306 #endif /* !_SYS_TIME_H_ */ 307