Home | History | Annotate | Line # | Download | only in sys
      1 /*	$NetBSD: timevar.h,v 1.52 2024/12/22 23:24:20 riastradh Exp $	*/
      2 
      3 /*
      4  *  Copyright (c) 2005, 2008, 2020 The NetBSD Foundation, Inc.
      5  *  All rights reserved.
      6  *
      7  *  Redistribution and use in source and binary forms, with or without
      8  *  modification, are permitted provided that the following conditions
      9  *  are met:
     10  *  1. Redistributions of source code must retain the above copyright
     11  *     notice, this list of conditions and the following disclaimer.
     12  *  2. Redistributions in binary form must reproduce the above copyright
     13  *     notice, this list of conditions and the following disclaimer in the
     14  *     documentation and/or other materials provided with the distribution.
     15  *
     16  *  THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  *  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  *  PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  *  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  *  POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 /*
     30  * Copyright (c) 1982, 1986, 1993
     31  *	The Regents of the University of California.  All rights reserved.
     32  *
     33  * Redistribution and use in source and binary forms, with or without
     34  * modification, are permitted provided that the following conditions
     35  * are met:
     36  * 1. Redistributions of source code must retain the above copyright
     37  *    notice, this list of conditions and the following disclaimer.
     38  * 2. Redistributions in binary form must reproduce the above copyright
     39  *    notice, this list of conditions and the following disclaimer in the
     40  *    documentation and/or other materials provided with the distribution.
     41  * 3. Neither the name of the University nor the names of its contributors
     42  *    may be used to endorse or promote products derived from this software
     43  *    without specific prior written permission.
     44  *
     45  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     55  * SUCH DAMAGE.
     56  *
     57  *	@(#)time.h	8.5 (Berkeley) 5/4/95
     58  */
     59 
     60 #ifndef _SYS_TIMEVAR_H_
     61 #define _SYS_TIMEVAR_H_
     62 
     63 #include <sys/atomic.h>
     64 #include <sys/callout.h>
     65 #include <sys/queue.h>
     66 #include <sys/signal.h>
     67 #include <sys/systm.h>
     68 
     69 struct itimer;
     70 LIST_HEAD(itlist, itimer);
     71 
     72 /*
     73  * Interval timer operations vector.
     74  *
     75  * Required fields:
     76  *
     77  *	- ito_fire: A function to be called when the itimer fires.
     78  *	  The timer implementation should perform whatever processing
     79  *	  is necessary for that timer type.
     80  *
     81  * Optional fields:
     82  *
     83  *	- ito_realtime_changed: A function that is called when the system
     84  *	  time (CLOCK_REALTIME) is called.
     85  */
     86 struct itimer_ops {
     87 	void	(*ito_fire)(struct itimer *);
     88 	void	(*ito_realtime_changed)(struct itimer *);
     89 };
     90 
     91 /*
     92  * Common interval timer data.
     93  */
     94 struct itimer {
     95 	union {
     96 		struct {
     97 			callout_t		it_ch;
     98 			LIST_ENTRY(itimer)	it_rtchgq;
     99 		} it_real;
    100 		struct {
    101 			struct itlist		*it_vlist;
    102 			LIST_ENTRY(itimer)	it_list;
    103 			bool			it_active;
    104 		} it_virtual;
    105 	};
    106 	const struct itimer_ops *it_ops;
    107 	struct itimerspec it_time;
    108 	clockid_t it_clockid;
    109 	int	it_overruns;	/* Overruns currently accumulating */
    110 	bool	it_dying;
    111 };
    112 
    113 #define	it_ch		it_real.it_ch
    114 #define	it_rtchgq	it_real.it_rtchgq
    115 
    116 #define	it_vlist	it_virtual.it_vlist
    117 #define	it_list		it_virtual.it_list
    118 #define	it_active	it_virtual.it_active
    119 
    120 /*
    121  * Structure used to manage timers in a process.
    122  */
    123 struct ptimer {
    124 	struct itimer pt_itimer;/* common interval timer data */
    125 
    126 	TAILQ_ENTRY(ptimer) pt_chain; /* link in signalling queue */
    127 	struct	sigevent pt_ev;	/* event notification info */
    128 	int	pt_poverruns;	/* Overruns associated w/ a delivery */
    129 	int	pt_entry;	/* slot in proc's timer table */
    130 	struct proc *pt_proc;	/* associated process */
    131 	bool	pt_queued;	/* true if linked into signalling queue */
    132 };
    133 
    134 #define	TIMER_MIN	4	/* [0..3] are reserved for setitimer(2) */
    135 				/* REAL=0,VIRTUAL=1,PROF=2,MONOTONIC=3 */
    136 #define	TIMER_MAX	36	/* 32 is minimum user timers per POSIX */
    137 #define	TIMERS_ALL	0
    138 #define	TIMERS_POSIX	1
    139 
    140 struct ptimers {
    141 	struct itlist pts_virtual;
    142 	struct itlist pts_prof;
    143 	struct itimer *pts_timers[TIMER_MAX];
    144 };
    145 
    146 /*
    147  * Functions for looking at our clock: [get]{bin,nano,micro}[up]time()
    148  *
    149  * Functions without the "get" prefix returns the best timestamp
    150  * we can produce in the given format.
    151  *
    152  * "bin"   == struct bintime  == seconds + 64 bit fraction of seconds.
    153  * "nano"  == struct timespec == seconds + nanoseconds.
    154  * "micro" == struct timeval  == seconds + microseconds.
    155  *
    156  * Functions containing "up" returns time relative to boot and
    157  * should be used for calculating time intervals.
    158  *
    159  * Functions without "up" returns GMT time.
    160  *
    161  * Functions with the "get" prefix returns a less precise result
    162  * much faster than the functions without "get" prefix and should
    163  * be used where a precision of 1/HZ (eg 10 msec on a 100HZ machine)
    164  * is acceptable or where performance is priority.
    165  * (NB: "precision", _not_ "resolution" !)
    166  *
    167  */
    168 
    169 void	binuptime(struct bintime *);
    170 void	nanouptime(struct timespec *);
    171 void	microuptime(struct timeval *);
    172 
    173 void	bintime(struct bintime *);
    174 void	nanotime(struct timespec *);
    175 void	microtime(struct timeval *);
    176 
    177 void	getbinuptime(struct bintime *);
    178 void	getnanouptime(struct timespec *);
    179 void	getmicrouptime(struct timeval *);
    180 
    181 void	getbintime(struct bintime *);
    182 void	getnanotime(struct timespec *);
    183 void	getmicrotime(struct timeval *);
    184 
    185 void	getbinboottime(struct bintime *);
    186 void	getnanoboottime(struct timespec *);
    187 void	getmicroboottime(struct timeval *);
    188 
    189 /* Other functions */
    190 int	ts2timo(clockid_t, int, struct timespec *, int *, struct timespec *);
    191 void	adjtime1(const struct timeval *, struct timeval *, struct proc *);
    192 int	clock_getres1(clockid_t, struct timespec *);
    193 int	clock_gettime1(clockid_t, struct timespec *);
    194 int	clock_settime1(struct proc *, clockid_t, const struct timespec *, bool);
    195 void	clock_timeleft(clockid_t, struct timespec *, struct timespec *);
    196 int	dogetitimer(struct proc *, int, struct itimerval *);
    197 int	dosetitimer(struct proc *, int, struct itimerval *);
    198 int	dotimer_gettime(int, struct proc *, struct itimerspec *);
    199 int	dotimer_settime(int, struct itimerspec *, struct itimerspec *, int,
    200 	    struct proc *);
    201 int	tshzto(const struct timespec *);
    202 int	tshztoup(const struct timespec *);
    203 int	tvhzto(const struct timeval *);
    204 void	inittimecounter(void);
    205 int	ppsratecheck(struct timeval *, int *, int);
    206 int	ratecheck(struct timeval *, const struct timeval *);
    207 int	settime(struct proc *p, struct timespec *);
    208 int	nanosleep1(struct lwp *, clockid_t, int, struct timespec *,
    209 	    struct timespec *);
    210 int	settimeofday1(const struct timeval *, bool,
    211 	    const void *, struct lwp *, bool);
    212 int	timer_create1(timer_t *, clockid_t, struct sigevent *, copyin_t,
    213 	    struct lwp *);
    214 int	inittimeleft(struct timespec *, struct timespec *);
    215 int	gettimeleft(struct timespec *, struct timespec *);
    216 void	timerupcall(struct lwp *);
    217 void	time_init(void);
    218 bool	time_wraps(struct timespec *, struct timespec *);
    219 
    220 void	itimer_init(struct itimer *, const struct itimer_ops *,
    221 	    clockid_t, struct itlist *);
    222 void	itimer_poison(struct itimer *);
    223 void	itimer_fini(struct itimer *);
    224 
    225 void	itimer_lock(void);
    226 void	itimer_unlock(void);
    227 bool	itimer_lock_held(void);		/* for diagnostic assertions only */
    228 int	itimer_settime(struct itimer *);
    229 void	itimer_gettime(const struct itimer *, struct itimerspec *);
    230 
    231 void	ptimer_tick(struct lwp *, bool);
    232 void	ptimers_free(struct proc *, int);
    233 
    234 #define	time_second	getrealtime()
    235 #define	time_uptime	getuptime()
    236 #define	time_uptime32	getuptime32()
    237 
    238 #ifdef __HAVE_ATOMIC64_LOADSTORE
    239 
    240 extern volatile time_t time__second;	/* current second in the epoch */
    241 extern volatile time_t time__uptime;	/* system uptime in seconds */
    242 
    243 static inline time_t
    244 getrealtime(void)
    245 {
    246 	return atomic_load_relaxed(&time__second);
    247 }
    248 
    249 static inline time_t
    250 getuptime(void)
    251 {
    252 	return atomic_load_relaxed(&time__uptime);
    253 }
    254 
    255 static inline time_t
    256 getboottime(void)
    257 {
    258 	return getrealtime() - getuptime();
    259 }
    260 
    261 static inline uint32_t
    262 getuptime32(void)
    263 {
    264 	return getuptime() & 0xffffffff;
    265 }
    266 
    267 #else
    268 
    269 time_t		getrealtime(void);
    270 time_t		getuptime(void);
    271 time_t		getboottime(void);
    272 uint32_t	getuptime32(void);
    273 
    274 #endif
    275 
    276 extern int time_adjusted;
    277 
    278 #define	DEFAULT_TIMEOUT_EPSILON						      \
    279 	(&(const struct bintime) {					      \
    280 		.sec = 0,						      \
    281 		.frac = ((uint64_t)1 << 32)/hz << 32,			      \
    282 	})
    283 
    284 static __inline time_t time_mono_to_wall(time_t t)
    285 {
    286 
    287 	return t + getboottime();
    288 }
    289 
    290 static __inline time_t time_wall_to_mono(time_t t)
    291 {
    292 
    293 	return t - getboottime();
    294 }
    295 
    296 #endif /* !_SYS_TIMEVAR_H_ */
    297