xref: /dragonfly/sys/sys/time.h (revision 1de703da)
1 /*
2  * Copyright (c) 1982, 1986, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)time.h	8.5 (Berkeley) 5/4/95
34  * $FreeBSD: src/sys/sys/time.h,v 1.42 1999/12/29 04:24:48 peter Exp $
35  * $DragonFly: src/sys/sys/time.h,v 1.2 2003/06/17 04:28:59 dillon Exp $
36  */
37 
38 #ifndef _SYS_TIME_H_
39 #define _SYS_TIME_H_
40 
41 #include <sys/types.h>
42 
43 /*
44  * Structure returned by gettimeofday(2) system call,
45  * and used in other calls.
46  */
47 struct timeval {
48 	long	tv_sec;		/* seconds */
49 	long	tv_usec;	/* and microseconds */
50 };
51 
52 #ifndef _TIMESPEC_DECLARED
53 #define _TIMESPEC_DECLARED
54 struct timespec {
55 	time_t	tv_sec;		/* seconds */
56 	long	tv_nsec;	/* and nanoseconds */
57 };
58 #endif
59 
60 #define	TIMEVAL_TO_TIMESPEC(tv, ts)					\
61 	do {								\
62 		(ts)->tv_sec = (tv)->tv_sec;				\
63 		(ts)->tv_nsec = (tv)->tv_usec * 1000;			\
64 	} while (0)
65 #define	TIMESPEC_TO_TIMEVAL(tv, ts)					\
66 	do {								\
67 		(tv)->tv_sec = (ts)->tv_sec;				\
68 		(tv)->tv_usec = (ts)->tv_nsec / 1000;			\
69 	} while (0)
70 
71 struct timezone {
72 	int	tz_minuteswest;	/* minutes west of Greenwich */
73 	int	tz_dsttime;	/* type of dst correction */
74 };
75 #define	DST_NONE	0	/* not on dst */
76 #define	DST_USA		1	/* USA style dst */
77 #define	DST_AUST	2	/* Australian style dst */
78 #define	DST_WET		3	/* Western European dst */
79 #define	DST_MET		4	/* Middle European dst */
80 #define	DST_EET		5	/* Eastern European dst */
81 #define	DST_CAN		6	/* Canada */
82 
83 /*
84  * Structure used to interface to the machine dependent hardware support
85  * for timekeeping.
86  *
87  * A timecounter is a (hard or soft) binary counter which has two properties:
88  *    * it runs at a fixed, known frequency.
89  *    * it must not roll over in less than (1 + delta)/HZ seconds.  "delta"
90  *	is expected to be less than 20 msec, but no hard data has been
91  *      collected on this.  16 bit at 5 MHz (31 msec) is known to work.
92  *
93  * get_timecount() reads the counter.
94  *
95  * counter_mask removes unimplemented bits from the count value.
96  *
97  * frequency is the counter frequency in hz.
98  *
99  * name is a short mnemonic name for this counter.
100  *
101  * cost is a measure of how long time it takes to read the counter.
102  *
103  * adjustment [PPM << 16] which means that the smallest unit of correction
104  *     you can apply amounts to 481.5 usec/year.
105  *
106  * scale_micro [2^32 * usec/tick].
107  * scale_nano_i [ns/tick].
108  * scale_nano_f [(ns/2^32)/tick].
109  *
110  * offset_count is the contents of the counter which corresponds to the
111  *     rest of the offset_* values.
112  *
113  * offset_sec [s].
114  * offset_micro [usec].
115  * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365...
116  *     attoseconds (10E-18) and before you ask: yes, they are in fact
117  *     called attoseconds, it comes from "atten" for 18 in Danish/Swedish.
118  *
119  * Each timecounter must supply an array of three timecounters, this is needed
120  * to guarantee atomicity in the code.  Index zero is used to transport
121  * modifications, for instance done with sysctl, into the timecounter being
122  * used in a safe way.  Such changes may be adopted with a delay of up to 1/HZ,
123  * index one & two are used alternately for the actual timekeeping.
124  *
125  * 'tc_avail' points to the next available (external) timecounter in a
126  *      circular queue.  This is only valid for index 0.
127  *
128  * `tc_other' points to the next "work" timecounter in a circular queue,
129  *      i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
130  *      We also use it to point from index 0 to index 1.
131  *
132  * `tc_tweak' points to index 0.
133  */
134 
135 struct timecounter;
136 typedef unsigned timecounter_get_t __P((struct timecounter *));
137 typedef void timecounter_pps_t __P((struct timecounter *));
138 
139 struct timecounter {
140 	/* These fields must be initialized by the driver. */
141 	timecounter_get_t	*tc_get_timecount;
142 	timecounter_pps_t	*tc_poll_pps;
143 	unsigned 		tc_counter_mask;
144 	u_int32_t		tc_frequency;
145 	char			*tc_name;
146 	void			*tc_priv;
147 	/* These fields will be managed by the generic code. */
148 	int64_t			tc_adjustment;
149 	u_int32_t		tc_scale_micro;
150 	u_int32_t		tc_scale_nano_i;
151 	u_int32_t		tc_scale_nano_f;
152 	unsigned 		tc_offset_count;
153 	u_int32_t		tc_offset_sec;
154 	u_int32_t		tc_offset_micro;
155 	u_int64_t		tc_offset_nano;
156 	struct timeval		tc_microtime;
157 	struct timespec		tc_nanotime;
158 	struct timecounter	*tc_avail;
159 	struct timecounter	*tc_other;
160 	struct timecounter	*tc_tweak;
161 };
162 
163 #ifdef _KERNEL
164 
165 /* Operations on timespecs */
166 #define	timespecclear(tvp)	((tvp)->tv_sec = (tvp)->tv_nsec = 0)
167 #define	timespecisset(tvp)	((tvp)->tv_sec || (tvp)->tv_nsec)
168 #define	timespeccmp(tvp, uvp, cmp)					\
169 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
170 	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :			\
171 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
172 #define timespecadd(vvp, uvp)						\
173 	do {								\
174 		(vvp)->tv_sec += (uvp)->tv_sec;				\
175 		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
176 		if ((vvp)->tv_nsec >= 1000000000) {			\
177 			(vvp)->tv_sec++;				\
178 			(vvp)->tv_nsec -= 1000000000;			\
179 		}							\
180 	} while (0)
181 #define timespecsub(vvp, uvp)						\
182 	do {								\
183 		(vvp)->tv_sec -= (uvp)->tv_sec;				\
184 		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
185 		if ((vvp)->tv_nsec < 0) {				\
186 			(vvp)->tv_sec--;				\
187 			(vvp)->tv_nsec += 1000000000;			\
188 		}							\
189 	} while (0)
190 
191 /* Operations on timevals. */
192 
193 #define	timevalclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
194 #define	timevalisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
195 #define	timevalcmp(tvp, uvp, cmp)					\
196 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
197 	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
198 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
199 
200 /* timevaladd and timevalsub are not inlined */
201 
202 #endif /* _KERNEL */
203 
204 #ifndef _KERNEL			/* NetBSD/OpenBSD compatable interfaces */
205 
206 #define	timerclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
207 #define	timerisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
208 #define	timercmp(tvp, uvp, cmp)					\
209 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
210 	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
211 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
212 #define timeradd(tvp, uvp, vvp)						\
213 	do {								\
214 		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
215 		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;	\
216 		if ((vvp)->tv_usec >= 1000000) {			\
217 			(vvp)->tv_sec++;				\
218 			(vvp)->tv_usec -= 1000000;			\
219 		}							\
220 	} while (0)
221 #define timersub(tvp, uvp, vvp)						\
222 	do {								\
223 		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
224 		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
225 		if ((vvp)->tv_usec < 0) {				\
226 			(vvp)->tv_sec--;				\
227 			(vvp)->tv_usec += 1000000;			\
228 		}							\
229 	} while (0)
230 #endif
231 
232 /*
233  * Names of the interval timers, and structure
234  * defining a timer setting.
235  */
236 #define	ITIMER_REAL	0
237 #define	ITIMER_VIRTUAL	1
238 #define	ITIMER_PROF	2
239 
240 struct	itimerval {
241 	struct	timeval it_interval;	/* timer interval */
242 	struct	timeval it_value;	/* current value */
243 };
244 
245 /*
246  * Getkerninfo clock information structure
247  */
248 struct clockinfo {
249 	int	hz;		/* clock frequency */
250 	int	tick;		/* micro-seconds per hz tick */
251 	int	tickadj;	/* clock skew rate for adjtime() */
252 	int	stathz;		/* statistics clock frequency */
253 	int	profhz;		/* profiling clock frequency */
254 };
255 
256 /* CLOCK_REALTIME and TIMER_ABSTIME are supposed to be in time.h */
257 
258 #ifndef CLOCK_REALTIME
259 #define CLOCK_REALTIME	0
260 #endif
261 #define CLOCK_VIRTUAL	1
262 #define CLOCK_PROF	2
263 
264 #define TIMER_RELTIME	0x0	/* relative timer */
265 #ifndef TIMER_ABSTIME
266 #define TIMER_ABSTIME	0x1	/* absolute timer */
267 #endif
268 
269 #ifdef _KERNEL
270 extern struct timecounter *timecounter;
271 extern time_t	time_second;
272 
273 void	getmicrouptime __P((struct timeval *tv));
274 void	getmicrotime __P((struct timeval *tv));
275 void	getnanouptime __P((struct timespec *tv));
276 void	getnanotime __P((struct timespec *tv));
277 void	init_timecounter __P((struct timecounter *tc));
278 int	itimerdecr __P((struct itimerval *itp, int usec));
279 int	itimerfix __P((struct timeval *tv));
280 void	microuptime __P((struct timeval *tv));
281 void	microtime __P((struct timeval *tv));
282 void	nanouptime __P((struct timespec *ts));
283 void	nanotime __P((struct timespec *ts));
284 void	set_timecounter __P((struct timespec *ts));
285 void	timevaladd __P((struct timeval *, struct timeval *));
286 void	timevalsub __P((struct timeval *, struct timeval *));
287 int	tvtohz __P((struct timeval *));
288 void	update_timecounter __P((struct timecounter *tc));
289 #else /* !_KERNEL */
290 #include <time.h>
291 
292 #include <sys/cdefs.h>
293 
294 __BEGIN_DECLS
295 int	adjtime __P((const struct timeval *, struct timeval *));
296 int	futimes __P((int, const struct timeval *));
297 int	getitimer __P((int, struct itimerval *));
298 int	gettimeofday __P((struct timeval *, struct timezone *));
299 int	lutimes __P((const char *, const struct timeval *));
300 int	setitimer __P((int, const struct itimerval *, struct itimerval *));
301 int	settimeofday __P((const struct timeval *, const struct timezone *));
302 int	utimes __P((const char *, const struct timeval *));
303 __END_DECLS
304 
305 #endif /* !_KERNEL */
306 
307 #endif /* !_SYS_TIME_H_ */
308