]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_time.c
906ba9ead3a62a0e1b309caab13c9e92183d19a1
[apple/xnu.git] / bsd / kern / kern_time.c
1 /*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 /*
30 * Copyright (c) 1982, 1986, 1989, 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. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)kern_time.c 8.4 (Berkeley) 5/26/95
62 */
63
64 #include <sys/param.h>
65 #include <sys/resourcevar.h>
66 #include <sys/kernel.h>
67 #include <sys/systm.h>
68 #include <sys/proc_internal.h>
69 #include <sys/kauth.h>
70 #include <sys/vnode.h>
71
72 #include <sys/mount_internal.h>
73 #include <sys/sysproto.h>
74 #include <sys/signalvar.h>
75
76 #include <kern/clock.h>
77 #include <kern/thread_call.h>
78
79 #define HZ 100 /* XXX */
80
81 /* simple lock used to access timezone, tz structure */
82 lck_spin_t * tz_slock;
83 lck_grp_t * tz_slock_grp;
84 lck_attr_t * tz_slock_attr;
85 lck_grp_attr_t *tz_slock_grp_attr;
86
87 static void setthetime(
88 struct timeval *tv);
89
90 void time_zone_slock_init(void);
91
92 /*
93 * Time of day and interval timer support.
94 *
95 * These routines provide the kernel entry points to get and set
96 * the time-of-day and per-process interval timers. Subroutines
97 * here provide support for adding and subtracting timeval structures
98 * and decrementing interval timers, optionally reloading the interval
99 * timers when they expire.
100 */
101 /* ARGSUSED */
102 int
103 gettimeofday(
104 __unused struct proc *p,
105 struct gettimeofday_args *uap,
106 register_t *retval)
107 {
108 int error = 0;
109 struct timezone ltz; /* local copy */
110
111 if (uap->tp)
112 clock_gettimeofday(&retval[0], &retval[1]);
113
114 if (uap->tzp) {
115 lck_spin_lock(tz_slock);
116 ltz = tz;
117 lck_spin_unlock(tz_slock);
118
119 error = copyout((caddr_t)&ltz, CAST_USER_ADDR_T(uap->tzp), sizeof (tz));
120 }
121
122 return (error);
123 }
124
125 /*
126 * XXX Y2038 bug because of setthetime() argument
127 */
128 /* ARGSUSED */
129 int
130 settimeofday(struct proc *p, struct settimeofday_args *uap, __unused register_t *retval)
131 {
132 struct timeval atv;
133 struct timezone atz;
134 int error;
135
136 if ((error = suser(kauth_cred_get(), &p->p_acflag)))
137 return (error);
138 /* Verify all parameters before changing time */
139 if (uap->tv) {
140 if (IS_64BIT_PROCESS(p)) {
141 struct user_timeval user_atv;
142 error = copyin(uap->tv, &user_atv, sizeof(struct user_timeval));
143 atv.tv_sec = user_atv.tv_sec;
144 atv.tv_usec = user_atv.tv_usec;
145 } else {
146 error = copyin(uap->tv, &atv, sizeof(struct timeval));
147 }
148 if (error)
149 return (error);
150 }
151 if (uap->tzp && (error = copyin(uap->tzp, (caddr_t)&atz, sizeof(atz))))
152 return (error);
153 if (uap->tv) {
154 timevalfix(&atv);
155 if (atv.tv_sec < 0 || (atv.tv_sec == 0 && atv.tv_usec < 0))
156 return (EPERM);
157 setthetime(&atv);
158 }
159 if (uap->tzp) {
160 lck_spin_lock(tz_slock);
161 tz = atz;
162 lck_spin_unlock(tz_slock);
163 }
164 return (0);
165 }
166
167 static void
168 setthetime(
169 struct timeval *tv)
170 {
171 clock_set_calendar_microtime(tv->tv_sec, tv->tv_usec);
172 }
173
174 /*
175 * XXX Y2038 bug because of clock_adjtime() first argument
176 */
177 /* ARGSUSED */
178 int
179 adjtime(struct proc *p, register struct adjtime_args *uap, __unused register_t *retval)
180 {
181 struct timeval atv;
182 int error;
183
184 if ((error = suser(kauth_cred_get(), &p->p_acflag)))
185 return (error);
186 if (IS_64BIT_PROCESS(p)) {
187 struct user_timeval user_atv;
188 error = copyin(uap->delta, &user_atv, sizeof(struct user_timeval));
189 atv.tv_sec = user_atv.tv_sec;
190 atv.tv_usec = user_atv.tv_usec;
191 } else {
192 error = copyin(uap->delta, &atv, sizeof(struct timeval));
193 }
194 if (error)
195 return (error);
196
197 /*
198 * Compute the total correction and the rate at which to apply it.
199 */
200 clock_adjtime((int32_t *)&atv.tv_sec, &atv.tv_usec);
201
202 if (uap->olddelta) {
203 if (IS_64BIT_PROCESS(p)) {
204 struct user_timeval user_atv;
205 user_atv.tv_sec = atv.tv_sec;
206 user_atv.tv_usec = atv.tv_usec;
207 error = copyout(&user_atv, uap->olddelta, sizeof(struct user_timeval));
208 } else {
209 error = copyout(&atv, uap->olddelta, sizeof(struct timeval));
210 }
211 }
212
213 return (0);
214 }
215
216 /*
217 * Verify the calendar value. If negative,
218 * reset to zero (the epoch).
219 */
220 void
221 inittodr(
222 __unused time_t base)
223 {
224 struct timeval tv;
225
226 /*
227 * Assertion:
228 * The calendar has already been
229 * set up from the platform clock.
230 *
231 * The value returned by microtime()
232 * is gotten from the calendar.
233 */
234 microtime(&tv);
235
236 if (tv.tv_sec < 0 || tv.tv_usec < 0) {
237 printf ("WARNING: preposterous time in Real Time Clock");
238 tv.tv_sec = 0; /* the UNIX epoch */
239 tv.tv_usec = 0;
240 setthetime(&tv);
241 printf(" -- CHECK AND RESET THE DATE!\n");
242 }
243 }
244
245 time_t
246 boottime_sec(void)
247 {
248 uint32_t sec, nanosec;
249 clock_get_boottime_nanotime(&sec, &nanosec);
250 return (sec);
251 }
252
253 uint64_t tvtoabstime(struct timeval *tvp);
254
255 /*
256 * Get value of an interval timer. The process virtual and
257 * profiling virtual time timers are kept internally in the
258 * way they are specified externally: in time until they expire.
259 *
260 * The real time interval timer expiration time (p_rtime)
261 * is kept as an absolute time rather than as a delta, so that
262 * it is easy to keep periodic real-time signals from drifting.
263 *
264 * Virtual time timers are processed in the hardclock() routine of
265 * kern_clock.c. The real time timer is processed by a callout
266 * routine. Since a callout may be delayed in real time due to
267 * other processing in the system, it is possible for the real
268 * time callout routine (realitexpire, given below), to be delayed
269 * in real time past when it is supposed to occur. It does not
270 * suffice, therefore, to reload the real time .it_value from the
271 * real time .it_interval. Rather, we compute the next time in
272 * absolute time when the timer should go off.
273 */
274
275 /* ARGSUSED */
276 int
277 getitimer(struct proc *p, register struct getitimer_args *uap, __unused register_t *retval)
278 {
279 struct itimerval aitv;
280
281 if (uap->which > ITIMER_PROF)
282 return(EINVAL);
283 if (uap->which == ITIMER_REAL) {
284 /*
285 * If time for real time timer has passed return 0,
286 * else return difference between current time and
287 * time for the timer to go off.
288 */
289 aitv = p->p_realtimer;
290 if (timerisset(&p->p_rtime)) {
291 struct timeval now;
292
293 microuptime(&now);
294 if (timercmp(&p->p_rtime, &now, <))
295 timerclear(&aitv.it_value);
296 else {
297 aitv.it_value = p->p_rtime;
298 timevalsub(&aitv.it_value, &now);
299 }
300 }
301 else
302 timerclear(&aitv.it_value);
303 }
304 else
305 aitv = p->p_stats->p_timer[uap->which];
306
307 if (IS_64BIT_PROCESS(p)) {
308 struct user_itimerval user_itv;
309 user_itv.it_interval.tv_sec = aitv.it_interval.tv_sec;
310 user_itv.it_interval.tv_usec = aitv.it_interval.tv_usec;
311 user_itv.it_value.tv_sec = aitv.it_value.tv_sec;
312 user_itv.it_value.tv_usec = aitv.it_value.tv_usec;
313 return (copyout((caddr_t)&user_itv, uap->itv, sizeof (struct user_itimerval)));
314 } else {
315 return (copyout((caddr_t)&aitv, uap->itv, sizeof (struct itimerval)));
316 }
317 }
318
319 /* ARGSUSED */
320 int
321 setitimer(p, uap, retval)
322 struct proc *p;
323 register struct setitimer_args *uap;
324 register_t *retval;
325 {
326 struct itimerval aitv;
327 user_addr_t itvp;
328 int error;
329
330 if (uap->which > ITIMER_PROF)
331 return (EINVAL);
332 if ((itvp = uap->itv)) {
333 if (IS_64BIT_PROCESS(p)) {
334 struct user_itimerval user_itv;
335 if ((error = copyin(itvp, (caddr_t)&user_itv, sizeof (struct user_itimerval))))
336 return (error);
337 aitv.it_interval.tv_sec = user_itv.it_interval.tv_sec;
338 aitv.it_interval.tv_usec = user_itv.it_interval.tv_usec;
339 aitv.it_value.tv_sec = user_itv.it_value.tv_sec;
340 aitv.it_value.tv_usec = user_itv.it_value.tv_usec;
341 } else {
342 if ((error = copyin(itvp, (caddr_t)&aitv, sizeof (struct itimerval))))
343 return (error);
344 }
345 }
346 if ((uap->itv = uap->oitv) && (error = getitimer(p, (struct getitimer_args *)uap, retval)))
347 return (error);
348 if (itvp == 0)
349 return (0);
350 if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
351 return (EINVAL);
352 if (uap->which == ITIMER_REAL) {
353 thread_call_func_cancel((thread_call_func_t)realitexpire, (void *)p->p_pid, FALSE);
354 if (timerisset(&aitv.it_value)) {
355 microuptime(&p->p_rtime);
356 timevaladd(&p->p_rtime, &aitv.it_value);
357 thread_call_func_delayed(
358 (thread_call_func_t)realitexpire, (void *)p->p_pid,
359 tvtoabstime(&p->p_rtime));
360 }
361 else
362 timerclear(&p->p_rtime);
363
364 p->p_realtimer = aitv;
365 }
366 else
367 p->p_stats->p_timer[uap->which] = aitv;
368
369 return (0);
370 }
371
372 /*
373 * Real interval timer expired:
374 * send process whose timer expired an alarm signal.
375 * If time is not set up to reload, then just return.
376 * Else compute next time timer should go off which is > current time.
377 * This is where delay in processing this timeout causes multiple
378 * SIGALRM calls to be compressed into one.
379 */
380 void
381 realitexpire(
382 void *pid)
383 {
384 register struct proc *p;
385 struct timeval now;
386 boolean_t funnel_state;
387
388 funnel_state = thread_funnel_set(kernel_flock, TRUE);
389 p = pfind((pid_t)pid);
390 if (p == NULL) {
391 (void) thread_funnel_set(kernel_flock, FALSE);
392 return;
393 }
394
395 if (!timerisset(&p->p_realtimer.it_interval)) {
396 timerclear(&p->p_rtime);
397 psignal(p, SIGALRM);
398
399 (void) thread_funnel_set(kernel_flock, FALSE);
400 return;
401 }
402
403 microuptime(&now);
404 timevaladd(&p->p_rtime, &p->p_realtimer.it_interval);
405 if (timercmp(&p->p_rtime, &now, <=)) {
406 if ((p->p_rtime.tv_sec + 2) >= now.tv_sec) {
407 for (;;) {
408 timevaladd(&p->p_rtime, &p->p_realtimer.it_interval);
409 if (timercmp(&p->p_rtime, &now, >))
410 break;
411 }
412 }
413 else {
414 p->p_rtime = p->p_realtimer.it_interval;
415 timevaladd(&p->p_rtime, &now);
416 }
417 }
418
419 psignal(p, SIGALRM);
420
421 thread_call_func_delayed((thread_call_func_t)realitexpire, pid, tvtoabstime(&p->p_rtime));
422
423 (void) thread_funnel_set(kernel_flock, FALSE);
424 }
425
426 /*
427 * Check that a proposed value to load into the .it_value or
428 * .it_interval part of an interval timer is acceptable, and
429 * fix it to have at least minimal value (i.e. if it is less
430 * than the resolution of the clock, round it up.)
431 */
432 int
433 itimerfix(tv)
434 struct timeval *tv;
435 {
436
437 if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
438 tv->tv_usec < 0 || tv->tv_usec >= 1000000)
439 return (EINVAL);
440 if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < tick)
441 tv->tv_usec = tick;
442 return (0);
443 }
444
445 /*
446 * Decrement an interval timer by a specified number
447 * of microseconds, which must be less than a second,
448 * i.e. < 1000000. If the timer expires, then reload
449 * it. In this case, carry over (usec - old value) to
450 * reducint the value reloaded into the timer so that
451 * the timer does not drift. This routine assumes
452 * that it is called in a context where the timers
453 * on which it is operating cannot change in value.
454 */
455 int
456 itimerdecr(itp, usec)
457 register struct itimerval *itp;
458 int usec;
459 {
460
461 if (itp->it_value.tv_usec < usec) {
462 if (itp->it_value.tv_sec == 0) {
463 /* expired, and already in next interval */
464 usec -= itp->it_value.tv_usec;
465 goto expire;
466 }
467 itp->it_value.tv_usec += 1000000;
468 itp->it_value.tv_sec--;
469 }
470 itp->it_value.tv_usec -= usec;
471 usec = 0;
472 if (timerisset(&itp->it_value))
473 return (1);
474 /* expired, exactly at end of interval */
475 expire:
476 if (timerisset(&itp->it_interval)) {
477 itp->it_value = itp->it_interval;
478 itp->it_value.tv_usec -= usec;
479 if (itp->it_value.tv_usec < 0) {
480 itp->it_value.tv_usec += 1000000;
481 itp->it_value.tv_sec--;
482 }
483 } else
484 itp->it_value.tv_usec = 0; /* sec is already 0 */
485 return (0);
486 }
487
488 /*
489 * Add and subtract routines for timevals.
490 * N.B.: subtract routine doesn't deal with
491 * results which are before the beginning,
492 * it just gets very confused in this case.
493 * Caveat emptor.
494 */
495 void
496 timevaladd(
497 struct timeval *t1,
498 struct timeval *t2)
499 {
500
501 t1->tv_sec += t2->tv_sec;
502 t1->tv_usec += t2->tv_usec;
503 timevalfix(t1);
504 }
505 void
506 timevalsub(
507 struct timeval *t1,
508 struct timeval *t2)
509 {
510
511 t1->tv_sec -= t2->tv_sec;
512 t1->tv_usec -= t2->tv_usec;
513 timevalfix(t1);
514 }
515 void
516 timevalfix(
517 struct timeval *t1)
518 {
519
520 if (t1->tv_usec < 0) {
521 t1->tv_sec--;
522 t1->tv_usec += 1000000;
523 }
524 if (t1->tv_usec >= 1000000) {
525 t1->tv_sec++;
526 t1->tv_usec -= 1000000;
527 }
528 }
529
530 /*
531 * Return the best possible estimate of the time in the timeval
532 * to which tvp points.
533 */
534 void
535 microtime(
536 struct timeval *tvp)
537 {
538 clock_get_calendar_microtime((uint32_t *)&tvp->tv_sec, &tvp->tv_usec);
539 }
540
541 void
542 microuptime(
543 struct timeval *tvp)
544 {
545 clock_get_system_microtime((uint32_t *)&tvp->tv_sec, &tvp->tv_usec);
546 }
547
548 /*
549 * Ditto for timespec.
550 */
551 void
552 nanotime(
553 struct timespec *tsp)
554 {
555 clock_get_calendar_nanotime((uint32_t *)&tsp->tv_sec, (uint32_t *)&tsp->tv_nsec);
556 }
557
558 void
559 nanouptime(
560 struct timespec *tsp)
561 {
562 clock_get_system_nanotime((uint32_t *)&tsp->tv_sec, (uint32_t *)&tsp->tv_nsec);
563 }
564
565 uint64_t
566 tvtoabstime(
567 struct timeval *tvp)
568 {
569 uint64_t result, usresult;
570
571 clock_interval_to_absolutetime_interval(
572 tvp->tv_sec, NSEC_PER_SEC, &result);
573 clock_interval_to_absolutetime_interval(
574 tvp->tv_usec, NSEC_PER_USEC, &usresult);
575
576 return (result + usresult);
577 }
578 void
579 time_zone_slock_init(void)
580 {
581 /* allocate lock group attribute and group */
582 tz_slock_grp_attr = lck_grp_attr_alloc_init();
583
584 tz_slock_grp = lck_grp_alloc_init("tzlock", tz_slock_grp_attr);
585
586 /* Allocate lock attribute */
587 tz_slock_attr = lck_attr_alloc_init();
588
589 /* Allocate the spin lock */
590 tz_slock = lck_spin_alloc_init(tz_slock_grp, tz_slock_attr);
591 }
592