Module Name: src Committed By: yamt Date: Fri Apr 8 10:35:38 UTC 2011
Modified Files: src/sys/kern: kern_time.c Log Message: implement timer_create of CLOCK_MONOTONIC To generate a diff of this commit: cvs rdiff -u -r1.167 -r1.168 src/sys/kern/kern_time.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_time.c diff -u src/sys/kern/kern_time.c:1.167 src/sys/kern/kern_time.c:1.168 --- src/sys/kern/kern_time.c:1.167 Tue Apr 5 00:27:35 2011 +++ src/sys/kern/kern_time.c Fri Apr 8 10:35:37 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.167 2011/04/05 00:27:35 yamt Exp $ */ +/* $NetBSD: kern_time.c,v 1.168 2011/04/08 10:35:37 yamt Exp $ */ /*- * Copyright (c) 2000, 2004, 2005, 2007, 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.167 2011/04/05 00:27:35 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.168 2011/04/08 10:35:37 yamt Exp $"); #include <sys/param.h> #include <sys/resourcevar.h> @@ -95,6 +95,13 @@ struct pool ptimer_pool, ptimers_pool; +#define CLOCK_VIRTUAL_P(clockid) \ + ((clockid) == CLOCK_VIRTUAL || (clockid) == CLOCK_PROF) + +CTASSERT(ITIMER_REAL == CLOCK_REALTIME); +CTASSERT(ITIMER_VIRTUAL == CLOCK_VIRTUAL); +CTASSERT(ITIMER_PROF == CLOCK_PROF); + /* * Initialize timekeeping. */ @@ -538,7 +545,8 @@ p = l->l_proc; - if (id < CLOCK_REALTIME || id > CLOCK_PROF) + if (id != CLOCK_REALTIME && id != CLOCK_VIRTUAL && + id != CLOCK_PROF && id != CLOCK_MONOTONIC) return (EINVAL); if ((pts = p->p_timers) == NULL) @@ -572,6 +580,7 @@ pt->pt_ev.sigev_notify = SIGEV_SIGNAL; switch (id) { case CLOCK_REALTIME: + case CLOCK_MONOTONIC: pt->pt_ev.sigev_signo = SIGALRM; break; case CLOCK_VIRTUAL: @@ -596,8 +605,8 @@ pt->pt_entry = timerid; pt->pt_queued = false; timespecclear(&pt->pt_time.it_value); - if (id == CLOCK_REALTIME) - callout_init(&pt->pt_ch, 0); + if (!CLOCK_VIRTUAL_P(id)) + callout_init(&pt->pt_ch, CALLOUT_MPSAFE); else pt->pt_active = 0; @@ -631,7 +640,7 @@ mutex_spin_exit(&timer_lock); return (EINVAL); } - if (pt->pt_type != CLOCK_REALTIME) { + if (CLOCK_VIRTUAL_P(pt->pt_type)) { if (pt->pt_active) { ptn = LIST_NEXT(pt, pt_list); LIST_REMOVE(pt, pt_list); @@ -649,9 +658,8 @@ /* * Set up the given timer. The value in pt->pt_time.it_value is taken - * to be an absolute time for CLOCK_REALTIME timers and a relative - * time for virtual timers. - * Must be called at splclock(). + * to be an absolute time for CLOCK_REALTIME/CLOCK_MONOTONIC timers and + * a relative time for CLOCK_VIRTUAL/CLOCK_PROF timers. */ void timer_settime(struct ptimer *pt) @@ -661,8 +669,8 @@ KASSERT(mutex_owned(&timer_lock)); - if (pt->pt_type == CLOCK_REALTIME) { - callout_stop(&pt->pt_ch); + if (!CLOCK_VIRTUAL_P(pt->pt_type)) { + callout_halt(&pt->pt_ch, &timer_lock); if (timespecisset(&pt->pt_time.it_value)) { /* * Don't need to check tshzto() return value, here. @@ -719,7 +727,7 @@ KASSERT(mutex_owned(&timer_lock)); *aits = pt->pt_time; - if (pt->pt_type == CLOCK_REALTIME) { + if (!CLOCK_VIRTUAL_P(pt->pt_type)) { /* * Convert from absolute to relative time in .it_value * part of real time timer. If time for real time @@ -728,7 +736,11 @@ * off. */ if (timespecisset(&aits->it_value)) { - getnanotime(&now); + if (pt->pt_type == CLOCK_REALTIME) { + getnanotime(&now); + } else { /* CLOCK_MONOTONIC */ + getnanouptime(&now); + } if (timespeccmp(&aits->it_value, &now, <)) timespecclear(&aits->it_value); else @@ -818,9 +830,13 @@ * negative, which would confuse the comparison tests. */ if (timespecisset(&pt->pt_time.it_value)) { - if (pt->pt_type == CLOCK_REALTIME) { + if (!CLOCK_VIRTUAL_P(pt->pt_type)) { if ((flags & TIMER_ABSTIME) == 0) { - getnanotime(&now); + if (pt->pt_type == CLOCK_REALTIME) { + getnanotime(&now); + } else { /* CLOCK_MONOTONIC */ + getnanouptime(&now); + } timespecadd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); } @@ -1110,6 +1126,8 @@ struct ptimers *pts; struct ptimer *pt, *spare; + KASSERT(which == CLOCK_REALTIME || which == CLOCK_VIRTUAL || + which == CLOCK_PROF); if (itimerfix(&itvp->it_value) || itimerfix(&itvp->it_interval)) return (EINVAL); @@ -1230,12 +1248,12 @@ for (ptn = LIST_FIRST(&pts->pts_virtual); ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL]; ptn = LIST_NEXT(ptn, pt_list)) { - KASSERT(ptn->pt_type != CLOCK_REALTIME); + KASSERT(ptn->pt_type == CLOCK_VIRTUAL); timespecadd(&ts, &ptn->pt_time.it_value, &ts); } LIST_FIRST(&pts->pts_virtual) = NULL; if (ptn) { - KASSERT(ptn->pt_type != CLOCK_REALTIME); + KASSERT(ptn->pt_type == CLOCK_VIRTUAL); timespecadd(&ts, &ptn->pt_time.it_value, &ptn->pt_time.it_value); LIST_INSERT_HEAD(&pts->pts_virtual, ptn, pt_list); @@ -1244,12 +1262,12 @@ for (ptn = LIST_FIRST(&pts->pts_prof); ptn && ptn != pts->pts_timers[ITIMER_PROF]; ptn = LIST_NEXT(ptn, pt_list)) { - KASSERT(ptn->pt_type != CLOCK_REALTIME); + KASSERT(ptn->pt_type == CLOCK_PROF); timespecadd(&ts, &ptn->pt_time.it_value, &ts); } LIST_FIRST(&pts->pts_prof) = NULL; if (ptn) { - KASSERT(ptn->pt_type != CLOCK_REALTIME); + KASSERT(ptn->pt_type == CLOCK_PROF); timespecadd(&ts, &ptn->pt_time.it_value, &ptn->pt_time.it_value); LIST_INSERT_HEAD(&pts->pts_prof, ptn, pt_list); @@ -1280,12 +1298,12 @@ pt = pts->pts_timers[index]; pts->pts_timers[index] = NULL; - if (pt->pt_type == CLOCK_REALTIME) + if (!CLOCK_VIRTUAL_P(pt->pt_type)) callout_halt(&pt->pt_ch, &timer_lock); if (pt->pt_queued) TAILQ_REMOVE(&timer_queue, pt, pt_chain); mutex_spin_exit(&timer_lock); - if (pt->pt_type == CLOCK_REALTIME) + if (!CLOCK_VIRTUAL_P(pt->pt_type)) callout_destroy(&pt->pt_ch); pool_put(&ptimer_pool, pt); } @@ -1306,6 +1324,7 @@ struct itimerspec *itp; KASSERT(mutex_owned(&timer_lock)); + KASSERT(CLOCK_VIRTUAL_P(pt->pt_type)); itp = &pt->pt_time; if (itp->it_value.tv_nsec < nsec) {