Module Name: src Committed By: jmcneill Date: Thu Dec 15 03:42:33 UTC 2011
Modified Files: src/sys/arch/usermode/dev: clock.c cpu.c src/sys/arch/usermode/include: thunk.h src/sys/arch/usermode/usermode: thunk.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/arch/usermode/dev/clock.c cvs rdiff -u -r1.54 -r1.55 src/sys/arch/usermode/dev/cpu.c cvs rdiff -u -r1.40 -r1.41 src/sys/arch/usermode/include/thunk.h cvs rdiff -u -r1.46 -r1.47 src/sys/arch/usermode/usermode/thunk.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/arch/usermode/dev/clock.c diff -u src/sys/arch/usermode/dev/clock.c:1.22 src/sys/arch/usermode/dev/clock.c:1.23 --- src/sys/arch/usermode/dev/clock.c:1.22 Tue Dec 13 22:22:08 2011 +++ src/sys/arch/usermode/dev/clock.c Thu Dec 15 03:42:32 2011 @@ -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 <jmcne...@invisible.ca> @@ -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 unsigned int clock_getcounter(str 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 @@ static struct timecounter clock_timecoun 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 @@ static void 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 @@ clock_attach(device_t parent, device_t s 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(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) +{ curcpu()->ci_idepth++; - spl_intr(IPL_SOFTCLOCK, (void (*)(void *)) hardclock, &cf); + spl_intr(IPL_SOFTCLOCK, clock_intr, NULL); curcpu()->ci_idepth--; } Index: src/sys/arch/usermode/dev/cpu.c diff -u src/sys/arch/usermode/dev/cpu.c:1.54 src/sys/arch/usermode/dev/cpu.c:1.55 --- src/sys/arch/usermode/dev/cpu.c:1.54 Thu Dec 15 02:09:15 2011 +++ src/sys/arch/usermode/dev/cpu.c Thu Dec 15 03:42:32 2011 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 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 Index: src/sys/arch/usermode/include/thunk.h diff -u src/sys/arch/usermode/include/thunk.h:1.40 src/sys/arch/usermode/include/thunk.h:1.41 --- src/sys/arch/usermode/include/thunk.h:1.40 Thu Dec 15 01:30:04 2011 +++ src/sys/arch/usermode/include/thunk.h Thu Dec 15 03:42:32 2011 @@ -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 <jmcne...@invisible.ca> @@ -77,6 +77,10 @@ unsigned int thunk_getcounter(void); 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); Index: src/sys/arch/usermode/usermode/thunk.c diff -u src/sys/arch/usermode/usermode/thunk.c:1.46 src/sys/arch/usermode/usermode/thunk.c:1.47 --- src/sys/arch/usermode/usermode/thunk.c:1.46 Thu Dec 15 01:30:04 2011 +++ src/sys/arch/usermode/usermode/thunk.c Thu Dec 15 03:42:33 2011 @@ -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 <jmcne...@invisible.ca> @@ -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 @@ thunk_clock_getres_monotonic(void) 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) {