ntp_unixtime.h revision 82498
1185377Ssam/*
2185377Ssam * ntp_unixtime.h - contains constants and macros for converting between
3185377Ssam *		    NTP time stamps (l_fp) and Unix times (struct timeval)
4185377Ssam */
5185377Ssam
6185377Ssam#include "ntp_types.h"
7185377Ssam
8185377Ssam/* gettimeofday() takes two args in BSD and only one in SYSV */
9185377Ssam# if defined(HAVE_SYS_TIMERS_H) && defined(HAVE_GETCLOCK)
10185377Ssam#  include <sys/timers.h>
11185377Ssamint getclock (int clock_type, struct timespec *tp);
12185377Ssam/* Don't #define GETTIMEOFDAY because we shouldn't be using it in this case. */
13185377Ssam#   define SETTIMEOFDAY(a, b) (settimeofday(a, b))
14185377Ssam# else /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
15185377Ssam#  ifdef SYSV_TIMEOFDAY
16185377Ssam#   define GETTIMEOFDAY(a, b) (gettimeofday(a))
17185377Ssam#   define SETTIMEOFDAY(a, b) (settimeofday(a))
18185377Ssam#  else /* ! SYSV_TIMEOFDAY */
19185377Ssam#if defined SYS_CYGWIN32
20185377Ssam#   define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
21185377Ssam#   define SETTIMEOFDAY(a, b) (settimeofday_NT(a))
22185377Ssam#else
23185377Ssam#   define GETTIMEOFDAY(a, b) (gettimeofday(a, b))
24185377Ssam#   define SETTIMEOFDAY(a, b) (settimeofday(a, b))
25185377Ssam#endif
26185377Ssam#  endif /* SYSV_TIMEOFDAY */
27185377Ssam# endif /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */
28185377Ssam
29185377Ssam/*
30185377Ssam * Time of day conversion constant.  Ntp's time scale starts in 1900,
31185377Ssam * Unix in 1970.
32185377Ssam */
33185377Ssam#define	JAN_1970	0x83aa7e80	/* 2208988800 1970 - 1900 in seconds */
34185377Ssam
35185377Ssam/*
36185377Ssam * These constants are used to round the time stamps computed from
37185377Ssam * a struct timeval to the microsecond (more or less).  This keeps
38185377Ssam * things neat.
39185377Ssam */
40185377Ssam#define	TS_MASK		0xfffff000	/* mask to usec, for time stamps */
41185377Ssam#define	TS_ROUNDBIT	0x00000800	/* round at this bit */
42185377Ssam
43185377Ssam
44185377Ssam/*
45185377Ssam * Convert usec to a time stamp fraction.  If you use this the program
46185377Ssam * must include the following declarations:
47185377Ssam */
48185377Ssamextern u_long ustotslo[];
49185377Ssamextern u_long ustotsmid[];
50185377Ssamextern u_long ustotshi[];
51185377Ssam
52185377Ssam#define	TVUTOTSF(tvu, tsf) \
53185377Ssam	(tsf) = ustotslo[(tvu) & 0xff] \
54185377Ssam	    + ustotsmid[((tvu) >> 8) & 0xff] \
55185377Ssam	    + ustotshi[((tvu) >> 16) & 0xf]
56185377Ssam
57185377Ssam/*
58185377Ssam * Convert a struct timeval to a time stamp.
59185377Ssam */
60185377Ssam#define TVTOTS(tv, ts) \
61185377Ssam	do { \
62185377Ssam		(ts)->l_ui = (u_long)(tv)->tv_sec; \
63185377Ssam		TVUTOTSF((tv)->tv_usec, (ts)->l_uf); \
64185377Ssam	} while(0)
65185377Ssam
66185377Ssam#define sTVTOTS(tv, ts) \
67185377Ssam	do { \
68185377Ssam		int isneg = 0; \
69185377Ssam		long usec; \
70185377Ssam		(ts)->l_ui = (tv)->tv_sec; \
71185377Ssam		usec = (tv)->tv_usec; \
72185377Ssam		if (((tv)->tv_sec < 0) || ((tv)->tv_usec < 0)) { \
73185377Ssam			usec = -usec; \
74185377Ssam			(ts)->l_ui = -(ts)->l_ui; \
75185377Ssam			isneg = 1; \
76185377Ssam		} \
77185377Ssam		TVUTOTSF(usec, (ts)->l_uf); \
78185377Ssam		if (isneg) { \
79185377Ssam			L_NEG((ts)); \
80185377Ssam		} \
81185377Ssam	} while(0)
82185377Ssam
83185377Ssam/*
84185377Ssam * TV_SHIFT is used to turn the table result into a usec value.  To round,
85185377Ssam * add in TV_ROUNDBIT before shifting
86185377Ssam */
87185377Ssam#define	TV_SHIFT	3
88185377Ssam#define	TV_ROUNDBIT	0x4
89185377Ssam
90185377Ssam
91185377Ssam/*
92185377Ssam * Convert a time stamp fraction to microseconds.  The time stamp
93185377Ssam * fraction is assumed to be unsigned.  To use this in a program, declare:
94185377Ssam */
95185377Ssamextern long tstouslo[];
96185377Ssamextern long tstousmid[];
97185377Ssamextern long tstoushi[];
98185377Ssam
99185377Ssam#define	TSFTOTVU(tsf, tvu) \
100185377Ssam	(tvu) = (tstoushi[((tsf) >> 24) & 0xff] \
101185377Ssam	    + tstousmid[((tsf) >> 16) & 0xff] \
102185377Ssam	    + tstouslo[((tsf) >> 9) & 0x7f] \
103185377Ssam	    + TV_ROUNDBIT) >> TV_SHIFT
104185377Ssam/*
105185377Ssam * Convert a time stamp to a struct timeval.  The time stamp
106185377Ssam * has to be positive.
107185377Ssam */
108185377Ssam#define	TSTOTV(ts, tv) \
109185377Ssam	do { \
110185377Ssam		(tv)->tv_sec = (ts)->l_ui; \
111185377Ssam		TSFTOTVU((ts)->l_uf, (tv)->tv_usec); \
112185377Ssam		if ((tv)->tv_usec == 1000000) { \
113185377Ssam			(tv)->tv_sec++; \
114185377Ssam			(tv)->tv_usec = 0; \
115185377Ssam		} \
116185377Ssam	} while (0)
117185377Ssam
118185377Ssam/*
119185377Ssam * Convert milliseconds to a time stamp fraction.  This shouldn't be
120185377Ssam * here, but it is convenient since the guys who use the definition will
121185377Ssam * often be including this file anyway.
122185377Ssam */
123185377Ssamextern u_long msutotsflo[];
124185377Ssamextern u_long msutotsfhi[];
125185377Ssam
126185377Ssam#define	MSUTOTSF(msu, tsf) \
127185377Ssam	(tsf) = msutotsfhi[((msu) >> 5) & 0x1f] + msutotsflo[(msu) & 0x1f]
128185377Ssam
129185377Ssamextern	char *	tvtoa		P((const struct timeval *));
130185377Ssamextern	char *	utvtoa		P((const struct timeval *));
131185377Ssam