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
gettimeofday(p,uap,retval)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
settimeofday(p,uap,retval)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
adjtime(p,uap,retval)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
getitimer(p,uap,retval)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
setitimer(p,uap,retval)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
realitexpire(arg)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
itimerfix(tv)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
itimerdecr(itp,usec)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