Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern implement timer_create of CLOCK_MONOTONIC



details:   https://anonhg.NetBSD.org/src/rev/6b31587f11f5
branches:  trunk
changeset: 763955:6b31587f11f5
user:      yamt <yamt%NetBSD.org@localhost>
date:      Fri Apr 08 10:35:37 2011 +0000

description:
implement timer_create of CLOCK_MONOTONIC

diffstat:

 sys/kern/kern_time.c |  61 ++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 40 insertions(+), 21 deletions(-)

diffs (193 lines):

diff -r 7add0e6e846c -r 6b31587f11f5 sys/kern/kern_time.c
--- a/sys/kern/kern_time.c      Fri Apr 08 10:14:24 2011 +0000
+++ b/sys/kern/kern_time.c      Fri Apr 08 10:35:37 2011 +0000
@@ -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) {



Home | Main Index | Thread Index | Old Index