diff options
author | marius <marius@FreeBSD.org> | 2010-10-17 16:46:54 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2010-10-17 16:46:54 +0000 |
commit | a5b338a9670cf20b4e13dad7d98dd2782ad6900a (patch) | |
tree | ca843d024259d500fd3b0888fc094af7c0493edc /sys/sparc64 | |
parent | 5f20c85d80fd664a636e53eb3bc630b106d8ea47 (diff) | |
download | FreeBSD-src-a5b338a9670cf20b4e13dad7d98dd2782ad6900a.zip FreeBSD-src-a5b338a9670cf20b4e13dad7d98dd2782ad6900a.tar.gz |
- In oneshot-mode it doesn't make sense to try to compensate the clock
drift in order to achieve a more stable clock as the tick intervals may
vary in the first place. In fact I haven't seen this code kick in when
in oneshot-mode so just skip it in that case.
- There's no need to explicitly stop the (S)TICK counter in oneshot-mode
with every tick as it just won't trigger again with the (S)TICK compare
register set to a value in the past (with a wrap-around once every ~195
years of uptime at 1.5 GHz this isn't something we have to worry about
in practice).
- Given that we'll disable interrupts completely anyway there's no
need to enter critical sections.
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/sparc64/tick.c | 86 |
1 files changed, 41 insertions, 45 deletions
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c index 7d693c7..3291687 100644 --- a/sys/sparc64/sparc64/tick.c +++ b/sys/sparc64/sparc64/tick.c @@ -96,8 +96,8 @@ static int tick_et_start(struct eventtimer *et, static int tick_et_stop(struct eventtimer *et); static void tick_intr(struct trapframe *tf); static void tick_intr_bbwar(struct trapframe *tf); -static inline void tick_hardclock_common(struct trapframe *tf, u_long tick, - u_long adj); +static inline void tick_hardclock_periodic(struct trapframe *tf, u_long tick, + u_long tick_increment, u_long adj); static inline void tick_process(struct trapframe *tf); static void stick_intr(struct trapframe *tf); @@ -225,18 +225,18 @@ tick_intr(struct trapframe *tf) u_long adj, tick, tick_increment; register_t s; - critical_enter(); - adj = PCPU_GET(tickadj); - tick_increment = PCPU_GET(tickincrement); s = intr_disable(); - tick = rd(tick); - if (tick_increment != 0) + tick_increment = PCPU_GET(tickincrement); + if (tick_increment != 0) { + adj = PCPU_GET(tickadj); + tick = rd(tick); wr(tick_cmpr, tick + tick_increment - adj, 0); - else - wr(tick_cmpr, 1L << 63, 0); - intr_restore(s); - tick_hardclock_common(tf, tick, adj); - critical_exit(); + intr_restore(s); + tick_hardclock_periodic(tf, tick, tick_increment, adj); + } else { + intr_restore(s); + tick_process(tf); + } } static void @@ -245,18 +245,18 @@ tick_intr_bbwar(struct trapframe *tf) u_long adj, tick, tick_increment; register_t s; - critical_enter(); - adj = PCPU_GET(tickadj); - tick_increment = PCPU_GET(tickincrement); s = intr_disable(); - tick = rd(tick); - if (tick_increment != 0) + tick_increment = PCPU_GET(tickincrement); + if (tick_increment != 0) { + adj = PCPU_GET(tickadj); + tick = rd(tick); wrtickcmpr(tick + tick_increment - adj, 0); - else - wrtickcmpr(1L << 63, 0); - intr_restore(s); - tick_hardclock_common(tf, tick, adj); - critical_exit(); + intr_restore(s); + tick_hardclock_periodic(tf, tick, tick_increment, adj); + } else { + intr_restore(s); + tick_process(tf); + } } static void @@ -265,28 +265,28 @@ stick_intr(struct trapframe *tf) u_long adj, stick, tick_increment; register_t s; - critical_enter(); - adj = PCPU_GET(tickadj); - tick_increment = PCPU_GET(tickincrement); s = intr_disable(); - stick = rdstick(); - if (tick_increment != 0) + tick_increment = PCPU_GET(tickincrement); + if (tick_increment != 0) { + adj = PCPU_GET(tickadj); + stick = rdstick(); wrstickcmpr(stick + tick_increment - adj, 0); - else - wrstickcmpr(1L << 63, 0); - intr_restore(s); - tick_hardclock_common(tf, stick, adj); - critical_exit(); + intr_restore(s); + tick_hardclock_periodic(tf, stick, tick_increment, adj); + } else { + intr_restore(s); + tick_process(tf); + } } static inline void -tick_hardclock_common(struct trapframe *tf, u_long tick, u_long adj) +tick_hardclock_periodic(struct trapframe *tf, u_long tick, + u_long tick_increment, u_long adj) { - u_long ref, tick_increment; + u_long ref; long delta; int count; - tick_increment = PCPU_GET(tickincrement); ref = PCPU_GET(tickref); delta = tick - ref; count = 0; @@ -297,8 +297,6 @@ tick_hardclock_common(struct trapframe *tf, u_long tick, u_long adj) if (adj != 0) adjust_ticks++; count++; - if (tick_increment == 0) - break; } if (count > 0) { adjust_missed += count - 1; @@ -361,11 +359,10 @@ tick_get_timecount_mp(struct timecounter *tc) #endif static int -tick_et_start(struct eventtimer *et, - struct bintime *first, struct bintime *period) +tick_et_start(struct eventtimer *et, struct bintime *first, + struct bintime *period) { - u_long fdiv, div; - u_long base; + u_long base, div, fdiv; register_t s; if (period != NULL) { @@ -387,22 +384,21 @@ tick_et_start(struct eventtimer *et, * on all CPUs to avoid inaccuracies for migrating processes. Leave * out one tick to make sure that it is not missed. */ - critical_enter(); - PCPU_SET(tickadj, 0); s = intr_disable(); if (hardclock_use_stick != 0) base = rdstick(); else base = rd(tick); - if (div != 0) + if (div != 0) { + PCPU_SET(tickadj, 0); base = roundup(base, div); + } PCPU_SET(tickref, base); if (hardclock_use_stick != 0) wrstickcmpr(base + fdiv, 0); else wrtickcmpr(base + fdiv, 0); intr_restore(s); - critical_exit(); return (0); } |