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