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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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)
{