File:  [DragonFly] / src / sys / sys / time.h
Revision 1.5: download - view: text, annotated - select for diffs
Sun Nov 9 02:22:37 2003 UTC (10 years, 10 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
Core integer types header file reorganization stage 1/2: Create and/or modify
intttypes.h and stdint.h plus the opaque underlying support in sys/ and
machine/ according to the OpenGroup specifications.

These changes are loosely based on FreeBSD-5 but use far saner type names
and include dependancies.

    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.5 2003/11/09 02:22:37 dillon Exp $
   36:  */
   37: 
   38: #ifndef _SYS_TIME_H_
   39: #define _SYS_TIME_H_
   40: 
   41: #ifndef _SYS_TYPES_H_
   42: #include <sys/types.h>
   43: #endif
   44: 
   45: /*
   46:  * Structure returned by gettimeofday(2) system call,
   47:  * and used in other calls.
   48:  */
   49: struct timeval {
   50: 	long	tv_sec;		/* seconds */
   51: 	long	tv_usec;	/* and microseconds */
   52: };
   53: 
   54: #ifndef _TIMESPEC_DECLARED
   55: #define _TIMESPEC_DECLARED
   56: struct timespec {
   57: 	time_t	tv_sec;		/* seconds */
   58: 	long	tv_nsec;	/* and nanoseconds */
   59: };
   60: #endif
   61: 
   62: #define	TIMEVAL_TO_TIMESPEC(tv, ts)					\
   63: 	do {								\
   64: 		(ts)->tv_sec = (tv)->tv_sec;				\
   65: 		(ts)->tv_nsec = (tv)->tv_usec * 1000;			\
   66: 	} while (0)
   67: #define	TIMESPEC_TO_TIMEVAL(tv, ts)					\
   68: 	do {								\
   69: 		(tv)->tv_sec = (ts)->tv_sec;				\
   70: 		(tv)->tv_usec = (ts)->tv_nsec / 1000;			\
   71: 	} while (0)
   72: 
   73: struct timezone {
   74: 	int	tz_minuteswest;	/* minutes west of Greenwich */
   75: 	int	tz_dsttime;	/* type of dst correction */
   76: };
   77: #define	DST_NONE	0	/* not on dst */
   78: #define	DST_USA		1	/* USA style dst */
   79: #define	DST_AUST	2	/* Australian style dst */
   80: #define	DST_WET		3	/* Western European dst */
   81: #define	DST_MET		4	/* Middle European dst */
   82: #define	DST_EET		5	/* Eastern European dst */
   83: #define	DST_CAN		6	/* Canada */
   84: 
   85: /*
   86:  * Structure used to interface to the machine dependent hardware support
   87:  * for timekeeping.
   88:  *
   89:  * A timecounter is a (hard or soft) binary counter which has two properties:
   90:  *    * it runs at a fixed, known frequency.
   91:  *    * it must not roll over in less than (1 + delta)/HZ seconds.  "delta"
   92:  *	is expected to be less than 20 msec, but no hard data has been 
   93:  *      collected on this.  16 bit at 5 MHz (31 msec) is known to work.
   94:  *
   95:  * get_timecount() reads the counter.
   96:  *
   97:  * counter_mask removes unimplemented bits from the count value.
   98:  *
   99:  * frequency is the counter frequency in hz.
  100:  *
  101:  * name is a short mnemonic name for this counter.
  102:  *
  103:  * cost is a measure of how long time it takes to read the counter.
  104:  *
  105:  * adjustment [PPM << 16] which means that the smallest unit of correction
  106:  *     you can apply amounts to 481.5 usec/year.
  107:  *
  108:  * scale_micro [2^32 * usec/tick].
  109:  * scale_nano_i [ns/tick].
  110:  * scale_nano_f [(ns/2^32)/tick].
  111:  *
  112:  * offset_count is the contents of the counter which corresponds to the
  113:  *     rest of the offset_* values.
  114:  *
  115:  * offset_sec [s].
  116:  * offset_micro [usec].
  117:  * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365...
  118:  *     attoseconds (10E-18) and before you ask: yes, they are in fact 
  119:  *     called attoseconds, it comes from "atten" for 18 in Danish/Swedish.
  120:  *
  121:  * Each timecounter must supply an array of three timecounters, this is needed
  122:  * to guarantee atomicity in the code.  Index zero is used to transport 
  123:  * modifications, for instance done with sysctl, into the timecounter being 
  124:  * used in a safe way.  Such changes may be adopted with a delay of up to 1/HZ,
  125:  * index one & two are used alternately for the actual timekeeping.
  126:  *
  127:  * 'tc_avail' points to the next available (external) timecounter in a
  128:  *      circular queue.  This is only valid for index 0.
  129:  *
  130:  * `tc_other' points to the next "work" timecounter in a circular queue,
  131:  *      i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
  132:  *      We also use it to point from index 0 to index 1.
  133:  *
  134:  * `tc_tweak' points to index 0.
  135:  */
  136: 
  137: struct timecounter;
  138: typedef unsigned timecounter_get_t (struct timecounter *);
  139: typedef void timecounter_pps_t (struct timecounter *);
  140: 
  141: struct timecounter {
  142: 	/* These fields must be initialized by the driver. */
  143: 	timecounter_get_t	*tc_get_timecount;
  144: 	timecounter_pps_t	*tc_poll_pps;
  145: 	unsigned 		tc_counter_mask;
  146: 	u_int32_t		tc_frequency;
  147: 	char			*tc_name;
  148: 	void			*tc_priv;
  149: 	/* These fields will be managed by the generic code. */
  150: 	int64_t			tc_adjustment;
  151: 	u_int32_t		tc_scale_micro;
  152: 	u_int32_t		tc_scale_nano_i;
  153: 	u_int32_t		tc_scale_nano_f;
  154: 	unsigned 		tc_offset_count;
  155: 	u_int32_t		tc_offset_sec;
  156: 	u_int32_t		tc_offset_micro;
  157: 	u_int64_t		tc_offset_nano;
  158: 	struct timeval		tc_microtime;
  159: 	struct timespec		tc_nanotime;
  160: 	struct timecounter	*tc_avail;
  161: 	struct timecounter	*tc_other;
  162: 	struct timecounter	*tc_tweak;
  163: };
  164: 
  165: #ifdef _KERNEL
  166: 
  167: /* Operations on timespecs */
  168: #define	timespecclear(tvp)	((tvp)->tv_sec = (tvp)->tv_nsec = 0)
  169: #define	timespecisset(tvp)	((tvp)->tv_sec || (tvp)->tv_nsec)
  170: #define	timespeccmp(tvp, uvp, cmp)					\
  171: 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
  172: 	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :			\
  173: 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
  174: #define timespecadd(vvp, uvp)						\
  175: 	do {								\
  176: 		(vvp)->tv_sec += (uvp)->tv_sec;				\
  177: 		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
  178: 		if ((vvp)->tv_nsec >= 1000000000) {			\
  179: 			(vvp)->tv_sec++;				\
  180: 			(vvp)->tv_nsec -= 1000000000;			\
  181: 		}							\
  182: 	} while (0)
  183: #define timespecsub(vvp, uvp)						\
  184: 	do {								\
  185: 		(vvp)->tv_sec -= (uvp)->tv_sec;				\
  186: 		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
  187: 		if ((vvp)->tv_nsec < 0) {				\
  188: 			(vvp)->tv_sec--;				\
  189: 			(vvp)->tv_nsec += 1000000000;			\
  190: 		}							\
  191: 	} while (0)
  192: 
  193: /* Operations on timevals. */
  194: 
  195: #define	timevalclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
  196: #define	timevalisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
  197: #define	timevalcmp(tvp, uvp, cmp)					\
  198: 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
  199: 	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
  200: 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
  201: 
  202: /* timevaladd and timevalsub are not inlined */
  203: 
  204: #endif /* _KERNEL */
  205: 
  206: #ifndef _KERNEL			/* NetBSD/OpenBSD compatable interfaces */
  207: 
  208: #define	timerclear(tvp)		(tvp)->tv_sec = (tvp)->tv_usec = 0
  209: #define	timerisset(tvp)		((tvp)->tv_sec || (tvp)->tv_usec)
  210: #define	timercmp(tvp, uvp, cmp)					\
  211: 	(((tvp)->tv_sec == (uvp)->tv_sec) ?				\
  212: 	    ((tvp)->tv_usec cmp (uvp)->tv_usec) :			\
  213: 	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
  214: #define timeradd(tvp, uvp, vvp)						\
  215: 	do {								\
  216: 		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
  217: 		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;	\
  218: 		if ((vvp)->tv_usec >= 1000000) {			\
  219: 			(vvp)->tv_sec++;				\
  220: 			(vvp)->tv_usec -= 1000000;			\
  221: 		}							\
  222: 	} while (0)
  223: #define timersub(tvp, uvp, vvp)						\
  224: 	do {								\
  225: 		(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;		\
  226: 		(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;	\
  227: 		if ((vvp)->tv_usec < 0) {				\
  228: 			(vvp)->tv_sec--;				\
  229: 			(vvp)->tv_usec += 1000000;			\
  230: 		}							\
  231: 	} while (0)
  232: #endif
  233: 
  234: /*
  235:  * Names of the interval timers, and structure
  236:  * defining a timer setting.
  237:  */
  238: #define	ITIMER_REAL	0
  239: #define	ITIMER_VIRTUAL	1
  240: #define	ITIMER_PROF	2
  241: 
  242: struct	itimerval {
  243: 	struct	timeval it_interval;	/* timer interval */
  244: 	struct	timeval it_value;	/* current value */
  245: };
  246: 
  247: /*
  248:  * Getkerninfo clock information structure
  249:  */
  250: struct clockinfo {
  251: 	int	hz;		/* clock frequency */
  252: 	int	tick;		/* micro-seconds per hz tick */
  253: 	int	tickadj;	/* clock skew rate for adjtime() */
  254: 	int	stathz;		/* statistics clock frequency */
  255: 	int	profhz;		/* profiling clock frequency */
  256: };
  257: 
  258: /* CLOCK_REALTIME and TIMER_ABSTIME are supposed to be in time.h */
  259: 
  260: #ifndef CLOCK_REALTIME
  261: #define CLOCK_REALTIME	0
  262: #endif
  263: #define CLOCK_VIRTUAL	1
  264: #define CLOCK_PROF	2
  265: 
  266: #define TIMER_RELTIME	0x0	/* relative timer */
  267: #ifndef TIMER_ABSTIME
  268: #define TIMER_ABSTIME	0x1	/* absolute timer */
  269: #endif
  270: 
  271: #ifdef _KERNEL
  272: extern struct timecounter *timecounter;
  273: extern time_t	time_second;
  274: 
  275: void	getmicrouptime (struct timeval *tv);
  276: void	getmicrotime (struct timeval *tv);
  277: void	getnanouptime (struct timespec *tv);
  278: void	getnanotime (struct timespec *tv);
  279: void	init_timecounter (struct timecounter *tc);
  280: int	itimerdecr (struct itimerval *itp, int usec);
  281: int	itimerfix (struct timeval *tv);
  282: int 	ppsratecheck (struct timeval *, int *, int usec);
  283: int 	ratecheck (struct timeval *, const struct timeval *);
  284: void	microuptime (struct timeval *tv);
  285: void	microtime (struct timeval *tv);
  286: void	nanouptime (struct timespec *ts);
  287: void	nanotime (struct timespec *ts);
  288: void	set_timecounter (struct timespec *ts);
  289: void	timevaladd (struct timeval *, struct timeval *);
  290: void	timevalsub (struct timeval *, struct timeval *);
  291: int	tvtohz (struct timeval *);
  292: void	update_timecounter (struct timecounter *tc);
  293: #else /* !_KERNEL */
  294: #include <time.h>
  295: 
  296: #include <sys/cdefs.h>
  297: 
  298: __BEGIN_DECLS
  299: int	adjtime (const struct timeval *, struct timeval *);
  300: int	futimes (int, const struct timeval *);
  301: int	getitimer (int, struct itimerval *);
  302: int	gettimeofday (struct timeval *, struct timezone *);
  303: int	lutimes (const char *, const struct timeval *);
  304: int	setitimer (int, const struct itimerval *, struct itimerval *);
  305: int	settimeofday (const struct timeval *, const struct timezone *);
  306: int	utimes (const char *, const struct timeval *);
  307: __END_DECLS
  308: 
  309: #endif /* !_KERNEL */
  310: 
  311: #endif /* !_SYS_TIME_H_ */