1 /* 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_time.c 8.4 (Berkeley) 05/26/95 8 */ 9 10 #include <sys/param.h> 11 #include <sys/resourcevar.h> 12 #include <sys/kernel.h> 13 #include <sys/systm.h> 14 #include <sys/proc.h> 15 #include <sys/vnode.h> 16 17 #include <sys/mount.h> 18 #include <sys/syscallargs.h> 19 20 #include <machine/cpu.h> 21 22 /* 23 * Time of day and interval timer support. 24 * 25 * These routines provide the kernel entry points to get and set 26 * the time-of-day and per-process interval timers. Subroutines 27 * here provide support for adding and subtracting timeval structures 28 * and decrementing interval timers, optionally reloading the interval 29 * timers when they expire. 30 */ 31 32 /* ARGSUSED */ 33 int 34 gettimeofday(p, uap, retval) 35 struct proc *p; 36 register struct gettimeofday_args /* { 37 syscallarg(struct timeval *) tp; 38 syscallarg(struct timezone *) tzp; 39 } */ *uap; 40 register_t *retval; 41 { 42 struct timeval atv; 43 int error = 0; 44 45 if (SCARG(uap, tp)) { 46 microtime(&atv); 47 if (error = copyout((caddr_t)&atv, (caddr_t)SCARG(uap, tp), 48 sizeof (atv))) 49 return (error); 50 } 51 if (SCARG(uap, tzp)) 52 error = copyout((caddr_t)&tz, (caddr_t)SCARG(uap, tzp), 53 sizeof (tz)); 54 return (error); 55 } 56 57 /* ARGSUSED */ 58 int 59 settimeofday(p, uap, retval) 60 struct proc *p; 61 struct settimeofday_args /* { 62 syscallarg(struct timeval *) tv; 63 syscallarg(struct timezone *) tzp; 64 } */ *uap; 65 register_t *retval; 66 { 67 struct timeval atv, delta; 68 struct timezone atz; 69 int error, s; 70 71 if (error = suser(p->p_ucred, &p->p_acflag)) 72 return (error); 73 /* Verify all parameters before changing time. */ 74 if (SCARG(uap, tv) && (error = copyin((caddr_t)SCARG(uap, tv), 75 (caddr_t)&atv, sizeof(atv)))) 76 return (error); 77 if (SCARG(uap, tzp) && (error = copyin((caddr_t)SCARG(uap, tzp), 78 (caddr_t)&atz, sizeof(atz)))) 79 return (error); 80 if (SCARG(uap, tv)) { 81 /* 82 * If the system is secure, we do not allow the time to be 83 * set to an earlier value (it may be slowed using adjtime, 84 * but not set back). This feature prevent interlopers from 85 * setting arbitrary time stamps on files. 86 */ 87 if (securelevel > 0 && timercmp(&atv, &time, <)) 88 return (EPERM); 89 /* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ 90 s = splclock(); 91 /* nb. delta.tv_usec may be < 0, but this is OK here */ 92 delta.tv_sec = atv.tv_sec - time.tv_sec; 93 delta.tv_usec = atv.tv_usec - time.tv_usec; 94 time = atv; 95 (void) splsoftclock(); 96 timevaladd(&boottime, &delta); 97 timevalfix(&boottime); 98 timevaladd(&runtime, &delta); 99 timevalfix(&runtime); 100 # ifdef NFS 101 lease_updatetime(delta.tv_sec); 102 # endif 103 splx(s); 104 resettodr(); 105 } 106 if (SCARG(uap, tzp)) 107 tz = atz; 108 return (0); 109 } 110 111 extern int tickadj; /* "standard" clock skew, us./tick */ 112 int tickdelta; /* current clock skew, us. per tick */ 113 long timedelta; /* unapplied time correction, us. */ 114 long bigadj = 1000000; /* use 10x skew above bigadj us. */ 115 116 /* ARGSUSED */ 117 int 118 adjtime(p, uap, retval) 119 struct proc *p; 120 register struct adjtime_args /* { 121 syscallarg(struct timeval *) delta; 122 syscallarg(struct timeval *) olddelta; 123 } */ *uap; 124 register_t *retval; 125 { 126 struct timeval atv; 127 register long ndelta, ntickdelta, odelta; 128 int s, error; 129 130 if (error = suser(p->p_ucred, &p->p_acflag)) 131 return (error); 132 if (error = copyin((caddr_t)SCARG(uap, delta), (caddr_t)&atv, 133 sizeof(struct timeval))) 134 return (error); 135 136 /* 137 * Compute the total correction and the rate at which to apply it. 138 * Round the adjustment down to a whole multiple of the per-tick 139 * delta, so that after some number of incremental changes in 140 * hardclock(), tickdelta will become zero, lest the correction 141 * overshoot and start taking us away from the desired final time. 142 */ 143 ndelta = atv.tv_sec * 1000000 + atv.tv_usec; 144 if (ndelta > bigadj) 145 ntickdelta = 10 * tickadj; 146 else 147 ntickdelta = tickadj; 148 if (ndelta % ntickdelta) 149 ndelta = ndelta / ntickdelta * ntickdelta; 150 151 /* 152 * To make hardclock()'s job easier, make the per-tick delta negative 153 * if we want time to run slower; then hardclock can simply compute 154 * tick + tickdelta, and subtract tickdelta from timedelta. 155 */ 156 if (ndelta < 0) 157 ntickdelta = -ntickdelta; 158 s = splclock(); 159 odelta = timedelta; 160 timedelta = ndelta; 161 tickdelta = ntickdelta; 162 splx(s); 163 164 if (SCARG(uap, olddelta)) { 165 atv.tv_sec = odelta / 1000000; 166 atv.tv_usec = odelta % 1000000; 167 (void) copyout((caddr_t)&atv, (caddr_t)SCARG(uap, olddelta), 168 sizeof(struct timeval)); 169 } 170 return (0); 171 } 172 173 /* 174 * Get value of an interval timer. The process virtual and 175 * profiling virtual time timers are kept in the p_stats area, since 176 * they can be swapped out. These are kept internally in the 177 * way they are specified externally: in time until they expire. 178 * 179 * The real time interval timer is kept in the process table slot 180 * for the process, and its value (it_value) is kept as an 181 * absolute time rather than as a delta, so that it is easy to keep 182 * periodic real-time signals from drifting. 183 * 184 * Virtual time timers are processed in the hardclock() routine of 185 * kern_clock.c. The real time timer is processed by a timeout 186 * routine, called from the softclock() routine. Since a callout 187 * may be delayed in real time due to interrupt processing in the system, 188 * it is possible for the real time timeout routine (realitexpire, given below), 189 * to be delayed in real time past when it is supposed to occur. It 190 * does not suffice, therefore, to reload the real timer .it_value from the 191 * real time timers .it_interval. Rather, we compute the next time in 192 * absolute time the timer should go off. 193 */ 194 /* ARGSUSED */ 195 int 196 getitimer(p, uap, retval) 197 struct proc *p; 198 register struct getitimer_args /* { 199 syscallarg(u_int) which; 200 syscallarg(struct itimerval *) itv; 201 } */ *uap; 202 register_t *retval; 203 { 204 struct itimerval aitv; 205 int s; 206 207 if (SCARG(uap, which) > ITIMER_PROF) 208 return (EINVAL); 209 s = splclock(); 210 if (SCARG(uap, which) == ITIMER_REAL) { 211 /* 212 * Convert from absolute to relative time in .it_value 213 * part of real time timer. If time for real time timer 214 * has passed return 0, else return difference between 215 * current time and time for the timer to go off. 216 */ 217 aitv = p->p_realtimer; 218 if (timerisset(&aitv.it_value)) 219 if (timercmp(&aitv.it_value, &time, <)) 220 timerclear(&aitv.it_value); 221 else 222 timevalsub(&aitv.it_value, 223 (struct timeval *)&time); 224 } else 225 aitv = p->p_stats->p_timer[SCARG(uap, which)]; 226 splx(s); 227 return (copyout((caddr_t)&aitv, (caddr_t)SCARG(uap, itv), 228 sizeof (struct itimerval))); 229 } 230 231 /* ARGSUSED */ 232 int 233 setitimer(p, uap, retval) 234 struct proc *p; 235 register struct setitimer_args /* { 236 syscallarg(u_int) which; 237 syscallarg(struct itimerval *) itv; 238 syscallarg(struct itimerval *) oitv; 239 } */ *uap; 240 register_t *retval; 241 { 242 struct itimerval aitv; 243 register struct itimerval *itvp; 244 int s, error; 245 246 if (SCARG(uap, which) > ITIMER_PROF) 247 return (EINVAL); 248 itvp = SCARG(uap, itv); 249 if (itvp && (error = copyin((caddr_t)itvp, (caddr_t)&aitv, 250 sizeof(struct itimerval)))) 251 return (error); 252 if ((SCARG(uap, itv) = SCARG(uap, oitv)) && 253 (error = getitimer(p, uap, retval))) 254 return (error); 255 if (itvp == 0) 256 return (0); 257 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) 258 return (EINVAL); 259 s = splclock(); 260 if (SCARG(uap, which) == ITIMER_REAL) { 261 untimeout(realitexpire, (caddr_t)p); 262 if (timerisset(&aitv.it_value)) { 263 timevaladd(&aitv.it_value, (struct timeval *)&time); 264 timeout(realitexpire, (caddr_t)p, hzto(&aitv.it_value)); 265 } 266 p->p_realtimer = aitv; 267 } else 268 p->p_stats->p_timer[SCARG(uap, which)] = aitv; 269 splx(s); 270 return (0); 271 } 272 273 /* 274 * Real interval timer expired: 275 * send process whose timer expired an alarm signal. 276 * If time is not set up to reload, then just return. 277 * Else compute next time timer should go off which is > current time. 278 * This is where delay in processing this timeout causes multiple 279 * SIGALRM calls to be compressed into one. 280 */ 281 void 282 realitexpire(arg) 283 void *arg; 284 { 285 register struct proc *p; 286 int s; 287 288 p = (struct proc *)arg; 289 psignal(p, SIGALRM); 290 if (!timerisset(&p->p_realtimer.it_interval)) { 291 timerclear(&p->p_realtimer.it_value); 292 return; 293 } 294 for (;;) { 295 s = splclock(); 296 timevaladd(&p->p_realtimer.it_value, 297 &p->p_realtimer.it_interval); 298 if (timercmp(&p->p_realtimer.it_value, &time, >)) { 299 timeout(realitexpire, (caddr_t)p, 300 hzto(&p->p_realtimer.it_value)); 301 splx(s); 302 return; 303 } 304 splx(s); 305 } 306 } 307 308 /* 309 * Check that a proposed value to load into the .it_value or 310 * .it_interval part of an interval timer is acceptable, and 311 * fix it to have at least minimal value (i.e. if it is less 312 * than the resolution of the clock, round it up.) 313 */ 314 int 315 itimerfix(tv) 316 struct timeval *tv; 317 { 318 319 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 || 320 tv->tv_usec < 0 || tv->tv_usec >= 1000000) 321 return (EINVAL); 322 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick) 323 tv->tv_usec = tick; 324 return (0); 325 } 326 327 /* 328 * Decrement an interval timer by a specified number 329 * of microseconds, which must be less than a second, 330 * i.e. < 1000000. If the timer expires, then reload 331 * it. In this case, carry over (usec - old value) to 332 * reduce the value reloaded into the timer so that 333 * the timer does not drift. This routine assumes 334 * that it is called in a context where the timers 335 * on which it is operating cannot change in value. 336 */ 337 int 338 itimerdecr(itp, usec) 339 register struct itimerval *itp; 340 int usec; 341 { 342 343 if (itp->it_value.tv_usec < usec) { 344 if (itp->it_value.tv_sec == 0) { 345 /* expired, and already in next interval */ 346 usec -= itp->it_value.tv_usec; 347 goto expire; 348 } 349 itp->it_value.tv_usec += 1000000; 350 itp->it_value.tv_sec--; 351 } 352 itp->it_value.tv_usec -= usec; 353 usec = 0; 354 if (timerisset(&itp->it_value)) 355 return (1); 356 /* expired, exactly at end of interval */ 357 expire: 358 if (timerisset(&itp->it_interval)) { 359 itp->it_value = itp->it_interval; 360 itp->it_value.tv_usec -= usec; 361 if (itp->it_value.tv_usec < 0) { 362 itp->it_value.tv_usec += 1000000; 363 itp->it_value.tv_sec--; 364 } 365 } else 366 itp->it_value.tv_usec = 0; /* sec is already 0 */ 367 return (0); 368 } 369 370 /* 371 * Add and subtract routines for timevals. 372 * N.B.: subtract routine doesn't deal with 373 * results which are before the beginning, 374 * it just gets very confused in this case. 375 * Caveat emptor. 376 */ 377 timevaladd(t1, t2) 378 struct timeval *t1, *t2; 379 { 380 381 t1->tv_sec += t2->tv_sec; 382 t1->tv_usec += t2->tv_usec; 383 timevalfix(t1); 384 } 385 386 timevalsub(t1, t2) 387 struct timeval *t1, *t2; 388 { 389 390 t1->tv_sec -= t2->tv_sec; 391 t1->tv_usec -= t2->tv_usec; 392 timevalfix(t1); 393 } 394 395 timevalfix(t1) 396 struct timeval *t1; 397 { 398 399 if (t1->tv_usec < 0) { 400 t1->tv_sec--; 401 t1->tv_usec += 1000000; 402 } 403 if (t1->tv_usec >= 1000000) { 404 t1->tv_sec++; 405 t1->tv_usec -= 1000000; 406 } 407 } 408