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