xref: /freebsd/contrib/ntp/include/ntp_unixtime.h (revision c0b746e5e8d9479f05b3749cbf1f73b8928719bd)
1c0b746e5SOllivier Robert /*
2c0b746e5SOllivier Robert  * ntp_unixtime.h - contains constants and macros for converting between
3c0b746e5SOllivier Robert  *		    NTP time stamps (l_fp) and Unix times (struct timeval)
4c0b746e5SOllivier Robert  */
5c0b746e5SOllivier Robert 
6c0b746e5SOllivier Robert #include "ntp_types.h"
7c0b746e5SOllivier Robert 
8c0b746e5SOllivier Robert #include <sys/time.h>
9c0b746e5SOllivier Robert 
10c0b746e5SOllivier Robert /* gettimeofday() takes two args in BSD and only one in SYSV */
11c0b746e5SOllivier Robert # if defined(HAVE_SYS_TIMERS_H) && defined(HAVE_GETCLOCK)
12c0b746e5SOllivier Robert #  include <sys/timers.h>
13c0b746e5SOllivier Robert int getclock (int clock_type, struct timespec *tp);
14c0b746e5SOllivier Robert /* Don't #define GETTIMEOFDAY because we shouldn't be using it in this case. */
15c0b746e5SOllivier Robert #   define SETTIMEOFDAY(a, b) (settimeofday(a, b))
16c0b746e5SOllivier Robert # else /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
17c0b746e5SOllivier Robert #  ifdef SYSV_TIMEOFDAY
18c0b746e5SOllivier Robert #   define GETTIMEOFDAY(a, b) (gettimeofday(a))
19c0b746e5SOllivier Robert #   define SETTIMEOFDAY(a, b) (settimeofday(a))
20c0b746e5SOllivier Robert #  else /* ! SYSV_TIMEOFDAY */
21c0b746e5SOllivier Robert #if defined SYS_CYGWIN32
22c0b746e5SOllivier Robert #   define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
23c0b746e5SOllivier Robert #   define SETTIMEOFDAY(a, b) (settimeofday_NT(a))
24c0b746e5SOllivier Robert #else
25c0b746e5SOllivier Robert #   define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
26c0b746e5SOllivier Robert #   define SETTIMEOFDAY(a, b) (settimeofday(a, b))
27c0b746e5SOllivier Robert #endif
28c0b746e5SOllivier Robert #  endif /* SYSV_TIMEOFDAY */
29c0b746e5SOllivier Robert # endif /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
30c0b746e5SOllivier Robert 
31c0b746e5SOllivier Robert /*
32c0b746e5SOllivier Robert  * Time of day conversion constant.  Ntp's time scale starts in 1900,
33c0b746e5SOllivier Robert  * Unix in 1970.
34c0b746e5SOllivier Robert  */
35c0b746e5SOllivier Robert #define	JAN_1970	0x83aa7e80	/* 2208988800 1970 - 1900 in seconds */
36c0b746e5SOllivier Robert 
37c0b746e5SOllivier Robert /*
38c0b746e5SOllivier Robert  * These constants are used to round the time stamps computed from
39c0b746e5SOllivier Robert  * a struct timeval to the microsecond (more or less).  This keeps
40c0b746e5SOllivier Robert  * things neat.
41c0b746e5SOllivier Robert  */
42c0b746e5SOllivier Robert #define	TS_MASK		0xfffff000	/* mask to usec, for time stamps */
43c0b746e5SOllivier Robert #define	TS_ROUNDBIT	0x00000800	/* round at this bit */
44c0b746e5SOllivier Robert 
45c0b746e5SOllivier Robert 
46c0b746e5SOllivier Robert /*
47c0b746e5SOllivier Robert  * Convert usec to a time stamp fraction.  If you use this the program
48c0b746e5SOllivier Robert  * must include the following declarations:
49c0b746e5SOllivier Robert  */
50c0b746e5SOllivier Robert extern u_long ustotslo[];
51c0b746e5SOllivier Robert extern u_long ustotsmid[];
52c0b746e5SOllivier Robert extern u_long ustotshi[];
53c0b746e5SOllivier Robert 
54c0b746e5SOllivier Robert #define	TVUTOTSF(tvu, tsf) \
55c0b746e5SOllivier Robert 	(tsf) = ustotslo[(tvu) & 0xff] \
56c0b746e5SOllivier Robert 	    + ustotsmid[((tvu) >> 8) & 0xff] \
57c0b746e5SOllivier Robert 	    + ustotshi[((tvu) >> 16) & 0xf]
58c0b746e5SOllivier Robert 
59c0b746e5SOllivier Robert /*
60c0b746e5SOllivier Robert  * Convert a struct timeval to a time stamp.
61c0b746e5SOllivier Robert  */
62c0b746e5SOllivier Robert #define TVTOTS(tv, ts) \
63c0b746e5SOllivier Robert 	do { \
64c0b746e5SOllivier Robert 		(ts)->l_ui = (u_long)(tv)->tv_sec; \
65c0b746e5SOllivier Robert 		TVUTOTSF((tv)->tv_usec, (ts)->l_uf); \
66c0b746e5SOllivier Robert 	} while(0)
67c0b746e5SOllivier Robert 
68c0b746e5SOllivier Robert #define sTVTOTS(tv, ts) \
69c0b746e5SOllivier Robert 	do { \
70c0b746e5SOllivier Robert 		int isneg = 0; \
71c0b746e5SOllivier Robert 		long usec; \
72c0b746e5SOllivier Robert 		(ts)->l_ui = (tv)->tv_sec; \
73c0b746e5SOllivier Robert 		usec = (tv)->tv_usec; \
74c0b746e5SOllivier Robert 		if (((tv)->tv_sec < 0) || ((tv)->tv_usec < 0)) { \
75c0b746e5SOllivier Robert 			usec = -usec; \
76c0b746e5SOllivier Robert 			(ts)->l_ui = -(ts)->l_ui; \
77c0b746e5SOllivier Robert 			isneg = 1; \
78c0b746e5SOllivier Robert 		} \
79c0b746e5SOllivier Robert 		TVUTOTSF(usec, (ts)->l_uf); \
80c0b746e5SOllivier Robert 		if (isneg) { \
81c0b746e5SOllivier Robert 			L_NEG((ts)); \
82c0b746e5SOllivier Robert 		} \
83c0b746e5SOllivier Robert 	} while(0)
84c0b746e5SOllivier Robert 
85c0b746e5SOllivier Robert /*
86c0b746e5SOllivier Robert  * TV_SHIFT is used to turn the table result into a usec value.  To round,
87c0b746e5SOllivier Robert  * add in TV_ROUNDBIT before shifting
88c0b746e5SOllivier Robert  */
89c0b746e5SOllivier Robert #define	TV_SHIFT	3
90c0b746e5SOllivier Robert #define	TV_ROUNDBIT	0x4
91c0b746e5SOllivier Robert 
92c0b746e5SOllivier Robert 
93c0b746e5SOllivier Robert /*
94c0b746e5SOllivier Robert  * Convert a time stamp fraction to microseconds.  The time stamp
95c0b746e5SOllivier Robert  * fraction is assumed to be unsigned.  To use this in a program, declare:
96c0b746e5SOllivier Robert  */
97c0b746e5SOllivier Robert extern long tstouslo[];
98c0b746e5SOllivier Robert extern long tstousmid[];
99c0b746e5SOllivier Robert extern long tstoushi[];
100c0b746e5SOllivier Robert 
101c0b746e5SOllivier Robert #define	TSFTOTVU(tsf, tvu) \
102c0b746e5SOllivier Robert 	(tvu) = (tstoushi[((tsf) >> 24) & 0xff] \
103c0b746e5SOllivier Robert 	    + tstousmid[((tsf) >> 16) & 0xff] \
104c0b746e5SOllivier Robert 	    + tstouslo[((tsf) >> 9) & 0x7f] \
105c0b746e5SOllivier Robert 	    + TV_ROUNDBIT) >> TV_SHIFT
106c0b746e5SOllivier Robert /*
107c0b746e5SOllivier Robert  * Convert a time stamp to a struct timeval.  The time stamp
108c0b746e5SOllivier Robert  * has to be positive.
109c0b746e5SOllivier Robert  */
110c0b746e5SOllivier Robert #define	TSTOTV(ts, tv) \
111c0b746e5SOllivier Robert 	do { \
112c0b746e5SOllivier Robert 		(tv)->tv_sec = (ts)->l_ui; \
113c0b746e5SOllivier Robert 		TSFTOTVU((ts)->l_uf, (tv)->tv_usec); \
114c0b746e5SOllivier Robert 		if ((tv)->tv_usec == 1000000) { \
115c0b746e5SOllivier Robert 			(tv)->tv_sec++; \
116c0b746e5SOllivier Robert 			(tv)->tv_usec = 0; \
117c0b746e5SOllivier Robert 		} \
118c0b746e5SOllivier Robert 	} while (0)
119c0b746e5SOllivier Robert 
120c0b746e5SOllivier Robert /*
121c0b746e5SOllivier Robert  * Convert milliseconds to a time stamp fraction.  This shouldn't be
122c0b746e5SOllivier Robert  * here, but it is convenient since the guys who use the definition will
123c0b746e5SOllivier Robert  * often be including this file anyway.
124c0b746e5SOllivier Robert  */
125c0b746e5SOllivier Robert extern u_long msutotsflo[];
126c0b746e5SOllivier Robert extern u_long msutotsfhi[];
127c0b746e5SOllivier Robert 
128c0b746e5SOllivier Robert #define	MSUTOTSF(msu, tsf) \
129c0b746e5SOllivier Robert 	(tsf) = msutotsfhi[((msu) >> 5) & 0x1f] + msutotsflo[(msu) & 0x1f]
130c0b746e5SOllivier Robert 
131c0b746e5SOllivier Robert extern	char *	tvtoa		P((const struct timeval *));
132c0b746e5SOllivier Robert extern	char *	utvtoa		P((const struct timeval *));
133