Rev 4921 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* time.h -- An implementation of the standard Unix |
2 | Written by Geoffrey Noer |
||
3 | Public domain; no rights reserved. */ |
||
4 | |||
6099 | serge | 5 | /*- |
6 | * Copyright (c) 1982, 1986, 1993 |
||
7 | * The Regents of the University of California. All rights reserved. |
||
8 | * |
||
9 | * Redistribution and use in source and binary forms, with or without |
||
10 | * modification, are permitted provided that the following conditions |
||
11 | * are met: |
||
12 | * 1. Redistributions of source code must retain the above copyright |
||
13 | * notice, this list of conditions and the following disclaimer. |
||
14 | * 2. Redistributions in binary form must reproduce the above copyright |
||
15 | * notice, this list of conditions and the following disclaimer in the |
||
16 | * documentation and/or other materials provided with the distribution. |
||
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$ |
||
35 | */ |
||
36 | |||
4349 | Serge | 37 | #ifndef _SYS_TIME_H_ |
6099 | serge | 38 | #define _SYS_TIME_H_ |
4349 | Serge | 39 | |
40 | #include <_ansi.h> |
||
6099 | serge | 41 | #include |
42 | #include |
||
4349 | Serge | 43 | #include |
6099 | serge | 44 | #include |
4349 | Serge | 45 | |
6099 | serge | 46 | #if __BSD_VISIBLE |
47 | #include |
||
4349 | Serge | 48 | #endif |
49 | |||
6099 | serge | 50 | struct timezone { |
51 | int tz_minuteswest; /* minutes west of Greenwich */ |
||
52 | int tz_dsttime; /* type of dst correction */ |
||
4349 | Serge | 53 | }; |
6099 | serge | 54 | #define DST_NONE 0 /* not on dst */ |
55 | #define DST_USA 1 /* USA style dst */ |
||
56 | #define DST_AUST 2 /* Australian style dst */ |
||
57 | #define DST_WET 3 /* Western European dst */ |
||
58 | #define DST_MET 4 /* Middle European dst */ |
||
59 | #define DST_EET 5 /* Eastern European dst */ |
||
60 | #define DST_CAN 6 /* Canada */ |
||
4349 | Serge | 61 | |
6099 | serge | 62 | #if __BSD_VISIBLE |
63 | struct bintime { |
||
64 | time_t sec; |
||
65 | uint64_t frac; |
||
66 | }; |
||
4349 | Serge | 67 | |
6099 | serge | 68 | static __inline void |
69 | bintime_addx(struct bintime *_bt, uint64_t _x) |
||
70 | { |
||
71 | uint64_t _u; |
||
4349 | Serge | 72 | |
6099 | serge | 73 | _u = _bt->frac; |
74 | _bt->frac += _x; |
||
75 | if (_u > _bt->frac) |
||
76 | _bt->sec++; |
||
77 | } |
||
4921 | Serge | 78 | |
6099 | serge | 79 | static __inline void |
80 | bintime_add(struct bintime *_bt, const struct bintime *_bt2) |
||
81 | { |
||
82 | uint64_t _u; |
||
4921 | Serge | 83 | |
6099 | serge | 84 | _u = _bt->frac; |
85 | _bt->frac += _bt2->frac; |
||
86 | if (_u > _bt->frac) |
||
87 | _bt->sec++; |
||
88 | _bt->sec += _bt2->sec; |
||
89 | } |
||
4921 | Serge | 90 | |
6099 | serge | 91 | static __inline void |
92 | bintime_sub(struct bintime *_bt, const struct bintime *_bt2) |
||
93 | { |
||
94 | uint64_t _u; |
||
95 | |||
96 | _u = _bt->frac; |
||
97 | _bt->frac -= _bt2->frac; |
||
98 | if (_u < _bt->frac) |
||
99 | _bt->sec--; |
||
100 | _bt->sec -= _bt2->sec; |
||
101 | } |
||
102 | |||
103 | static __inline void |
||
104 | bintime_mul(struct bintime *_bt, u_int _x) |
||
105 | { |
||
106 | uint64_t _p1, _p2; |
||
107 | |||
108 | _p1 = (_bt->frac & 0xffffffffull) * _x; |
||
109 | _p2 = (_bt->frac >> 32) * _x + (_p1 >> 32); |
||
110 | _bt->sec *= _x; |
||
111 | _bt->sec += (_p2 >> 32); |
||
112 | _bt->frac = (_p2 << 32) | (_p1 & 0xffffffffull); |
||
113 | } |
||
114 | |||
115 | static __inline void |
||
116 | bintime_shift(struct bintime *_bt, int _exp) |
||
117 | { |
||
118 | |||
119 | if (_exp > 0) { |
||
120 | _bt->sec <<= _exp; |
||
121 | _bt->sec |= _bt->frac >> (64 - _exp); |
||
122 | _bt->frac <<= _exp; |
||
123 | } else if (_exp < 0) { |
||
124 | _bt->frac >>= -_exp; |
||
125 | _bt->frac |= (uint64_t)_bt->sec << (64 + _exp); |
||
126 | _bt->sec >>= -_exp; |
||
127 | } |
||
128 | } |
||
129 | |||
130 | #define bintime_clear(a) ((a)->sec = (a)->frac = 0) |
||
131 | #define bintime_isset(a) ((a)->sec || (a)->frac) |
||
132 | #define bintime_cmp(a, b, cmp) \ |
||
133 | (((a)->sec == (b)->sec) ? \ |
||
134 | ((a)->frac cmp (b)->frac) : \ |
||
135 | ((a)->sec cmp (b)->sec)) |
||
136 | |||
137 | #define SBT_1S ((sbintime_t)1 << 32) |
||
138 | #define SBT_1M (SBT_1S * 60) |
||
139 | #define SBT_1MS (SBT_1S / 1000) |
||
140 | #define SBT_1US (SBT_1S / 1000000) |
||
141 | #define SBT_1NS (SBT_1S / 1000000000) |
||
142 | #define SBT_MAX 0x7fffffffffffffffLL |
||
143 | |||
144 | static __inline int |
||
145 | sbintime_getsec(sbintime_t _sbt) |
||
146 | { |
||
147 | |||
148 | return (_sbt >> 32); |
||
149 | } |
||
150 | |||
151 | static __inline sbintime_t |
||
152 | bttosbt(const struct bintime _bt) |
||
153 | { |
||
154 | |||
155 | return (((sbintime_t)_bt.sec << 32) + (_bt.frac >> 32)); |
||
156 | } |
||
157 | |||
158 | static __inline struct bintime |
||
159 | sbttobt(sbintime_t _sbt) |
||
160 | { |
||
161 | struct bintime _bt; |
||
162 | |||
163 | _bt.sec = _sbt >> 32; |
||
164 | _bt.frac = _sbt << 32; |
||
165 | return (_bt); |
||
166 | } |
||
167 | |||
168 | /*- |
||
169 | * Background information: |
||
170 | * |
||
171 | * When converting between timestamps on parallel timescales of differing |
||
172 | * resolutions it is historical and scientific practice to round down rather |
||
173 | * than doing 4/5 rounding. |
||
174 | * |
||
175 | * The date changes at midnight, not at noon. |
||
176 | * |
||
177 | * Even at 15:59:59.999999999 it's not four'o'clock. |
||
178 | * |
||
179 | * time_second ticks after N.999999999 not after N.4999999999 |
||
180 | */ |
||
181 | |||
182 | static __inline void |
||
183 | bintime2timespec(const struct bintime *_bt, struct timespec *_ts) |
||
184 | { |
||
185 | |||
186 | _ts->tv_sec = _bt->sec; |
||
187 | _ts->tv_nsec = ((uint64_t)1000000000 * |
||
188 | (uint32_t)(_bt->frac >> 32)) >> 32; |
||
189 | } |
||
190 | |||
191 | static __inline void |
||
192 | timespec2bintime(const struct timespec *_ts, struct bintime *_bt) |
||
193 | { |
||
194 | |||
195 | _bt->sec = _ts->tv_sec; |
||
196 | /* 18446744073 = int(2^64 / 1000000000) */ |
||
197 | _bt->frac = _ts->tv_nsec * (uint64_t)18446744073LL; |
||
198 | } |
||
199 | |||
200 | static __inline void |
||
201 | bintime2timeval(const struct bintime *_bt, struct timeval *_tv) |
||
202 | { |
||
203 | |||
204 | _tv->tv_sec = _bt->sec; |
||
205 | _tv->tv_usec = ((uint64_t)1000000 * (uint32_t)(_bt->frac >> 32)) >> 32; |
||
206 | } |
||
207 | |||
208 | static __inline void |
||
209 | timeval2bintime(const struct timeval *_tv, struct bintime *_bt) |
||
210 | { |
||
211 | |||
212 | _bt->sec = _tv->tv_sec; |
||
213 | /* 18446744073709 = int(2^64 / 1000000) */ |
||
214 | _bt->frac = _tv->tv_usec * (uint64_t)18446744073709LL; |
||
215 | } |
||
216 | |||
217 | static __inline struct timespec |
||
218 | sbttots(sbintime_t _sbt) |
||
219 | { |
||
220 | struct timespec _ts; |
||
221 | |||
222 | _ts.tv_sec = _sbt >> 32; |
||
223 | _ts.tv_nsec = ((uint64_t)1000000000 * (uint32_t)_sbt) >> 32; |
||
224 | return (_ts); |
||
225 | } |
||
226 | |||
227 | static __inline sbintime_t |
||
228 | tstosbt(struct timespec _ts) |
||
229 | { |
||
230 | |||
231 | return (((sbintime_t)_ts.tv_sec << 32) + |
||
232 | (_ts.tv_nsec * (((uint64_t)1 << 63) / 500000000) >> 32)); |
||
233 | } |
||
234 | |||
235 | static __inline struct timeval |
||
236 | sbttotv(sbintime_t _sbt) |
||
237 | { |
||
238 | struct timeval _tv; |
||
239 | |||
240 | _tv.tv_sec = _sbt >> 32; |
||
241 | _tv.tv_usec = ((uint64_t)1000000 * (uint32_t)_sbt) >> 32; |
||
242 | return (_tv); |
||
243 | } |
||
244 | |||
245 | static __inline sbintime_t |
||
246 | tvtosbt(struct timeval _tv) |
||
247 | { |
||
248 | |||
249 | return (((sbintime_t)_tv.tv_sec << 32) + |
||
250 | (_tv.tv_usec * (((uint64_t)1 << 63) / 500000) >> 32)); |
||
251 | } |
||
252 | #endif /* __BSD_VISIBLE */ |
||
253 | |||
254 | #ifdef _KERNEL |
||
255 | |||
256 | /* Operations on timespecs */ |
||
257 | #define timespecclear(tvp) ((tvp)->tv_sec = (tvp)->tv_nsec = 0) |
||
258 | #define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) |
||
259 | #define timespeccmp(tvp, uvp, cmp) \ |
||
260 | (((tvp)->tv_sec == (uvp)->tv_sec) ? \ |
||
261 | ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ |
||
262 | ((tvp)->tv_sec cmp (uvp)->tv_sec)) |
||
263 | #define timespecadd(vvp, uvp) \ |
||
264 | do { \ |
||
265 | (vvp)->tv_sec += (uvp)->tv_sec; \ |
||
266 | (vvp)->tv_nsec += (uvp)->tv_nsec; \ |
||
267 | if ((vvp)->tv_nsec >= 1000000000) { \ |
||
268 | (vvp)->tv_sec++; \ |
||
269 | (vvp)->tv_nsec -= 1000000000; \ |
||
270 | } \ |
||
271 | } while (0) |
||
272 | #define timespecsub(vvp, uvp) \ |
||
273 | do { \ |
||
274 | (vvp)->tv_sec -= (uvp)->tv_sec; \ |
||
275 | (vvp)->tv_nsec -= (uvp)->tv_nsec; \ |
||
276 | if ((vvp)->tv_nsec < 0) { \ |
||
277 | (vvp)->tv_sec--; \ |
||
278 | (vvp)->tv_nsec += 1000000000; \ |
||
279 | } \ |
||
280 | } while (0) |
||
281 | |||
282 | /* Operations on timevals. */ |
||
283 | |||
284 | #define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) |
||
285 | #define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) |
||
286 | #define timevalcmp(tvp, uvp, cmp) \ |
||
287 | (((tvp)->tv_sec == (uvp)->tv_sec) ? \ |
||
288 | ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ |
||
289 | ((tvp)->tv_sec cmp (uvp)->tv_sec)) |
||
290 | |||
291 | /* timevaladd and timevalsub are not inlined */ |
||
292 | |||
293 | #endif /* _KERNEL */ |
||
294 | |||
295 | /* |
||
296 | * Names of the interval timers, and structure |
||
297 | * defining a timer setting. |
||
298 | */ |
||
299 | #define ITIMER_REAL 0 |
||
300 | #define ITIMER_VIRTUAL 1 |
||
301 | #define ITIMER_PROF 2 |
||
302 | |||
303 | struct itimerval { |
||
304 | struct timeval it_interval; /* timer interval */ |
||
305 | struct timeval it_value; /* current value */ |
||
4921 | Serge | 306 | }; |
307 | |||
6099 | serge | 308 | #ifdef _KERNEL |
309 | |||
310 | /* |
||
311 | * Kernel to clock driver interface. |
||
312 | */ |
||
313 | void inittodr(time_t base); |
||
314 | void resettodr(void); |
||
315 | |||
316 | extern volatile time_t time_second; |
||
317 | extern volatile time_t time_uptime; |
||
318 | extern struct bintime boottimebin; |
||
319 | extern struct timeval boottime; |
||
320 | extern struct bintime tc_tick_bt; |
||
321 | extern sbintime_t tc_tick_sbt; |
||
322 | extern struct bintime tick_bt; |
||
323 | extern sbintime_t tick_sbt; |
||
324 | extern int tc_precexp; |
||
325 | extern int tc_timepercentage; |
||
326 | extern struct bintime bt_timethreshold; |
||
327 | extern struct bintime bt_tickthreshold; |
||
328 | extern sbintime_t sbt_timethreshold; |
||
329 | extern sbintime_t sbt_tickthreshold; |
||
330 | |||
331 | /* |
||
332 | * Functions for looking at our clock: [get]{bin,nano,micro}[up]time() |
||
333 | * |
||
334 | * Functions without the "get" prefix returns the best timestamp |
||
335 | * we can produce in the given format. |
||
336 | * |
||
337 | * "bin" == struct bintime == seconds + 64 bit fraction of seconds. |
||
338 | * "nano" == struct timespec == seconds + nanoseconds. |
||
339 | * "micro" == struct timeval == seconds + microseconds. |
||
340 | * |
||
341 | * Functions containing "up" returns time relative to boot and |
||
342 | * should be used for calculating time intervals. |
||
343 | * |
||
344 | * Functions without "up" returns UTC time. |
||
345 | * |
||
346 | * Functions with the "get" prefix returns a less precise result |
||
347 | * much faster than the functions without "get" prefix and should |
||
348 | * be used where a precision of 1/hz seconds is acceptable or where |
||
349 | * performance is priority. (NB: "precision", _not_ "resolution" !) |
||
350 | */ |
||
351 | |||
352 | void binuptime(struct bintime *bt); |
||
353 | void nanouptime(struct timespec *tsp); |
||
354 | void microuptime(struct timeval *tvp); |
||
355 | |||
356 | static __inline sbintime_t |
||
357 | sbinuptime(void) |
||
358 | { |
||
359 | struct bintime _bt; |
||
360 | |||
361 | binuptime(&_bt); |
||
362 | return (bttosbt(_bt)); |
||
363 | } |
||
364 | |||
365 | void bintime(struct bintime *bt); |
||
366 | void nanotime(struct timespec *tsp); |
||
367 | void microtime(struct timeval *tvp); |
||
368 | |||
369 | void getbinuptime(struct bintime *bt); |
||
370 | void getnanouptime(struct timespec *tsp); |
||
371 | void getmicrouptime(struct timeval *tvp); |
||
372 | |||
373 | static __inline sbintime_t |
||
374 | getsbinuptime(void) |
||
375 | { |
||
376 | struct bintime _bt; |
||
377 | |||
378 | getbinuptime(&_bt); |
||
379 | return (bttosbt(_bt)); |
||
380 | } |
||
381 | |||
382 | void getbintime(struct bintime *bt); |
||
383 | void getnanotime(struct timespec *tsp); |
||
384 | void getmicrotime(struct timeval *tvp); |
||
385 | |||
386 | /* Other functions */ |
||
387 | int itimerdecr(struct itimerval *itp, int usec); |
||
388 | int itimerfix(struct timeval *tv); |
||
389 | int ppsratecheck(struct timeval *, int *, int); |
||
390 | int ratecheck(struct timeval *, const struct timeval *); |
||
391 | void timevaladd(struct timeval *t1, const struct timeval *t2); |
||
392 | void timevalsub(struct timeval *t1, const struct timeval *t2); |
||
393 | int tvtohz(struct timeval *tv); |
||
394 | |||
395 | #define TC_DEFAULTPERC 5 |
||
396 | |||
397 | #define BT2FREQ(bt) \ |
||
398 | (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \ |
||
399 | ((bt)->frac >> 1)) |
||
400 | |||
401 | #define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt)) |
||
402 | |||
403 | #define FREQ2BT(freq, bt) \ |
||
404 | { \ |
||
405 | (bt)->sec = 0; \ |
||
406 | (bt)->frac = ((uint64_t)0x8000000000000000 / (freq)) << 1; \ |
||
407 | } |
||
408 | |||
409 | #define TIMESEL(sbt, sbt2) \ |
||
410 | (((sbt2) >= sbt_timethreshold) ? \ |
||
411 | ((*(sbt) = getsbinuptime()), 1) : ((*(sbt) = sbinuptime()), 0)) |
||
412 | |||
413 | #else /* !_KERNEL */ |
||
414 | #include |
||
415 | |||
416 | #include |
||
417 | |||
418 | __BEGIN_DECLS |
||
419 | int _EXFUN(setitimer, (int __which, const struct itimerval *__restrict __value, |
||
420 | struct itimerval *__restrict __ovalue)); |
||
421 | int _EXFUN(utimes, (const char *__path, const struct timeval *__tvp)); |
||
422 | |||
423 | #if __BSD_VISIBLE |
||
424 | int _EXFUN(adjtime, (const struct timeval *, struct timeval *)); |
||
425 | int _EXFUN(futimes, (int, const struct timeval *)); |
||
426 | int _EXFUN(futimesat, (int, const char *, const struct timeval [2])); |
||
427 | int _EXFUN(lutimes, (const char *, const struct timeval *)); |
||
428 | int _EXFUN(settimeofday, (const struct timeval *, const struct timezone *)); |
||
4921 | Serge | 429 | #endif |
430 | |||
6099 | serge | 431 | #if __XSI_VISIBLE |
432 | int _EXFUN(getitimer, (int __which, struct itimerval *__value)); |
||
4921 | Serge | 433 | int _EXFUN(gettimeofday, (struct timeval *__restrict __p, |
434 | void *__restrict __tz)); |
||
6099 | serge | 435 | #endif |
4349 | Serge | 436 | |
6099 | serge | 437 | #ifdef _COMPILING_NEWLIB |
438 | int _EXFUN(_gettimeofday, (struct timeval *__p, void *__tz)); |
||
4349 | Serge | 439 | #endif |
6099 | serge | 440 | |
441 | __END_DECLS |
||
442 | |||
443 | #endif /* !_KERNEL */ |
||
444 | |||
445 | #endif /* !_SYS_TIME_H_ */><>>><>><>><>><>><>><>><>><>>=><=>=><=>><>> |