Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/usermode Improve usermode timecounter. It's unreaso...



details:   https://anonhg.NetBSD.org/src/rev/96336e2bc8c7
branches:  trunk
changeset: 772038:96336e2bc8c7
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Thu Dec 15 03:42:32 2011 +0000

description:
Improve usermode timecounter. It's unreasonable to assume that we'll get
100 "SIGALRM" per second with an ITIMER_REAL at 100Hz on a HZ=100 host as
the timer may expire before a pending signal has been delivered.

Instead of setitimer, use timer_create + timer_settime and from our
intr handler use timer_getoverrun to determine how many ticks we have
missed.

diffstat:

 sys/arch/usermode/dev/clock.c      |  46 ++++++++++++++++++++-----------------
 sys/arch/usermode/dev/cpu.c        |  11 +++-----
 sys/arch/usermode/include/thunk.h  |   6 ++++-
 sys/arch/usermode/usermode/thunk.c |  37 ++++++++++++++++++++++++++++-
 4 files changed, 69 insertions(+), 31 deletions(-)

diffs (218 lines):

diff -r 715fd7d9fa39 -r 96336e2bc8c7 sys/arch/usermode/dev/clock.c
--- a/sys/arch/usermode/dev/clock.c     Thu Dec 15 02:09:15 2011 +0000
+++ b/sys/arch/usermode/dev/clock.c     Thu Dec 15 03:42:32 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.22 2011/12/13 22:22:08 jmcneill Exp $ */
+/* $NetBSD: clock.c,v 1.23 2011/12/15 03:42:32 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -26,8 +26,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "opt_hz.h"
+
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.22 2011/12/13 22:22:08 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.23 2011/12/15 03:42:32 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -54,10 +56,10 @@
 
 static int     clock_todr_gettime(struct todr_chip_handle *, struct timeval *);
 
-typedef struct clock_softc {
+struct clock_softc {
        device_t                sc_dev;
        struct todr_chip_handle sc_todr;
-} clock_softc_t;
+};
 
 static struct timecounter clock_timecounter = {
        clock_getcounter,       /* get_timecount */
@@ -70,11 +72,9 @@
        NULL,                   /* next */
 };
 
-static struct clock_softc *clock_sc;
-
+timer_t clock_timerid;
 
-
-CFATTACH_DECL_NEW(clock, sizeof(clock_softc_t),
+CFATTACH_DECL_NEW(clock, sizeof(struct clock_softc),
     clock_match, clock_attach, NULL, NULL);
 
 static int
@@ -92,15 +92,11 @@
 clock_attach(device_t parent, device_t self, void *opaque)
 {
        static struct sigaction sa;
-       clock_softc_t *sc = device_private(self);
-       long tcres;
+       struct clock_softc *sc = device_private(self);
 
        aprint_naive("\n");
        aprint_normal("\n");
 
-       KASSERT(clock_sc == NULL);
-       clock_sc = sc;
-
        sc->sc_dev = self;
 
        sc->sc_todr.todr_gettime = clock_todr_gettime;
@@ -109,25 +105,33 @@
        memset(&sa, 0, sizeof(sa));
        thunk_sigemptyset(&sa.sa_mask);
        sa.sa_sigaction = clock_signal;
-       sa.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+       sa.sa_flags = SA_RESTART | SA_ONSTACK;
        if (thunk_sigaction(SIGALRM, &sa, NULL) == -1)
                panic("couldn't register SIGALRM handler : %d",
                    thunk_geterrno());
 
-       tcres = thunk_clock_getres_monotonic();
-       if (tcres > 0) {
-               clock_timecounter.tc_quality = 1000;
-       }
+       clock_timerid = thunk_timer_attach();
+
+       clock_timecounter.tc_quality = 1000;
        tc_init(&clock_timecounter);
 }
 
 static void
+clock_intr(void *priv)
+{
+       struct clockframe cf;
+       int nticks = thunk_timer_getoverrun(clock_timerid) + 1;
+
+       while (nticks-- > 0) {
+               hardclock(&cf);
+       };
+}
+
+static void
 clock(void)
 {
-       struct clockframe cf;
-
        curcpu()->ci_idepth++;
-       spl_intr(IPL_SOFTCLOCK, (void (*)(void *)) hardclock, &cf);
+       spl_intr(IPL_SOFTCLOCK, clock_intr, NULL);
        curcpu()->ci_idepth--;
 }
 
diff -r 715fd7d9fa39 -r 96336e2bc8c7 sys/arch/usermode/dev/cpu.c
--- a/sys/arch/usermode/dev/cpu.c       Thu Dec 15 02:09:15 2011 +0000
+++ b/sys/arch/usermode/dev/cpu.c       Thu Dec 15 03:42:32 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.54 2011/12/15 02:09:15 jmcneill Exp $ */
+/* $NetBSD: cpu.c,v 1.55 2011/12/15 03:42:32 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
 #include "opt_hz.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.54 2011/12/15 02:09:15 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.55 2011/12/15 03:42:32 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -364,12 +364,9 @@
 void
 cpu_initclocks(void)
 {
-       struct thunk_itimerval itimer;
+       extern timer_t clock_timerid;
 
-       itimer.it_interval.tv_sec = 0;
-       itimer.it_interval.tv_usec = 1000000 / HZ;
-       itimer.it_value = itimer.it_interval;
-       thunk_setitimer(ITIMER_REAL, &itimer, NULL);
+       thunk_timer_start(clock_timerid, HZ);
 }
 
 void
diff -r 715fd7d9fa39 -r 96336e2bc8c7 sys/arch/usermode/include/thunk.h
--- a/sys/arch/usermode/include/thunk.h Thu Dec 15 02:09:15 2011 +0000
+++ b/sys/arch/usermode/include/thunk.h Thu Dec 15 03:42:32 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.h,v 1.40 2011/12/15 01:30:04 jmcneill Exp $ */
+/* $NetBSD: thunk.h,v 1.41 2011/12/15 03:42:32 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -77,6 +77,10 @@
 long   thunk_clock_getres_monotonic(void);
 int    thunk_usleep(useconds_t);
 
+timer_t        thunk_timer_attach(void);
+int    thunk_timer_start(timer_t, int);
+int    thunk_timer_getoverrun(timer_t);
+
 void   thunk_exit(int);
 void   thunk_abort(void);
 
diff -r 715fd7d9fa39 -r 96336e2bc8c7 sys/arch/usermode/usermode/thunk.c
--- a/sys/arch/usermode/usermode/thunk.c        Thu Dec 15 02:09:15 2011 +0000
+++ b/sys/arch/usermode/usermode/thunk.c        Thu Dec 15 03:42:32 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: thunk.c,v 1.46 2011/12/15 01:30:04 jmcneill Exp $ */
+/* $NetBSD: thunk.c,v 1.47 2011/12/15 03:42:33 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifdef __NetBSD__
-__RCSID("$NetBSD: thunk.c,v 1.46 2011/12/15 01:30:04 jmcneill Exp $");
+__RCSID("$NetBSD: thunk.c,v 1.47 2011/12/15 03:42:33 jmcneill Exp $");
 #endif
 
 #include <sys/types.h>
@@ -229,6 +229,39 @@
        return (long)(res.tv_sec * 1000000000ULL + res.tv_nsec);
 }
 
+timer_t
+thunk_timer_attach(void)
+{
+       timer_t timerid;
+       int error;
+
+       error = timer_create(CLOCK_MONOTONIC, NULL, &timerid);
+       if (error) {
+               perror("timer_create CLOCK_MONOTONIC");
+               abort();
+       }
+
+       return timerid;
+}
+
+int
+thunk_timer_start(timer_t timerid, int freq)
+{
+       struct itimerspec tim;
+
+       tim.it_interval.tv_sec = 0;
+       tim.it_interval.tv_nsec = 1000000000 / freq;
+       tim.it_value = tim.it_interval;
+
+       return timer_settime(timerid, TIMER_RELTIME, &tim, NULL);
+}
+
+int
+thunk_timer_getoverrun(timer_t timerid)
+{
+       return timer_getoverrun(timerid);
+}
+
 int
 thunk_usleep(useconds_t microseconds)
 {



Home | Main Index | Thread Index | Old Index