kern_time.c revision 139804
1139804Simp/*- 21541Srgrimes * Copyright (c) 1982, 1986, 1989, 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 * 4. Neither the name of the University nor the names of its contributors 141541Srgrimes * may be used to endorse or promote products derived from this software 151541Srgrimes * without specific prior written permission. 161541Srgrimes * 171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271541Srgrimes * SUCH DAMAGE. 281541Srgrimes * 291541Srgrimes * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 301541Srgrimes */ 311541Srgrimes 32116182Sobrien#include <sys/cdefs.h> 33116182Sobrien__FBSDID("$FreeBSD: head/sys/kern/kern_time.c 139804 2005-01-06 23:35:40Z imp $"); 34116182Sobrien 35106369Srwatson#include "opt_mac.h" 36106369Srwatson 371541Srgrimes#include <sys/param.h> 3848274Speter#include <sys/systm.h> 3976166Smarkm#include <sys/lock.h> 4076166Smarkm#include <sys/mutex.h> 4112221Sbde#include <sys/sysproto.h> 421541Srgrimes#include <sys/resourcevar.h> 433308Sphk#include <sys/signalvar.h> 441541Srgrimes#include <sys/kernel.h> 45106369Srwatson#include <sys/mac.h> 4625583Speter#include <sys/sysent.h> 471541Srgrimes#include <sys/proc.h> 4825656Speter#include <sys/time.h> 4958377Sphk#include <sys/timetc.h> 501541Srgrimes#include <sys/vnode.h> 5176166Smarkm 5226335Speter#include <vm/vm.h> 5326335Speter#include <vm/vm_extern.h> 541541Srgrimes 55110299Sphkint tz_minuteswest; 56110299Sphkint tz_dsttime; 579369Sdg 588876Srgrimes/* 591541Srgrimes * Time of day and interval timer support. 601541Srgrimes * 611541Srgrimes * These routines provide the kernel entry points to get and set 621541Srgrimes * the time-of-day and per-process interval timers. Subroutines 631541Srgrimes * here provide support for adding and subtracting timeval structures 641541Srgrimes * and decrementing interval timers, optionally reloading the interval 651541Srgrimes * timers when they expire. 661541Srgrimes */ 671541Srgrimes 6892723Salfredstatic int nanosleep1(struct thread *td, struct timespec *rqt, 6992723Salfred struct timespec *rmt); 7094343Sjhbstatic int settime(struct thread *, struct timeval *); 7192723Salfredstatic void timevalfix(struct timeval *); 7292723Salfredstatic void no_lease_updatetime(int); 7313016Sbde 7430739Sphkstatic void 7530739Sphkno_lease_updatetime(deltat) 7630739Sphk int deltat; 7730739Sphk{ 7830739Sphk} 7930739Sphk 8092723Salfredvoid (*lease_updatetime)(int) = no_lease_updatetime; 8130739Sphk 8225583Speterstatic int 83102074Sphksettime(struct thread *td, struct timeval *tv) 8425583Speter{ 8545433Snsayer struct timeval delta, tv1, tv2; 8645438Snsayer static struct timeval maxtime, laststep; 8733690Sphk struct timespec ts; 8825583Speter int s; 8925583Speter 9025656Speter s = splclock(); 9133818Sbde microtime(&tv1); 9235029Sphk delta = *tv; 9335029Sphk timevalsub(&delta, &tv1); 9425583Speter 9525583Speter /* 9633818Sbde * If the system is secure, we do not allow the time to be 9745433Snsayer * set to a value earlier than 1 second less than the highest 9845433Snsayer * time we have yet seen. The worst a miscreant can do in 9945433Snsayer * this circumstance is "freeze" time. He couldn't go 10045433Snsayer * back to the past. 10145438Snsayer * 10245438Snsayer * We similarly do not allow the clock to be stepped more 10345438Snsayer * than one second, nor more than once per second. This allows 10445438Snsayer * a miscreant to make the clock march double-time, but no worse. 10525583Speter */ 10694343Sjhb if (securelevel_gt(td->td_ucred, 1) != 0) { 10745433Snsayer if (delta.tv_sec < 0 || delta.tv_usec < 0) { 10845437Smjacob /* 10945438Snsayer * Update maxtime to latest time we've seen. 11045437Smjacob */ 11145437Smjacob if (tv1.tv_sec > maxtime.tv_sec) 11245437Smjacob maxtime = tv1; 11345437Smjacob tv2 = *tv; 11445437Smjacob timevalsub(&tv2, &maxtime); 11545437Smjacob if (tv2.tv_sec < -1) { 11645437Smjacob tv->tv_sec = maxtime.tv_sec - 1; 11745433Snsayer printf("Time adjustment clamped to -1 second\n"); 11845433Snsayer } 11945437Smjacob } else { 12045438Snsayer if (tv1.tv_sec == laststep.tv_sec) { 12145438Snsayer splx(s); 12245438Snsayer return (EPERM); 12345438Snsayer } 12445438Snsayer if (delta.tv_sec > 1) { 12545438Snsayer tv->tv_sec = tv1.tv_sec + 1; 12645438Snsayer printf("Time adjustment clamped to +1 second\n"); 12745438Snsayer } 12845438Snsayer laststep = *tv; 12945433Snsayer } 13033818Sbde } 13133818Sbde 13233690Sphk ts.tv_sec = tv->tv_sec; 13333690Sphk ts.tv_nsec = tv->tv_usec * 1000; 13494343Sjhb mtx_lock(&Giant); 13558377Sphk tc_setclock(&ts); 13625583Speter (void) splsoftclock(); 13725583Speter lease_updatetime(delta.tv_sec); 13825583Speter splx(s); 13925583Speter resettodr(); 14094343Sjhb mtx_unlock(&Giant); 14125583Speter return (0); 14225583Speter} 14325583Speter 14412221Sbde#ifndef _SYS_SYSPROTO_H_ 14525583Speterstruct clock_gettime_args { 14625583Speter clockid_t clock_id; 14725583Speter struct timespec *tp; 14825583Speter}; 14925583Speter#endif 15025656Speter 15182746Sdillon/* 15282746Sdillon * MPSAFE 15382746Sdillon */ 15425583Speter/* ARGSUSED */ 15525583Speterint 156102074Sphkclock_gettime(struct thread *td, struct clock_gettime_args *uap) 15725583Speter{ 15825583Speter struct timespec ats; 159130884Skbyanc struct timeval sys, user; 160136152Sjhb struct proc *p; 16125583Speter 162136152Sjhb p = td->td_proc; 163130654Skbyanc switch (uap->clock_id) { 164130654Skbyanc case CLOCK_REALTIME: 165111300Sphk nanotime(&ats); 166130654Skbyanc break; 167130654Skbyanc case CLOCK_VIRTUAL: 168136152Sjhb PROC_LOCK(p); 169136152Sjhb calcru(p, &user, &sys); 170136152Sjhb PROC_UNLOCK(p); 171130654Skbyanc TIMEVAL_TO_TIMESPEC(&user, &ats); 172130654Skbyanc break; 173130654Skbyanc case CLOCK_PROF: 174136152Sjhb PROC_LOCK(p); 175136152Sjhb calcru(p, &user, &sys); 176136152Sjhb PROC_UNLOCK(p); 177130884Skbyanc timevaladd(&user, &sys); 178130884Skbyanc TIMEVAL_TO_TIMESPEC(&user, &ats); 179130654Skbyanc break; 180130884Skbyanc case CLOCK_MONOTONIC: 181130884Skbyanc nanouptime(&ats); 182130884Skbyanc break; 183130654Skbyanc default: 184111315Sphk return (EINVAL); 185130654Skbyanc } 186107849Salfred return (copyout(&ats, uap->tp, sizeof(ats))); 18725583Speter} 18825583Speter 18925583Speter#ifndef _SYS_SYSPROTO_H_ 19025583Speterstruct clock_settime_args { 19125583Speter clockid_t clock_id; 19225583Speter const struct timespec *tp; 19325583Speter}; 19425583Speter#endif 19525656Speter 19682746Sdillon/* 19782746Sdillon * MPSAFE 19882746Sdillon */ 19925583Speter/* ARGSUSED */ 20025583Speterint 201102074Sphkclock_settime(struct thread *td, struct clock_settime_args *uap) 20225583Speter{ 20325583Speter struct timeval atv; 20425583Speter struct timespec ats; 20525583Speter int error; 20625583Speter 207106369Srwatson#ifdef MAC 208106369Srwatson error = mac_check_system_settime(td->td_ucred); 209106369Srwatson if (error) 210106369Srwatson return (error); 211106369Srwatson#endif 21293593Sjhb if ((error = suser(td)) != 0) 21394343Sjhb return (error); 214107849Salfred if (uap->clock_id != CLOCK_REALTIME) 21594343Sjhb return (EINVAL); 216107849Salfred if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0) 21794343Sjhb return (error); 21894343Sjhb if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000) 21994343Sjhb return (EINVAL); 22034901Sphk /* XXX Don't convert nsec->usec and back */ 22125583Speter TIMESPEC_TO_TIMEVAL(&atv, &ats); 22294343Sjhb error = settime(td, &atv); 22382746Sdillon return (error); 22425583Speter} 22525583Speter 22625583Speter#ifndef _SYS_SYSPROTO_H_ 22725583Speterstruct clock_getres_args { 22825583Speter clockid_t clock_id; 22925583Speter struct timespec *tp; 23025583Speter}; 23125583Speter#endif 23225656Speter 23325583Speterint 234102074Sphkclock_getres(struct thread *td, struct clock_getres_args *uap) 23525583Speter{ 23625583Speter struct timespec ts; 23725583Speter 238130654Skbyanc ts.tv_sec = 0; 239130654Skbyanc switch (uap->clock_id) { 240130654Skbyanc case CLOCK_REALTIME: 241130654Skbyanc case CLOCK_MONOTONIC: 242103964Sbde /* 243103964Sbde * Round up the result of the division cheaply by adding 1. 244103964Sbde * Rounding up is especially important if rounding down 245103964Sbde * would give 0. Perfect rounding is unimportant. 246103964Sbde */ 247103964Sbde ts.tv_nsec = 1000000000 / tc_getfrequency() + 1; 248130654Skbyanc break; 249130654Skbyanc case CLOCK_VIRTUAL: 250130654Skbyanc case CLOCK_PROF: 251130654Skbyanc /* Accurately round up here because we can do so cheaply. */ 252130654Skbyanc ts.tv_nsec = (1000000000 + hz - 1) / hz; 253130654Skbyanc break; 254130654Skbyanc default: 255130654Skbyanc return (EINVAL); 256130654Skbyanc } 257130884Skbyanc if (uap->tp == NULL) 258130884Skbyanc return (0); 259130884Skbyanc return (copyout(&ts, uap->tp, sizeof(ts))); 26025583Speter} 26125583Speter 26226335Speterstatic int nanowait; 26325656Speter 26426335Speterstatic int 265102074Sphknanosleep1(struct thread *td, struct timespec *rqt, struct timespec *rmt) 26625583Speter{ 26735045Sphk struct timespec ts, ts2, ts3; 26835042Sphk struct timeval tv; 26935042Sphk int error; 27025583Speter 27128773Sbde if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) 27225656Speter return (EINVAL); 27343301Sdillon if (rqt->tv_sec < 0 || (rqt->tv_sec == 0 && rqt->tv_nsec == 0)) 27428773Sbde return (0); 27536119Sphk getnanouptime(&ts); 27635029Sphk timespecadd(&ts, rqt); 27735042Sphk TIMESPEC_TO_TIMEVAL(&tv, rqt); 27835042Sphk for (;;) { 27935042Sphk error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp", 28035042Sphk tvtohz(&tv)); 28136119Sphk getnanouptime(&ts2); 28235042Sphk if (error != EWOULDBLOCK) { 28335042Sphk if (error == ERESTART) 28435042Sphk error = EINTR; 28535042Sphk if (rmt != NULL) { 28635042Sphk timespecsub(&ts, &ts2); 28735042Sphk if (ts.tv_sec < 0) 28835042Sphk timespecclear(&ts); 28935042Sphk *rmt = ts; 29035042Sphk } 29135042Sphk return (error); 29235042Sphk } 29335029Sphk if (timespeccmp(&ts2, &ts, >=)) 29435042Sphk return (0); 29535045Sphk ts3 = ts; 29635045Sphk timespecsub(&ts3, &ts2); 29735045Sphk TIMESPEC_TO_TIMEVAL(&tv, &ts3); 29826335Speter } 29926335Speter} 30025583Speter 30126335Speter#ifndef _SYS_SYSPROTO_H_ 30226335Speterstruct nanosleep_args { 30326335Speter struct timespec *rqtp; 30426335Speter struct timespec *rmtp; 30526335Speter}; 30626335Speter#endif 30726335Speter 30882746Sdillon/* 30982746Sdillon * MPSAFE 31082746Sdillon */ 31126335Speter/* ARGSUSED */ 31226335Speterint 313102074Sphknanosleep(struct thread *td, struct nanosleep_args *uap) 31426335Speter{ 31526335Speter struct timespec rmt, rqt; 31682746Sdillon int error; 31726335Speter 318107849Salfred error = copyin(uap->rqtp, &rqt, sizeof(rqt)); 31926335Speter if (error) 32026335Speter return (error); 32182746Sdillon 322109521Salfred if (uap->rmtp && 323109521Salfred !useracc((caddr_t)uap->rmtp, sizeof(rmt), VM_PROT_WRITE)) 324109521Salfred return (EFAULT); 32583366Sjulian error = nanosleep1(td, &rqt, &rmt); 326107849Salfred if (error && uap->rmtp) { 32782746Sdillon int error2; 32882746Sdillon 329107849Salfred error2 = copyout(&rmt, uap->rmtp, sizeof(rmt)); 330109521Salfred if (error2) 33182746Sdillon error = error2; 33225583Speter } 33325656Speter return (error); 33425583Speter} 33525583Speter 33626335Speter#ifndef _SYS_SYSPROTO_H_ 3371541Srgrimesstruct gettimeofday_args { 3381541Srgrimes struct timeval *tp; 3391541Srgrimes struct timezone *tzp; 3401541Srgrimes}; 34112221Sbde#endif 34282746Sdillon/* 34382746Sdillon * MPSAFE 34482746Sdillon */ 3451541Srgrimes/* ARGSUSED */ 3461549Srgrimesint 347102074Sphkgettimeofday(struct thread *td, struct gettimeofday_args *uap) 3481541Srgrimes{ 3491541Srgrimes struct timeval atv; 350110286Stjr struct timezone rtz; 3511541Srgrimes int error = 0; 3521541Srgrimes 3531541Srgrimes if (uap->tp) { 3541541Srgrimes microtime(&atv); 35599012Salfred error = copyout(&atv, uap->tp, sizeof (atv)); 3561541Srgrimes } 35790836Sphk if (error == 0 && uap->tzp != NULL) { 358110299Sphk rtz.tz_minuteswest = tz_minuteswest; 359110299Sphk rtz.tz_dsttime = tz_dsttime; 360110286Stjr error = copyout(&rtz, uap->tzp, sizeof (rtz)); 36182746Sdillon } 3621541Srgrimes return (error); 3631541Srgrimes} 3641541Srgrimes 36512221Sbde#ifndef _SYS_SYSPROTO_H_ 3661541Srgrimesstruct settimeofday_args { 3671541Srgrimes struct timeval *tv; 3681541Srgrimes struct timezone *tzp; 3691541Srgrimes}; 37012221Sbde#endif 37182746Sdillon/* 37282746Sdillon * MPSAFE 37382746Sdillon */ 3741541Srgrimes/* ARGSUSED */ 3751549Srgrimesint 376102074Sphksettimeofday(struct thread *td, struct settimeofday_args *uap) 3771541Srgrimes{ 37825656Speter struct timeval atv; 3791541Srgrimes struct timezone atz; 38082746Sdillon int error = 0; 3811541Srgrimes 382106369Srwatson#ifdef MAC 383106369Srwatson error = mac_check_system_settime(td->td_ucred); 384106369Srwatson if (error) 385106369Srwatson return (error); 386106369Srwatson#endif 38793593Sjhb if ((error = suser(td))) 38894343Sjhb return (error); 3891541Srgrimes /* Verify all parameters before changing time. */ 39025656Speter if (uap->tv) { 39199012Salfred if ((error = copyin(uap->tv, &atv, sizeof(atv)))) 39294343Sjhb return (error); 39394343Sjhb if (atv.tv_usec < 0 || atv.tv_usec >= 1000000) 39494343Sjhb return (EINVAL); 39525656Speter } 3961541Srgrimes if (uap->tzp && 39799012Salfred (error = copyin(uap->tzp, &atz, sizeof(atz)))) 39894343Sjhb return (error); 39994343Sjhb 40094343Sjhb if (uap->tv && (error = settime(td, &atv))) 40194343Sjhb return (error); 40294343Sjhb if (uap->tzp) { 403110299Sphk tz_minuteswest = atz.tz_minuteswest; 404110299Sphk tz_dsttime = atz.tz_dsttime; 40582746Sdillon } 40682746Sdillon return (error); 4071541Srgrimes} 40882746Sdillon/* 4091541Srgrimes * Get value of an interval timer. The process virtual and 4101541Srgrimes * profiling virtual time timers are kept in the p_stats area, since 4111541Srgrimes * they can be swapped out. These are kept internally in the 4121541Srgrimes * way they are specified externally: in time until they expire. 4131541Srgrimes * 4141541Srgrimes * The real time interval timer is kept in the process table slot 4151541Srgrimes * for the process, and its value (it_value) is kept as an 4161541Srgrimes * absolute time rather than as a delta, so that it is easy to keep 4171541Srgrimes * periodic real-time signals from drifting. 4181541Srgrimes * 4191541Srgrimes * Virtual time timers are processed in the hardclock() routine of 4201541Srgrimes * kern_clock.c. The real time timer is processed by a timeout 4211541Srgrimes * routine, called from the softclock() routine. Since a callout 4221541Srgrimes * may be delayed in real time due to interrupt processing in the system, 4231541Srgrimes * it is possible for the real time timeout routine (realitexpire, given below), 4241541Srgrimes * to be delayed in real time past when it is supposed to occur. It 4251541Srgrimes * does not suffice, therefore, to reload the real timer .it_value from the 4261541Srgrimes * real time timers .it_interval. Rather, we compute the next time in 4271541Srgrimes * absolute time the timer should go off. 4281541Srgrimes */ 42912221Sbde#ifndef _SYS_SYSPROTO_H_ 4301541Srgrimesstruct getitimer_args { 4311541Srgrimes u_int which; 4321541Srgrimes struct itimerval *itv; 4331541Srgrimes}; 43412221Sbde#endif 43582746Sdillon/* 43682746Sdillon * MPSAFE 43782746Sdillon */ 4381549Srgrimesint 439102074Sphkgetitimer(struct thread *td, struct getitimer_args *uap) 4401541Srgrimes{ 44183366Sjulian struct proc *p = td->td_proc; 44234961Sphk struct timeval ctv; 4431541Srgrimes struct itimerval aitv; 4441541Srgrimes 4451541Srgrimes if (uap->which > ITIMER_PROF) 4461541Srgrimes return (EINVAL); 44782746Sdillon 4481541Srgrimes if (uap->which == ITIMER_REAL) { 4491541Srgrimes /* 45036128Sbde * Convert from absolute to relative time in .it_value 4511541Srgrimes * part of real time timer. If time for real time timer 4521541Srgrimes * has passed return 0, else return difference between 4531541Srgrimes * current time and time for the timer to go off. 4541541Srgrimes */ 455111034Stjr PROC_LOCK(p); 4561541Srgrimes aitv = p->p_realtimer; 457111034Stjr PROC_UNLOCK(p); 45835058Sphk if (timevalisset(&aitv.it_value)) { 45936119Sphk getmicrouptime(&ctv); 46035058Sphk if (timevalcmp(&aitv.it_value, &ctv, <)) 46135058Sphk timevalclear(&aitv.it_value); 4621541Srgrimes else 46334961Sphk timevalsub(&aitv.it_value, &ctv); 46434961Sphk } 46582746Sdillon } else { 466111034Stjr mtx_lock_spin(&sched_lock); 4671541Srgrimes aitv = p->p_stats->p_timer[uap->which]; 468111034Stjr mtx_unlock_spin(&sched_lock); 46982746Sdillon } 470110286Stjr return (copyout(&aitv, uap->itv, sizeof (struct itimerval))); 4711541Srgrimes} 4721541Srgrimes 47312221Sbde#ifndef _SYS_SYSPROTO_H_ 4741541Srgrimesstruct setitimer_args { 4751541Srgrimes u_int which; 4761541Srgrimes struct itimerval *itv, *oitv; 4771541Srgrimes}; 47812221Sbde#endif 47982746Sdillon/* 48082746Sdillon * MPSAFE 48182746Sdillon */ 4821549Srgrimesint 483102074Sphksetitimer(struct thread *td, struct setitimer_args *uap) 4841541Srgrimes{ 48583366Sjulian struct proc *p = td->td_proc; 486111034Stjr struct itimerval aitv, oitv; 48734961Sphk struct timeval ctv; 488111034Stjr int error; 4891541Srgrimes 490111034Stjr if (uap->itv == NULL) { 491111034Stjr uap->itv = uap->oitv; 492111034Stjr return (getitimer(td, (struct getitimer_args *)uap)); 493111034Stjr } 494111034Stjr 4951541Srgrimes if (uap->which > ITIMER_PROF) 4961541Srgrimes return (EINVAL); 497111034Stjr if ((error = copyin(uap->itv, &aitv, sizeof(struct itimerval)))) 4981541Srgrimes return (error); 499111034Stjr if (itimerfix(&aitv.it_value)) 500111034Stjr return (EINVAL); 501111034Stjr if (!timevalisset(&aitv.it_value)) 502111034Stjr timevalclear(&aitv.it_interval); 503111034Stjr else if (itimerfix(&aitv.it_interval)) 504111034Stjr return (EINVAL); 50582746Sdillon 5061541Srgrimes if (uap->which == ITIMER_REAL) { 507111034Stjr PROC_LOCK(p); 50835058Sphk if (timevalisset(&p->p_realtimer.it_value)) 50969286Sjake callout_stop(&p->p_itcallout); 510114980Sjhb getmicrouptime(&ctv); 511114980Sjhb if (timevalisset(&aitv.it_value)) { 51269286Sjake callout_reset(&p->p_itcallout, tvtohz(&aitv.it_value), 51369286Sjake realitexpire, p); 514114980Sjhb timevaladd(&aitv.it_value, &ctv); 515114980Sjhb } 516111034Stjr oitv = p->p_realtimer; 5171541Srgrimes p->p_realtimer = aitv; 518111034Stjr PROC_UNLOCK(p); 519111034Stjr if (timevalisset(&oitv.it_value)) { 520111034Stjr if (timevalcmp(&oitv.it_value, &ctv, <)) 521111034Stjr timevalclear(&oitv.it_value); 522111034Stjr else 523111034Stjr timevalsub(&oitv.it_value, &ctv); 524111034Stjr } 52582746Sdillon } else { 526111034Stjr mtx_lock_spin(&sched_lock); 527111034Stjr oitv = p->p_stats->p_timer[uap->which]; 5281541Srgrimes p->p_stats->p_timer[uap->which] = aitv; 529111034Stjr mtx_unlock_spin(&sched_lock); 53082746Sdillon } 531111034Stjr if (uap->oitv == NULL) 532111034Stjr return (0); 533111034Stjr return (copyout(&oitv, uap->oitv, sizeof(struct itimerval))); 5341541Srgrimes} 5351541Srgrimes 5361541Srgrimes/* 5371541Srgrimes * Real interval timer expired: 5381541Srgrimes * send process whose timer expired an alarm signal. 5391541Srgrimes * If time is not set up to reload, then just return. 5401541Srgrimes * Else compute next time timer should go off which is > current time. 5411541Srgrimes * This is where delay in processing this timeout causes multiple 5421541Srgrimes * SIGALRM calls to be compressed into one. 54336127Sbde * tvtohz() always adds 1 to allow for the time until the next clock 5449327Sbde * interrupt being strictly less than 1 clock tick, but we don't want 5459327Sbde * that here since we want to appear to be in sync with the clock 5469327Sbde * interrupt even when we're delayed. 5471541Srgrimes */ 5481541Srgrimesvoid 549102074Sphkrealitexpire(void *arg) 5501541Srgrimes{ 551102074Sphk struct proc *p; 55235044Sphk struct timeval ctv, ntv; 5531541Srgrimes 5541541Srgrimes p = (struct proc *)arg; 55573916Sjhb PROC_LOCK(p); 5561541Srgrimes psignal(p, SIGALRM); 55735058Sphk if (!timevalisset(&p->p_realtimer.it_interval)) { 55835058Sphk timevalclear(&p->p_realtimer.it_value); 559116123Sjhb if (p->p_flag & P_WEXIT) 560116123Sjhb wakeup(&p->p_itcallout); 56173916Sjhb PROC_UNLOCK(p); 5621541Srgrimes return; 5631541Srgrimes } 5641541Srgrimes for (;;) { 5651541Srgrimes timevaladd(&p->p_realtimer.it_value, 5661541Srgrimes &p->p_realtimer.it_interval); 56736119Sphk getmicrouptime(&ctv); 56835058Sphk if (timevalcmp(&p->p_realtimer.it_value, &ctv, >)) { 56935044Sphk ntv = p->p_realtimer.it_value; 57035044Sphk timevalsub(&ntv, &ctv); 57169286Sjake callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1, 57269286Sjake realitexpire, p); 57373916Sjhb PROC_UNLOCK(p); 5741541Srgrimes return; 5751541Srgrimes } 5761541Srgrimes } 57773916Sjhb /*NOTREACHED*/ 5781541Srgrimes} 5791541Srgrimes 5801541Srgrimes/* 5811541Srgrimes * Check that a proposed value to load into the .it_value or 5821541Srgrimes * .it_interval part of an interval timer is acceptable, and 5831541Srgrimes * fix it to have at least minimal value (i.e. if it is less 5841541Srgrimes * than the resolution of the clock, round it up.) 5851541Srgrimes */ 5861549Srgrimesint 587102074Sphkitimerfix(struct timeval *tv) 5881541Srgrimes{ 5891541Srgrimes 5901541Srgrimes if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 5911541Srgrimes tv->tv_usec < 0 || tv->tv_usec >= 1000000) 5921541Srgrimes return (EINVAL); 5931541Srgrimes if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 5941541Srgrimes tv->tv_usec = tick; 5951541Srgrimes return (0); 5961541Srgrimes} 5971541Srgrimes 5981541Srgrimes/* 5991541Srgrimes * Decrement an interval timer by a specified number 6001541Srgrimes * of microseconds, which must be less than a second, 6011541Srgrimes * i.e. < 1000000. If the timer expires, then reload 6021541Srgrimes * it. In this case, carry over (usec - old value) to 6031541Srgrimes * reduce the value reloaded into the timer so that 6041541Srgrimes * the timer does not drift. This routine assumes 6051541Srgrimes * that it is called in a context where the timers 6061541Srgrimes * on which it is operating cannot change in value. 6071541Srgrimes */ 6081549Srgrimesint 609102074Sphkitimerdecr(struct itimerval *itp, int usec) 6101541Srgrimes{ 6111541Srgrimes 6121541Srgrimes if (itp->it_value.tv_usec < usec) { 6131541Srgrimes if (itp->it_value.tv_sec == 0) { 6141541Srgrimes /* expired, and already in next interval */ 6151541Srgrimes usec -= itp->it_value.tv_usec; 6161541Srgrimes goto expire; 6171541Srgrimes } 6181541Srgrimes itp->it_value.tv_usec += 1000000; 6191541Srgrimes itp->it_value.tv_sec--; 6201541Srgrimes } 6211541Srgrimes itp->it_value.tv_usec -= usec; 6221541Srgrimes usec = 0; 62335058Sphk if (timevalisset(&itp->it_value)) 6241541Srgrimes return (1); 6251541Srgrimes /* expired, exactly at end of interval */ 6261541Srgrimesexpire: 62735058Sphk if (timevalisset(&itp->it_interval)) { 6281541Srgrimes itp->it_value = itp->it_interval; 6291541Srgrimes itp->it_value.tv_usec -= usec; 6301541Srgrimes if (itp->it_value.tv_usec < 0) { 6311541Srgrimes itp->it_value.tv_usec += 1000000; 6321541Srgrimes itp->it_value.tv_sec--; 6331541Srgrimes } 6341541Srgrimes } else 6351541Srgrimes itp->it_value.tv_usec = 0; /* sec is already 0 */ 6361541Srgrimes return (0); 6371541Srgrimes} 6381541Srgrimes 6391541Srgrimes/* 6401541Srgrimes * Add and subtract routines for timevals. 6411541Srgrimes * N.B.: subtract routine doesn't deal with 6421541Srgrimes * results which are before the beginning, 6431541Srgrimes * it just gets very confused in this case. 6441541Srgrimes * Caveat emptor. 6451541Srgrimes */ 6461549Srgrimesvoid 647121523Salfredtimevaladd(struct timeval *t1, const struct timeval *t2) 6481541Srgrimes{ 6491541Srgrimes 6501541Srgrimes t1->tv_sec += t2->tv_sec; 6511541Srgrimes t1->tv_usec += t2->tv_usec; 6521541Srgrimes timevalfix(t1); 6531541Srgrimes} 6541541Srgrimes 6551549Srgrimesvoid 656121523Salfredtimevalsub(struct timeval *t1, const struct timeval *t2) 6571541Srgrimes{ 6581541Srgrimes 6591541Srgrimes t1->tv_sec -= t2->tv_sec; 6601541Srgrimes t1->tv_usec -= t2->tv_usec; 6611541Srgrimes timevalfix(t1); 6621541Srgrimes} 6631541Srgrimes 66412819Sphkstatic void 665102074Sphktimevalfix(struct timeval *t1) 6661541Srgrimes{ 6671541Srgrimes 6681541Srgrimes if (t1->tv_usec < 0) { 6691541Srgrimes t1->tv_sec--; 6701541Srgrimes t1->tv_usec += 1000000; 6711541Srgrimes } 6721541Srgrimes if (t1->tv_usec >= 1000000) { 6731541Srgrimes t1->tv_sec++; 6741541Srgrimes t1->tv_usec -= 1000000; 6751541Srgrimes } 6761541Srgrimes} 677108142Ssam 678108142Ssam/* 679108511Ssam * ratecheck(): simple time-based rate-limit checking. 680108142Ssam */ 681108142Ssamint 682108142Ssamratecheck(struct timeval *lasttime, const struct timeval *mininterval) 683108142Ssam{ 684108142Ssam struct timeval tv, delta; 685108142Ssam int rv = 0; 686108142Ssam 687108511Ssam getmicrouptime(&tv); /* NB: 10ms precision */ 688108511Ssam delta = tv; 689108511Ssam timevalsub(&delta, lasttime); 690108142Ssam 691108142Ssam /* 692108142Ssam * check for 0,0 is so that the message will be seen at least once, 693108142Ssam * even if interval is huge. 694108142Ssam */ 695108142Ssam if (timevalcmp(&delta, mininterval, >=) || 696108142Ssam (lasttime->tv_sec == 0 && lasttime->tv_usec == 0)) { 697108142Ssam *lasttime = tv; 698108142Ssam rv = 1; 699108142Ssam } 700108142Ssam 701108142Ssam return (rv); 702108142Ssam} 703108142Ssam 704108142Ssam/* 705108142Ssam * ppsratecheck(): packets (or events) per second limitation. 706108511Ssam * 707108511Ssam * Return 0 if the limit is to be enforced (e.g. the caller 708108511Ssam * should drop a packet because of the rate limitation). 709108511Ssam * 710111558Ssam * maxpps of 0 always causes zero to be returned. maxpps of -1 711111558Ssam * always causes 1 to be returned; this effectively defeats rate 712111558Ssam * limiting. 713111558Ssam * 714108511Ssam * Note that we maintain the struct timeval for compatibility 715108511Ssam * with other bsd systems. We reuse the storage and just monitor 716108511Ssam * clock ticks for minimal overhead. 717108142Ssam */ 718108142Ssamint 719108142Ssamppsratecheck(struct timeval *lasttime, int *curpps, int maxpps) 720108142Ssam{ 721108511Ssam int now; 722108142Ssam 723108142Ssam /* 724108511Ssam * Reset the last time and counter if this is the first call 725108511Ssam * or more than a second has passed since the last update of 726108511Ssam * lasttime. 727108142Ssam */ 728108511Ssam now = ticks; 729108511Ssam if (lasttime->tv_sec == 0 || (u_int)(now - lasttime->tv_sec) >= hz) { 730108511Ssam lasttime->tv_sec = now; 731108511Ssam *curpps = 1; 732111558Ssam return (maxpps != 0); 733108511Ssam } else { 734108511Ssam (*curpps)++; /* NB: ignore potential overflow */ 735108511Ssam return (maxpps < 0 || *curpps < maxpps); 736108511Ssam } 737108142Ssam} 738