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