xref: /openbsd/sys/sys/time.h (revision 106c68c4)
1 /*	$OpenBSD: time.h,v 1.66 2023/10/17 00:04:02 cheloha Exp $	*/
2 /*	$NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $	*/
3 
4 /*
5  * Copyright (c) 1982, 1986, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)time.h	8.2 (Berkeley) 7/10/94
33  */
34 
35 #ifndef _SYS_TIME_H_
36 #define _SYS_TIME_H_
37 
38 #include <sys/select.h>
39 
40 #ifndef _TIMEVAL_DECLARED
41 #define _TIMEVAL_DECLARED
42 /*
43  * Structure returned by gettimeofday(2) system call,
44  * and used in other calls.
45  */
46 struct timeval {
47 	time_t		tv_sec;		/* seconds */
48 	suseconds_t	tv_usec;	/* and microseconds */
49 };
50 #endif
51 
52 #ifndef _TIMESPEC_DECLARED
53 #define _TIMESPEC_DECLARED
54 /*
55  * Structure defined by POSIX.1b to be like a timeval.
56  */
57 struct timespec {
58 	time_t	tv_sec;		/* seconds */
59 	long	tv_nsec;	/* and nanoseconds */
60 };
61 #endif
62 
63 #define	TIMEVAL_TO_TIMESPEC(tv, ts) do {				\
64 	(ts)->tv_sec = (tv)->tv_sec;					\
65 	(ts)->tv_nsec = (tv)->tv_usec * 1000;				\
66 } while (0)
67 #define	TIMESPEC_TO_TIMEVAL(tv, ts) do {				\
68 	(tv)->tv_sec = (ts)->tv_sec;					\
69 	(tv)->tv_usec = (ts)->tv_nsec / 1000;				\
70 } while (0)
71 
72 struct timezone {
73 	int	tz_minuteswest;	/* minutes west of Greenwich */
74 	int	tz_dsttime;	/* type of dst correction */
75 };
76 #define	DST_NONE	0	/* not on dst */
77 #define	DST_USA		1	/* USA style dst */
78 #define	DST_AUST	2	/* Australian style dst */
79 #define	DST_WET		3	/* Western European dst */
80 #define	DST_MET		4	/* Middle European dst */
81 #define	DST_EET		5	/* Eastern European dst */
82 #define	DST_CAN		6	/* Canada */
83 
84 /* Operations on timevals. */
85 #define	timerclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
86 #define	timerisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
87 #define	timerisvalid(tvp)						\
88 	((tvp)->tv_usec >= 0 && (tvp)->tv_usec < 1000000)
89 #define	timercmp(tvp, uvp, cmp)						\
90 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
91 	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
92 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
93 #define	timeradd(tvp, uvp, vvp)						\
94 	do {								\
95 		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
96 		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;	\
97 		if ((vvp)->tv_usec >= 1000000) {			\
98 			(vvp)->tv_sec++;				\
99 			(vvp)->tv_usec -= 1000000;			\
100 		}							\
101 	} while (0)
102 #define	timersub(tvp, uvp, vvp)						\
103 	do {								\
104 		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
105 		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
106 		if ((vvp)->tv_usec < 0) {				\
107 			(vvp)->tv_sec--;				\
108 			(vvp)->tv_usec += 1000000;			\
109 		}							\
110 	} while (0)
111 
112 /* Operations on timespecs. */
113 #define	timespecclear(tsp)		(tsp)->tv_sec = (tsp)->tv_nsec = 0
114 #define	timespecisset(tsp)		((tsp)->tv_sec || (tsp)->tv_nsec)
115 #define	timespecisvalid(tsp)						\
116 	((tsp)->tv_nsec >= 0 && (tsp)->tv_nsec < 1000000000L)
117 #define	timespeccmp(tsp, usp, cmp)					\
118 	(((tsp)->tv_sec == (usp)->tv_sec) ?				\
119 	    ((tsp)->tv_nsec cmp (usp)->tv_nsec) :			\
120 	    ((tsp)->tv_sec cmp (usp)->tv_sec))
121 #define	timespecadd(tsp, usp, vsp)					\
122 	do {								\
123 		(vsp)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec;		\
124 		(vsp)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec;	\
125 		if ((vsp)->tv_nsec >= 1000000000L) {			\
126 			(vsp)->tv_sec++;				\
127 			(vsp)->tv_nsec -= 1000000000L;			\
128 		}							\
129 	} while (0)
130 #define	timespecsub(tsp, usp, vsp)					\
131 	do {								\
132 		(vsp)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec;		\
133 		(vsp)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec;	\
134 		if ((vsp)->tv_nsec < 0) {				\
135 			(vsp)->tv_sec--;				\
136 			(vsp)->tv_nsec += 1000000000L;			\
137 		}							\
138 	} while (0)
139 
140 /*
141  * Names of the interval timers, and structure
142  * defining a timer setting.
143  */
144 #define	ITIMER_REAL	0
145 #define	ITIMER_VIRTUAL	1
146 #define	ITIMER_PROF	2
147 
148 struct	itimerval {
149 	struct	timeval it_interval;	/* timer interval */
150 	struct	timeval it_value;	/* current value */
151 };
152 
153 #if __BSD_VISIBLE
154 /*
155  * clock information structure for sysctl({CTL_KERN, KERN_CLOCKRATE})
156  */
157 struct clockinfo {
158 	int	hz;		/* clock frequency */
159 	int	tick;		/* micro-seconds per hz tick */
160 	int	stathz;		/* statistics clock frequency */
161 	int	profhz;		/* profiling clock frequency */
162 };
163 #endif /* __BSD_VISIBLE */
164 
165 #if defined(_KERNEL) || defined(_STANDALONE) || defined (_LIBC)
166 #include <sys/_time.h>
167 
168 /* Time expressed as seconds and fractions of a second + operations on it. */
169 struct bintime {
170 	time_t	sec;
171 	uint64_t frac;
172 };
173 #endif
174 
175 #if defined(_KERNEL) || defined(_STANDALONE) || defined (_LIBC)
176 
177 #define bintimecmp(btp, ctp, cmp)					\
178 	((btp)->sec == (ctp)->sec ?					\
179 	    (btp)->frac cmp (ctp)->frac :				\
180 	    (btp)->sec cmp (ctp)->sec)
181 
182 static inline void
bintimeaddfrac(const struct bintime * bt,uint64_t x,struct bintime * ct)183 bintimeaddfrac(const struct bintime *bt, uint64_t x, struct bintime *ct)
184 {
185 	ct->sec = bt->sec;
186 	if (bt->frac > bt->frac + x)
187 		ct->sec++;
188 	ct->frac = bt->frac + x;
189 }
190 
191 static inline void
bintimeadd(const struct bintime * bt,const struct bintime * ct,struct bintime * dt)192 bintimeadd(const struct bintime *bt, const struct bintime *ct,
193     struct bintime *dt)
194 {
195 	dt->sec = bt->sec + ct->sec;
196 	if (bt->frac > bt->frac + ct->frac)
197 		dt->sec++;
198 	dt->frac = bt->frac + ct->frac;
199 }
200 
201 static inline void
bintimesub(const struct bintime * bt,const struct bintime * ct,struct bintime * dt)202 bintimesub(const struct bintime *bt, const struct bintime *ct,
203     struct bintime *dt)
204 {
205 	dt->sec = bt->sec - ct->sec;
206 	if (bt->frac < bt->frac - ct->frac)
207 		dt->sec--;
208 	dt->frac = bt->frac - ct->frac;
209 }
210 
211 static inline void
TIMECOUNT_TO_BINTIME(u_int count,uint64_t scale,struct bintime * bt)212 TIMECOUNT_TO_BINTIME(u_int count, uint64_t scale, struct bintime *bt)
213 {
214 	uint64_t hi64;
215 
216 	hi64 = count * (scale >> 32);
217 	bt->sec = hi64 >> 32;
218 	bt->frac = hi64 << 32;
219 	bintimeaddfrac(bt, count * (scale & 0xffffffff), bt);
220 }
221 
222 /*-
223  * Background information:
224  *
225  * When converting between timestamps on parallel timescales of differing
226  * resolutions it is historical and scientific practice to round down rather
227  * than doing 4/5 rounding.
228  *
229  *   The date changes at midnight, not at noon.
230  *
231  *   Even at 15:59:59.999999999 it's not four'o'clock.
232  *
233  *   time_second ticks after N.999999999 not after N.4999999999
234  */
235 
236 static inline uint32_t
FRAC_TO_NSEC(uint64_t frac)237 FRAC_TO_NSEC(uint64_t frac)
238 {
239 	return ((frac >> 32) * 1000000000ULL) >> 32;
240 }
241 
242 static inline void
BINTIME_TO_TIMESPEC(const struct bintime * bt,struct timespec * ts)243 BINTIME_TO_TIMESPEC(const struct bintime *bt, struct timespec *ts)
244 {
245 	ts->tv_sec = bt->sec;
246 	ts->tv_nsec = FRAC_TO_NSEC(bt->frac);
247 }
248 
249 static inline void
TIMESPEC_TO_BINTIME(const struct timespec * ts,struct bintime * bt)250 TIMESPEC_TO_BINTIME(const struct timespec *ts, struct bintime *bt)
251 {
252 	bt->sec = ts->tv_sec;
253 	/* 18446744073 = int(2^64 / 1000000000) */
254 	bt->frac = (uint64_t)ts->tv_nsec * (uint64_t)18446744073ULL;
255 }
256 
257 static inline void
BINTIME_TO_TIMEVAL(const struct bintime * bt,struct timeval * tv)258 BINTIME_TO_TIMEVAL(const struct bintime *bt, struct timeval *tv)
259 {
260 	tv->tv_sec = bt->sec;
261 	tv->tv_usec = (long)(((uint64_t)1000000 * (uint32_t)(bt->frac >> 32)) >> 32);
262 }
263 
264 static inline void
TIMEVAL_TO_BINTIME(const struct timeval * tv,struct bintime * bt)265 TIMEVAL_TO_BINTIME(const struct timeval *tv, struct bintime *bt)
266 {
267 	bt->sec = (time_t)tv->tv_sec;
268 	/* 18446744073709 = int(2^64 / 1000000) */
269 	bt->frac = (uint64_t)tv->tv_usec * (uint64_t)18446744073709ULL;
270 }
271 #endif
272 
273 #if defined(_KERNEL) || defined(_STANDALONE)
274 
275 /*
276  * Functions for looking at our clocks: [get]{bin,nano,micro}[boot|up]time()
277  *
278  * Functions without the "get" prefix returns the best timestamp
279  * we can produce in the given format.
280  *
281  * "bin"   == struct bintime  == seconds + 64 bit fraction of seconds.
282  * "nano"  == struct timespec == seconds + nanoseconds.
283  * "micro" == struct timeval  == seconds + microseconds.
284  *
285  * Functions containing "up" returns time relative to boot and
286  * should be used for calculating time intervals.
287  *
288  * Functions containing "boot" return the GMT time at which the
289  * system booted.
290  *
291  * Functions with just "time" return the current GMT time.
292  *
293  * Functions with the "get" prefix returns a less precise result
294  * much faster than the functions without "get" prefix and should
295  * be used where a precision of 10 msec is acceptable or where
296  * performance is priority. (NB: "precision", _not_ "resolution" !)
297  */
298 
299 void	bintime(struct bintime *);
300 void	nanotime(struct timespec *);
301 void	microtime(struct timeval *);
302 
303 void	getnanotime(struct timespec *);
304 void	getmicrotime(struct timeval *);
305 
306 void	binuptime(struct bintime *);
307 void	nanouptime(struct timespec *);
308 void	microuptime(struct timeval *);
309 
310 void	getbinuptime(struct bintime *);
311 void	getnanouptime(struct timespec *);
312 void	getmicrouptime(struct timeval *);
313 
314 void	binboottime(struct bintime *);
315 void	microboottime(struct timeval *);
316 void	nanoboottime(struct timespec *);
317 
318 void	binruntime(struct bintime *);
319 void	nanoruntime(struct timespec *);
320 
321 void getbinruntime(struct bintime *);
322 uint64_t getnsecruntime(void);
323 
324 time_t	gettime(void);
325 time_t	getuptime(void);
326 
327 uint64_t	nsecuptime(void);
328 uint64_t	getnsecuptime(void);
329 
330 struct proc;
331 int	clock_gettime(struct proc *, clockid_t, struct timespec *);
332 
333 struct clockrequest;
334 void itimer_update(struct clockrequest *, void *, void *);
335 
336 void	cancel_all_itimers(void);
337 int	settime(const struct timespec *);
338 int	ratecheck(struct timeval *, const struct timeval *);
339 int	ppsratecheck(struct timeval *, int *, int);
340 
341 /*
342  * "POSIX time" to/from "YY/MM/DD/hh/mm/ss"
343  */
344 struct clock_ymdhms {
345         u_short dt_year;
346         u_char dt_mon;
347         u_char dt_day;
348         u_char dt_wday; /* Day of week */
349         u_char dt_hour;
350         u_char dt_min;
351         u_char dt_sec;
352 };
353 
354 time_t clock_ymdhms_to_secs(struct clock_ymdhms *);
355 void clock_secs_to_ymdhms(time_t, struct clock_ymdhms *);
356 /*
357  * BCD to decimal and decimal to BCD.
358  */
359 #define FROMBCD(x)      (((x) >> 4) * 10 + ((x) & 0xf))
360 #define TOBCD(x)        (((x) / 10 * 16) + ((x) % 10))
361 
362 /* Some handy constants. */
363 #define SECDAY          86400L
364 #define SECYR           (SECDAY * 365)
365 
366 /* Traditional POSIX base year */
367 #define POSIX_BASE_YEAR 1970
368 
369 #include <sys/stdint.h>
370 
371 static inline void
USEC_TO_TIMEVAL(uint64_t us,struct timeval * tv)372 USEC_TO_TIMEVAL(uint64_t us, struct timeval *tv)
373 {
374 	tv->tv_sec = us / 1000000;
375 	tv->tv_usec = us % 1000000;
376 }
377 
378 static inline void
NSEC_TO_TIMEVAL(uint64_t ns,struct timeval * tv)379 NSEC_TO_TIMEVAL(uint64_t ns, struct timeval *tv)
380 {
381 	tv->tv_sec = ns / 1000000000L;
382 	tv->tv_usec = (ns % 1000000000L) / 1000;
383 }
384 
385 static inline uint64_t
TIMEVAL_TO_NSEC(const struct timeval * tv)386 TIMEVAL_TO_NSEC(const struct timeval *tv)
387 {
388 	uint64_t nsecs;
389 
390 	if (tv->tv_sec > UINT64_MAX / 1000000000ULL)
391 		return UINT64_MAX;
392 	nsecs = tv->tv_sec * 1000000000ULL;
393 	if (tv->tv_usec * 1000ULL > UINT64_MAX - nsecs)
394 		return UINT64_MAX;
395 	return nsecs + tv->tv_usec * 1000ULL;
396 }
397 
398 static inline void
NSEC_TO_TIMESPEC(uint64_t ns,struct timespec * ts)399 NSEC_TO_TIMESPEC(uint64_t ns, struct timespec *ts)
400 {
401 	ts->tv_sec = ns / 1000000000L;
402 	ts->tv_nsec = ns % 1000000000L;
403 }
404 
405 static inline uint64_t
SEC_TO_NSEC(uint64_t seconds)406 SEC_TO_NSEC(uint64_t seconds)
407 {
408 	if (seconds > UINT64_MAX / 1000000000ULL)
409 		return UINT64_MAX;
410 	return seconds * 1000000000ULL;
411 }
412 
413 static inline uint64_t
MSEC_TO_NSEC(uint64_t milliseconds)414 MSEC_TO_NSEC(uint64_t milliseconds)
415 {
416 	if (milliseconds > UINT64_MAX / 1000000ULL)
417 		return UINT64_MAX;
418 	return milliseconds * 1000000ULL;
419 }
420 
421 static inline uint64_t
USEC_TO_NSEC(uint64_t microseconds)422 USEC_TO_NSEC(uint64_t microseconds)
423 {
424 	if (microseconds > UINT64_MAX / 1000ULL)
425 		return UINT64_MAX;
426 	return microseconds * 1000ULL;
427 }
428 
429 static inline uint64_t
TIMESPEC_TO_NSEC(const struct timespec * ts)430 TIMESPEC_TO_NSEC(const struct timespec *ts)
431 {
432 	if (ts->tv_sec > (UINT64_MAX - ts->tv_nsec) / 1000000000ULL)
433 		return UINT64_MAX;
434 	return ts->tv_sec * 1000000000ULL + ts->tv_nsec;
435 }
436 
437 static inline uint64_t
BINTIME_TO_NSEC(const struct bintime * bt)438 BINTIME_TO_NSEC(const struct bintime *bt)
439 {
440 	return bt->sec * 1000000000ULL + FRAC_TO_NSEC(bt->frac);
441 }
442 
443 #else /* !_KERNEL */
444 #include <time.h>
445 
446 #if __BSD_VISIBLE || __XPG_VISIBLE
447 __BEGIN_DECLS
448 #if __BSD_VISIBLE
449 int	adjtime(const struct timeval *, struct timeval *);
450 int	adjfreq(const int64_t *, int64_t *);
451 #endif
452 #if __XPG_VISIBLE
453 int	futimes(int, const struct timeval *);
454 int	getitimer(int, struct itimerval *);
455 int	gettimeofday(struct timeval *, struct timezone *);
456 int	setitimer(int, const struct itimerval *, struct itimerval *);
457 int	settimeofday(const struct timeval *, const struct timezone *);
458 int	utimes(const char *, const struct timeval *);
459 #endif /* __XPG_VISIBLE */
460 __END_DECLS
461 #endif /* __BSD_VISIBLE || __XPG_VISIBLE */
462 
463 #endif /* !_KERNEL */
464 
465 #endif /* !_SYS_TIME_H_ */
466