time.h revision 34901
11541Srgrimes/*
21541Srgrimes * Copyright (c) 1982, 1986, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 3. All advertising materials mentioning features or use of this software
141541Srgrimes *    must display the following acknowledgement:
151541Srgrimes *	This product includes software developed by the University of
161541Srgrimes *	California, Berkeley and its contributors.
171541Srgrimes * 4. Neither the name of the University nor the names of its contributors
181541Srgrimes *    may be used to endorse or promote products derived from this software
191541Srgrimes *    without specific prior written permission.
201541Srgrimes *
211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311541Srgrimes * SUCH DAMAGE.
321541Srgrimes *
3314487Shsu *	@(#)time.h	8.5 (Berkeley) 5/4/95
3434901Sphk * $Id: time.h,v 1.20 1998/03/04 10:26:44 dufault Exp $
351541Srgrimes */
361541Srgrimes
371541Srgrimes#ifndef _SYS_TIME_H_
381541Srgrimes#define _SYS_TIME_H_
391541Srgrimes
4014487Shsu#include <sys/types.h>
4114487Shsu
421541Srgrimes/*
431541Srgrimes * Structure returned by gettimeofday(2) system call,
441541Srgrimes * and used in other calls.
451541Srgrimes */
461541Srgrimesstruct timeval {
471541Srgrimes	long	tv_sec;		/* seconds */
481541Srgrimes	long	tv_usec;	/* and microseconds */
491541Srgrimes};
501541Srgrimes
5125775Speter#ifndef _TIMESPEC_DECLARED
5225775Speter#define _TIMESPEC_DECLARED
531541Srgrimesstruct timespec {
5418397Snate	time_t	tv_sec;		/* seconds */
5518397Snate	long	tv_nsec;	/* and nanoseconds */
561541Srgrimes};
5725775Speter#endif
581541Srgrimes
591541Srgrimes#define	TIMEVAL_TO_TIMESPEC(tv, ts) {					\
6018397Snate	(ts)->tv_sec = (tv)->tv_sec;					\
6118397Snate	(ts)->tv_nsec = (tv)->tv_usec * 1000;				\
621541Srgrimes}
631541Srgrimes#define	TIMESPEC_TO_TIMEVAL(tv, ts) {					\
6418397Snate	(tv)->tv_sec = (ts)->tv_sec;					\
6518397Snate	(tv)->tv_usec = (ts)->tv_nsec / 1000;				\
661541Srgrimes}
671541Srgrimes
681541Srgrimesstruct timezone {
691541Srgrimes	int	tz_minuteswest;	/* minutes west of Greenwich */
701541Srgrimes	int	tz_dsttime;	/* type of dst correction */
711541Srgrimes};
721541Srgrimes#define	DST_NONE	0	/* not on dst */
731541Srgrimes#define	DST_USA		1	/* USA style dst */
741541Srgrimes#define	DST_AUST	2	/* Australian style dst */
751541Srgrimes#define	DST_WET		3	/* Western European dst */
761541Srgrimes#define	DST_MET		4	/* Middle European dst */
771541Srgrimes#define	DST_EET		5	/* Eastern European dst */
781541Srgrimes#define	DST_CAN		6	/* Canada */
791541Srgrimes
8033690Sphk/*
8134901Sphk * Structure used to interface to the machine dependent hardware support
8234901Sphk * for timekeeping.
8333690Sphk *
8434901Sphk * A timecounter is a (hard or soft) binary counter which has two properties:
8534901Sphk *    * it runs at a fixed, known frequency.
8634901Sphk *    * it must not roll over in less than (1 + delta)/HZ seconds.  "delta"
8734901Sphk *	is expected to be less than 20 msec, but no hard data has been
8834901Sphk *      collected on this.  16 bit at 5 MHz (31 msec) is known to work.
8933690Sphk *
9034901Sphk * get_timedelta() returns difference between the counter now and offset_count.
9133690Sphk *
9234901Sphk * get_timecount() reads the counter.
9333690Sphk *
9434901Sphk * counter_mask removes unimplemented bits from the count value.
9533690Sphk *
9634901Sphk * frequency is the counter frequency in hz.
9733690Sphk *
9833690Sphk * name is a short mnemonic name for this counter.
9933690Sphk *
10033690Sphk * cost is a measure of how long time it takes to read the counter.
10133690Sphk *
10233690Sphk * adjustment [PPM << 16] which means that the smallest unit of correction
10333690Sphk *     you can apply amounts to 481.5 usec/year.
10433690Sphk *
10534901Sphk * scale_micro [2^32 * usec/tick].
10634901Sphk * scale_nano_i [ns/tick].
10734901Sphk * scale_nano_f [(ns/2^32)/tick].
10833690Sphk *
10933690Sphk * offset_count is the contents of the counter which corresponds to the
11034901Sphk *     rest of the offset_* values.
11133690Sphk *
11234901Sphk * offset_sec [s].
11334901Sphk * offset_micro [usec].
11433690Sphk * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365...
11533690Sphk *     attoseconds (10E-18) and before you ask: yes, they are in fact
11633690Sphk *     called attoseconds, it comes from "atten" for 18 in Danish/Swedish.
11734901Sphk *
11834901Sphk * Each timecounter must supply an array of three timecounters, this is needed
11934901Sphk * to guarantee atomicity in the code.  Index zero is used to transport
12034901Sphk * modifications, for instance done with sysctl, into the timecounter being
12134901Sphk * used in a safe way.  Such changes may be adopted with a delay of up to 1/HZ,
12234901Sphk * index one & two are used alternately for the actual timekeeping.
12334901Sphk *
12434901Sphk * `other' points to the opposite "work" timecounter, ie, in index one it
12534901Sphk *      points to index two and vice versa
12634901Sphk *
12734901Sphk * `tweak' points to index zero.
12834901Sphk *
12933690Sphk */
13033690Sphk
13133690Sphkstruct timecounter;
13234901Sphktypedef unsigned timecounter_get_t __P((struct timecounter *));
13333690Sphktypedef	u_int64_t timecounter_delta_t __P((void));
13433690Sphk
13533690Sphkstruct timecounter {
13634901Sphk	/* These fields must be initialized by the driver. */
13733690Sphk	timecounter_get_t	*get_timedelta;
13833690Sphk	timecounter_delta_t	*get_timecount;
13933690Sphk	u_int64_t		counter_mask;
14033690Sphk	u_int32_t		frequency;
14133690Sphk	char			*name;
14234901Sphk	/* These fields will be managed by the generic code. */
14333690Sphk	int			cost;
14433690Sphk	int32_t			adjustment;
14533690Sphk	u_int32_t		scale_micro;
14633690Sphk	u_int32_t		scale_nano_i;
14733690Sphk	u_int32_t		scale_nano_f;
14833690Sphk	u_int64_t		offset_count;
14933690Sphk	u_int32_t		offset_sec;
15033690Sphk	u_int32_t		offset_micro;
15133690Sphk	u_int64_t		offset_nano;
15233690Sphk	struct timecounter	*other;
15333690Sphk	struct timecounter	*tweak;
15433690Sphk};
15533690Sphk
1561541Srgrimes/* Operations on timevals. */
1571541Srgrimes#define	timerclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
1581541Srgrimes#define	timerisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
1591541Srgrimes#define	timercmp(tvp, uvp, cmp)						\
1601541Srgrimes	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
1611541Srgrimes	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
1621541Srgrimes	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
16321099Speter#ifndef KERNEL		/* use timevaladd/timevalsub in kernel */
16421099Speter/* NetBSD/OpenBSD compatable interfaces */
16521099Speter#define timeradd(tvp, uvp, vvp)						\
16621099Speter	do {								\
16721099Speter		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
16821099Speter		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;	\
16921099Speter		if ((vvp)->tv_usec >= 1000000) {			\
17021099Speter			(vvp)->tv_sec++;				\
17121099Speter			(vvp)->tv_usec -= 1000000;			\
17221099Speter		}							\
17321099Speter	} while (0)
17421099Speter#define timersub(tvp, uvp, vvp)						\
17521099Speter	do {								\
17621099Speter		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
17721099Speter		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
17821099Speter		if ((vvp)->tv_usec < 0) {				\
17921099Speter			(vvp)->tv_sec--;				\
18021099Speter			(vvp)->tv_usec += 1000000;			\
18121099Speter		}							\
18221099Speter	} while (0)
18321099Speter#endif
1841541Srgrimes
1851541Srgrimes/*
1861541Srgrimes * Names of the interval timers, and structure
1871541Srgrimes * defining a timer setting.
1881541Srgrimes */
1891541Srgrimes#define	ITIMER_REAL	0
1901541Srgrimes#define	ITIMER_VIRTUAL	1
1911541Srgrimes#define	ITIMER_PROF	2
1921541Srgrimes
1931541Srgrimesstruct	itimerval {
1941541Srgrimes	struct	timeval it_interval;	/* timer interval */
1951541Srgrimes	struct	timeval it_value;	/* current value */
1961541Srgrimes};
1971541Srgrimes
1981541Srgrimes/*
1991541Srgrimes * Getkerninfo clock information structure
2001541Srgrimes */
2011541Srgrimesstruct clockinfo {
2021541Srgrimes	int	hz;		/* clock frequency */
2031541Srgrimes	int	tick;		/* micro-seconds per hz tick */
20426897Sjhay	int	tickadj;	/* clock skew rate for adjtime() */
2051541Srgrimes	int	stathz;		/* statistics clock frequency */
2061541Srgrimes	int	profhz;		/* profiling clock frequency */
2071541Srgrimes};
2081541Srgrimes
20934030Sdufault/* CLOCK_REALTIME and TIMER_ABSTIME are supposed to be in time.h */
21034030Sdufault
21134030Sdufault#ifndef CLOCK_REALTIME
21225578Speter#define CLOCK_REALTIME	0
21334030Sdufault#endif
21425578Speter#define CLOCK_VIRTUAL	1
21525578Speter#define CLOCK_PROF	2
21625578Speter
21725578Speter#define TIMER_RELTIME	0x0	/* relative timer */
21834030Sdufault#ifndef TIMER_ABSTIME
21925578Speter#define TIMER_ABSTIME	0x1	/* absolute timer */
22034030Sdufault#endif
22125578Speter
2222112Swollman#ifdef KERNEL
22333690Sphkextern struct timecounter *timecounter;
22433690Sphk
22533690Sphkvoid	forward_timecounter __P((void));
22634901Sphkvoid	getmicrotime __P((struct timeval *tv));
22734901Sphkvoid	getnanotime __P((struct timespec *tv));
22834901Sphk#define	gettime(xxx) getmicrotime(xxx)	/* XXX be compatible */
22934901Sphkvoid	init_timecounter __P((struct timecounter *tc));
23014487Shsuint	itimerfix __P((struct timeval *tv));
23114487Shsuint	itimerdecr __P((struct itimerval *itp, int usec));
23233690Sphkvoid	microtime __P((struct timeval *tv));
23333690Sphkvoid	nanotime __P((struct timespec *ts));
23433690Sphkvoid	second_overflow __P((u_int32_t *psec));
23534901Sphkvoid	set_timecounter __P((struct timespec *ts));
2363484Sphkvoid	timevaladd __P((struct timeval *, struct timeval *));
2373484Sphkvoid	timevalsub __P((struct timeval *, struct timeval *));
23814487Shsu#else /* !KERNEL */
2391541Srgrimes#include <time.h>
2401541Srgrimes
2411541Srgrimes#include <sys/cdefs.h>
2421541Srgrimes
2431541Srgrimes__BEGIN_DECLS
2441541Srgrimesint	adjtime __P((const struct timeval *, struct timeval *));
2451541Srgrimesint	getitimer __P((int, struct itimerval *));
2461541Srgrimesint	gettimeofday __P((struct timeval *, struct timezone *));
2471541Srgrimesint	setitimer __P((int, const struct itimerval *, struct itimerval *));
2481541Srgrimesint	settimeofday __P((const struct timeval *, const struct timezone *));
2491541Srgrimesint	utimes __P((const char *, const struct timeval *));
2501541Srgrimes__END_DECLS
2511541Srgrimes
2521541Srgrimes#endif /* !KERNEL */
2531541Srgrimes
2541541Srgrimes#endif /* !_SYS_TIME_H_ */
255