From f5c0f0c5a864c4263400210b8c619fa333696081 Mon Sep 17 00:00:00 2001 From: eeh Date: Fri, 29 Dec 2000 18:35:18 +0000 Subject: [PATCH] Separate schedclock from statclock on machines w/counter-timers. This lets us lower splsched(). --- sys/arch/sparc64/sparc64/clock.c | 51 ++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/sys/arch/sparc64/sparc64/clock.c b/sys/arch/sparc64/sparc64/clock.c index 938d0d53b777..b983fc8c9447 100644 --- a/sys/arch/sparc64/sparc64/clock.c +++ b/sys/arch/sparc64/sparc64/clock.c @@ -1,4 +1,4 @@ -/* $NetBSD: clock.c,v 1.36 2000/12/19 05:09:06 mrg Exp $ */ +/* $NetBSD: clock.c,v 1.37 2000/12/29 18:35:18 eeh Exp $ */ /* * Copyright (c) 1992, 1993 @@ -92,6 +92,8 @@ #include #include +extern u_int64_t cpu_clockrate; + /* * Statistics clock interval and variance, in usec. Variance must be a * power of two. Since this gives us an even number, not an odd number, @@ -106,10 +108,12 @@ int statmin; /* statclock interval - 1/2*variance */ int timerok; static long tick_increment; +int schedintr __P((void *)); static struct intrhand level10 = { clockintr }; static struct intrhand level0 = { tickintr }; static struct intrhand level14 = { statintr }; +static struct intrhand schedint = { schedintr }; /* * clock (eeprom) attaches at the sbus or the ebus (PCI) @@ -531,7 +535,6 @@ void cpu_initclocks() { int statint, minint; - extern u_int64_t cpu_clockrate; static u_int64_t start_time; #ifdef DEBUG extern int intrdebug; @@ -627,6 +630,15 @@ cpu_initclocks() while (statvar > minint) statvar >>= 1; + /* + * Establish scheduler softint. + */ + schedint.ih_pil = PIL_SCHED; + schedint.ih_clr = NULL; + schedint.ih_arg = 0; + schedint.ih_pending = 0; + schedhz = stathz/4; + /* * Enable timers * @@ -670,10 +682,33 @@ setstatclockrate(newhz) * console input, we need to check for that here as well, and generate * a software interrupt to read it. */ +static int clockcheck = 0; int clockintr(cap) void *cap; { +#ifdef DEBUG + static int64_t tick_base = 0; + int64_t t = (u_int64_t)tick(); + + if (!tick_base) { + tick_base = (time.tv_sec * 1000000LL + time.tv_usec) + * 1000000LL / cpu_clockrate; + tick_base -= t; + } else if (clockcheck) { + int64_t tk = t; + int64_t clk = (time.tv_sec * 1000000LL + time.tv_usec); + t -= tick_base; + t = t * 1000000LL / cpu_clockrate; + if (t - clk > hz) { + printf("Clock lost an interrupt!\n"); + printf("Actual: %llx Expected: %llx tick %llx tick_base %llx\n", + (long long)t, (long long)clk, (long long)tk, (long long)tick_base); + Debugger(); + tick_base = 0; + } + } +#endif /* Let locore.s clear the interrupt for us. */ hardclock((struct clockframe *)cap); return (1); @@ -720,6 +755,7 @@ statintr(cap) void *cap; { register u_long newint, r, var; + struct cpu_info *ci = curcpu(); #ifdef NOT_DEBUG printf("statclock: count %x:%x, limit %x:%x\n", @@ -744,11 +780,22 @@ statintr(cap) } while (r == 0); newint = statmin + r; + if (schedhz) + if ((++ci->ci_schedstate.spc_schedticks & 3) == 0) + send_softint(-1, PIL_SCHED, &schedint); stxa((vaddr_t)&timerreg_4u.t_timer[1].t_limit, ASI_NUCLEUS, tmr_ustolim(newint)|TMR_LIM_IEN|TMR_LIM_RELOAD); return (1); } +int +schedintr(arg) + void *arg; +{ + if (curproc) + schedclock(curproc); + return (1); +} /* * Set up the system's time, given a `reasonable' time value. */