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)
 {

Reply via email to