Messages in this thread Patch in this message | | | From | Bruce Elliott <> | Date | Wed, 24 Feb 1999 01:42:45 -0800 | Subject | Re: gettimeofday & high-res timers |
| |
On Feb 24, 11:00am, Tom Holroyd wrote: } Subject: Re: gettimeofday & high-res timers } On Tue, 23 Feb 1999, Vojtech Pavlik wrote: } } Hmm. On my AlphaPC164LX running 2.2.1 with /dev/rtc enabled, the timetest } program produces deltas of -4088 or so every second! Very sawtooth.
You probably need the missing second half of a patch I submitted, but missed the 2.2 cutoff.
> From: Bruce Elliott <bde@nwlink.com> > Message-Id: <199901110550.VAA01240@mail.nwlink.com> > Date: Sun, 10 Jan 1999 21:47:53 -0800 > X-Mailer: Mail User's Shell (7.2.5 10/14/92) > To: linux-kernel@vger.rutgers.edu > Subject: Re: Problems in ALPHA Timekeeping > Cc: torvalds@transmeta.com > Sender: owner-linux-kernel@vger.rutgers.edu > Precedence: bulk > X-Loop: majordomo@vger.rutgers.edu > X-Orcpt: rfc822;linux-kernel-outgoing-dig > X-UIDL: 1447633ab1bad139c20ce340083a192d > Status: OR > > (This probably doesn't have a very high priority, as I have received zero > comments on the first patch. The timekeeping does work much better with > this however.) > > My previous patch to arch/alpha/time.c was somewhat incomplete. > > timer_interrupt() logic did some updating even when no tick had passed. > > do_gettimeofday() didn't account for the unused partial tick. > > do_settimeofday() didn't handle any of this. > > Making this work properly with SMP will require more changes.
====== --- linux.rels/arch/alpha/kernel/time.c Sun Dec 27 15:21:50 1998 +++ linux/arch/alpha/kernel/time.c Tue Dec 29 20:45:41 1998 @@ -93,14 +98,17 @@ /* * Calculate how many ticks have passed since the last update, * including any previous partial leftover. Save any resulting - * fraction for the next pass. + * fraction for the next pass. Don't change anything unless + * at least one tick has passed. */ now = rpcc(); delta = now - state.last_time; - state.last_time = now; delta = delta * state.scaled_ticks_per_cycle + state.partial_tick; - state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); nticks = delta >> FIX_SHIFT; + if (nticks) { + state.last_time = now; + state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); + } while (nticks > 0) { do_timer(regs); @@ -339,12 +378,14 @@ { unsigned long flags, now, delta_cycles, delta_usec; unsigned long sec, usec; + unsigned long partial_tick; - now = rpcc(); save_and_cli(flags); + now = rpcc(); sec = xtime.tv_sec; usec = xtime.tv_usec; delta_cycles = now - state.last_time; + partial_tick = state.partial_tick; restore_flags(flags); /* @@ -360,7 +401,8 @@ * with no clear gain. */ - delta_usec = delta_cycles * state.scaled_ticks_per_cycle * 15625; + delta_usec = delta_cycles * state.scaled_ticks_per_cycle + partial_tick; + delta_usec *= 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; usec += delta_usec; @@ -376,8 +418,24 @@ void do_settimeofday(struct timeval *tv) { + unsigned long delta_usec; + + /* + * The offset that is added into time in do_gettimeofday above must + * be subtracted here to keep a coherent view of the time. Without + * this, a full-tick error is possible. + */ cli(); + delta_usec = (rpcc() - state.last_time) * state.scaled_ticks_per_cycle + + state.partial_tick; + delta_usec *= 15625; + delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; xtime = *tv; + xtime.tv_usec -= delta_usec; + if (xtime.tv_usec < 0) { + xtime.tv_usec += 1000000; + xtime.tv_sec--; + } time_state = TIME_BAD; time_maxerror = 0x70000000; time_esterror = 0x70000000; ====== -- B. D. Elliott bde@nwlink.com (Seattle)
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |