xref: /illumos-gate/usr/src/compat/bhyve/sys/time.h (revision 2699b94c)
1bf21cd93STycho Nightingale /*
2bf21cd93STycho Nightingale  * This file and its contents are supplied under the terms of the
3bf21cd93STycho Nightingale  * Common Development and Distribution License ("CDDL"), version 1.0.
4bf21cd93STycho Nightingale  * You may only use this file in accordance with the terms of version
5bf21cd93STycho Nightingale  * 1.0 of the CDDL.
6bf21cd93STycho Nightingale  *
7bf21cd93STycho Nightingale  * A full copy of the text of the CDDL should have accompanied this
8bf21cd93STycho Nightingale  * source.  A copy of the CDDL is also available via the Internet at
9bf21cd93STycho Nightingale  * http://www.illumos.org/license/CDDL.
10bf21cd93STycho Nightingale  */
11bf21cd93STycho Nightingale 
12bf21cd93STycho Nightingale /*
13bf21cd93STycho Nightingale  * Copyright 2013 Pluribus Networks Inc.
14*2699b94cSPatrick Mooney  * Copyright 2020 Oxide Computer Company
15bf21cd93STycho Nightingale  */
16bf21cd93STycho Nightingale 
17bf21cd93STycho Nightingale #ifndef _COMPAT_FREEBSD_SYS_TIME_H_
18bf21cd93STycho Nightingale #define	_COMPAT_FREEBSD_SYS_TIME_H_
19bf21cd93STycho Nightingale 
20bf21cd93STycho Nightingale #include_next <sys/time.h>
21bf21cd93STycho Nightingale 
22bf21cd93STycho Nightingale #define	tc_precexp	0
23bf21cd93STycho Nightingale 
24bf21cd93STycho Nightingale struct bintime {
25bf21cd93STycho Nightingale 	ulong_t		sec;		/* seconds */
26bf21cd93STycho Nightingale 	uint64_t	frac;		/* 64 bit fraction of a second */
27bf21cd93STycho Nightingale };
28bf21cd93STycho Nightingale 
29bf21cd93STycho Nightingale #define	BT2FREQ(bt)							\
30bf21cd93STycho Nightingale 	(((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) /		\
31bf21cd93STycho Nightingale 	    ((bt)->frac >> 1))
32bf21cd93STycho Nightingale 
33bf21cd93STycho Nightingale #define	FREQ2BT(freq, bt)						\
34bf21cd93STycho Nightingale {									\
35bf21cd93STycho Nightingale 	(bt)->sec = 0;							\
36bf21cd93STycho Nightingale 	(bt)->frac = ((uint64_t)0x8000000000000000  / (freq)) << 1;	\
37bf21cd93STycho Nightingale }
38bf21cd93STycho Nightingale 
39bf21cd93STycho Nightingale static __inline void
binuptime(struct bintime * bt)40bf21cd93STycho Nightingale binuptime(struct bintime *bt)
41bf21cd93STycho Nightingale {
42bf21cd93STycho Nightingale 	hrtime_t	now = gethrtime();
43bf21cd93STycho Nightingale 
44bf21cd93STycho Nightingale 	bt->sec = now / 1000000000;
45bf21cd93STycho Nightingale 	/* 18446744073 = int(2^64 / 1000000000) = 1ns in 64-bit fractions */
46bf21cd93STycho Nightingale 	bt->frac = (now % 1000000000) * (uint64_t)18446744073LL;
47bf21cd93STycho Nightingale }
48bf21cd93STycho Nightingale 
49bf21cd93STycho Nightingale #define	bintime_cmp(a, b, cmp)						\
50bf21cd93STycho Nightingale 	(((a)->sec == (b)->sec) ?					\
51bf21cd93STycho Nightingale 	    ((a)->frac cmp (b)->frac) :					\
52bf21cd93STycho Nightingale 	    ((a)->sec cmp (b)->sec))
53bf21cd93STycho Nightingale 
54*2699b94cSPatrick Mooney /*
55*2699b94cSPatrick Mooney  * The bintime_cmp() macro is problematic for a couple reasons:
56*2699b94cSPatrick Mooney  * 1. Bearing a lowercase name suggests it is a function rather than a macro.
57*2699b94cSPatrick Mooney  * 2. Placing the comparison operator as the last argument runs afoul of our
58*2699b94cSPatrick Mooney  *    cstyle rules, unlike cases such as VERIFY3*().
59*2699b94cSPatrick Mooney  *
60*2699b94cSPatrick Mooney  * To remedy these issues in illumos bhyve, we provide a slightly modified
61*2699b94cSPatrick Mooney  * version which addresses both problems.
62*2699b94cSPatrick Mooney  */
63*2699b94cSPatrick Mooney #define	BINTIME_CMP(a, cmp, b)	bintime_cmp((a), (b), cmp)
64*2699b94cSPatrick Mooney 
654c87aefeSPatrick Mooney #define SBT_1S  ((sbintime_t)1 << 32)
664c87aefeSPatrick Mooney #define SBT_1M  (SBT_1S * 60)
674c87aefeSPatrick Mooney #define SBT_1MS (SBT_1S / 1000)
684c87aefeSPatrick Mooney #define SBT_1US (SBT_1S / 1000000)
694c87aefeSPatrick Mooney #define SBT_1NS (SBT_1S / 1000000000)
704c87aefeSPatrick Mooney #define SBT_MAX 0x7fffffffffffffffLL
714c87aefeSPatrick Mooney 
72bf21cd93STycho Nightingale 
73bf21cd93STycho Nightingale static __inline void
bintime_add(struct bintime * bt,const struct bintime * bt2)74bf21cd93STycho Nightingale bintime_add(struct bintime *bt, const struct bintime *bt2)
75bf21cd93STycho Nightingale {
76bf21cd93STycho Nightingale 	uint64_t u;
77bf21cd93STycho Nightingale 
78bf21cd93STycho Nightingale 	u = bt->frac;
79bf21cd93STycho Nightingale 	bt->frac += bt2->frac;
80bf21cd93STycho Nightingale 	if (u > bt->frac)
81bf21cd93STycho Nightingale 		bt->sec++;
82bf21cd93STycho Nightingale 	bt->sec += bt2->sec;
83bf21cd93STycho Nightingale }
84bf21cd93STycho Nightingale 
85bf21cd93STycho Nightingale static __inline void
bintime_sub(struct bintime * bt,const struct bintime * bt2)86bf21cd93STycho Nightingale bintime_sub(struct bintime *bt, const struct bintime *bt2)
87bf21cd93STycho Nightingale {
88bf21cd93STycho Nightingale 	uint64_t u;
89bf21cd93STycho Nightingale 
90bf21cd93STycho Nightingale 	u = bt->frac;
91bf21cd93STycho Nightingale 	bt->frac -= bt2->frac;
92bf21cd93STycho Nightingale 	if (u < bt->frac)
93bf21cd93STycho Nightingale 		bt->sec--;
94bf21cd93STycho Nightingale 	bt->sec -= bt2->sec;
95bf21cd93STycho Nightingale }
96bf21cd93STycho Nightingale 
97bf21cd93STycho Nightingale static __inline void
bintime_mul(struct bintime * bt,u_int x)98bf21cd93STycho Nightingale bintime_mul(struct bintime *bt, u_int x)
99bf21cd93STycho Nightingale {
100bf21cd93STycho Nightingale 	uint64_t p1, p2;
101bf21cd93STycho Nightingale 
102bf21cd93STycho Nightingale 	p1 = (bt->frac & 0xffffffffull) * x;
103bf21cd93STycho Nightingale 	p2 = (bt->frac >> 32) * x + (p1 >> 32);
104bf21cd93STycho Nightingale 	bt->sec *= x;
105bf21cd93STycho Nightingale 	bt->sec += (p2 >> 32);
106bf21cd93STycho Nightingale 	bt->frac = (p2 << 32) | (p1 & 0xffffffffull);
107bf21cd93STycho Nightingale }
108bf21cd93STycho Nightingale 
109bf21cd93STycho Nightingale static __inline sbintime_t
bttosbt(const struct bintime bt)110bf21cd93STycho Nightingale bttosbt(const struct bintime bt)
111bf21cd93STycho Nightingale {
1124c87aefeSPatrick Mooney 	return (((sbintime_t)bt.sec << 32) + (bt.frac >> 32));
1134c87aefeSPatrick Mooney }
1144c87aefeSPatrick Mooney 
1154c87aefeSPatrick Mooney static __inline struct bintime
sbttobt(sbintime_t _sbt)1164c87aefeSPatrick Mooney sbttobt(sbintime_t _sbt)
1174c87aefeSPatrick Mooney {
1184c87aefeSPatrick Mooney 	struct bintime _bt;
1194c87aefeSPatrick Mooney 
1204c87aefeSPatrick Mooney 	_bt.sec = _sbt >> 32;
1214c87aefeSPatrick Mooney 	_bt.frac = _sbt << 32;
1224c87aefeSPatrick Mooney 	return (_bt);
123bf21cd93STycho Nightingale }
124bf21cd93STycho Nightingale 
125bf21cd93STycho Nightingale static __inline sbintime_t
sbinuptime(void)126bf21cd93STycho Nightingale sbinuptime(void)
127bf21cd93STycho Nightingale {
1284c87aefeSPatrick Mooney 	hrtime_t hrt = gethrtime();
1294c87aefeSPatrick Mooney 	uint64_t sec = hrt / NANOSEC;
1304c87aefeSPatrick Mooney 	uint64_t nsec = hrt % NANOSEC;
1314c87aefeSPatrick Mooney 
1324c87aefeSPatrick Mooney 	return (((sbintime_t)sec << 32) +
1334c87aefeSPatrick Mooney 	    (nsec * (((uint64_t)1 << 63) / 500000000) >> 32));
134bf21cd93STycho Nightingale }
135bf21cd93STycho Nightingale 
136bf21cd93STycho Nightingale #endif	/* _COMPAT_FREEBSD_SYS_TIME_H_ */
137