Messages in this thread | | | Date | Wed, 17 Aug 2005 12:03:47 -0700 | From | George Anzinger <> | Subject | Re: [RFC - 0/9] Generic timekeeping subsystem (v. B5) |
| |
Roman Zippel wrote:
~
The thing that worries me about this function is that it does every thing in usec. We are using nsec in xtime now and I wonder if it would not be more accurate to do the math in nsecs. Even tick size (tick_nsec) does not translate well to usec, it currently being 999849 nsecs.
George > --- > > kernel/time.c | 3 ++- > kernel/timer.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 55 insertions(+), 1 deletion(-) > > Index: linux-2.6/kernel/time.c > =================================================================== > --- linux-2.6.orig/kernel/time.c 2005-07-13 03:18:04.000000000 +0200 > +++ linux-2.6/kernel/time.c 2005-08-16 01:37:20.000000000 +0200 > @@ -366,8 +366,9 @@ int do_adjtimex(struct timex *txc) > } /* txc->modes & ADJ_OFFSET */ > if (txc->modes & ADJ_TICK) { > tick_usec = txc->tick; > - tick_nsec = TICK_USEC_TO_NSEC(tick_usec); > } > + if (txc->modes & (ADJ_FREQUENCY|ADJ_OFFSET|ADJ_TICK)) > + time_recalc(); > } /* txc->modes */ > leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0 > || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0 > Index: linux-2.6/kernel/timer.c > =================================================================== > --- linux-2.6.orig/kernel/timer.c 2005-07-13 03:18:04.000000000 +0200 > +++ linux-2.6/kernel/timer.c 2005-08-16 23:10:53.000000000 +0200 > @@ -559,6 +559,7 @@ found: > */ > unsigned long tick_usec = TICK_USEC; /* USER_HZ period (usec) */ > unsigned long tick_nsec = TICK_NSEC; /* ACTHZ period (nsec) */ > +unsigned long tick_nsec2 = TICK_NSEC; > > /* > * The current time > @@ -569,6 +570,7 @@ unsigned long tick_nsec = TICK_NSEC; /* > * the usual normalization. > */ > struct timespec xtime __attribute__ ((aligned (16))); > +struct timespec xtime2 __attribute__ ((aligned (16))); > struct timespec wall_to_monotonic __attribute__ ((aligned (16))); > > EXPORT_SYMBOL(xtime); > @@ -596,6 +598,33 @@ static long time_adj; /* tick adjust ( > long time_reftime; /* time at last adjustment (s) */ > long time_adjust; > long time_next_adjust; > +static long time_adj2, time_adj2_cur, time_freq_adj2, time_freq_phase2, time_phase2; > + > +void time_recalc(void) > +{ > + long f, t; > + tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
This leaves bits on the floor. Is it not possible to do this whole calculation in nano seconds? Currently, for example, tick_nsec is 999849... > + > + t = time_freq >> (SHIFT_USEC + 8); > + if (t) { > + time_freq -= t << (SHIFT_USEC + 8); > + t *= 1000 << 8; > + } > + f = time_freq * 125; > + t += tick_usec * USER_HZ * 1000 + (f >> (SHIFT_USEC - 3)); > + f &= (1 << (SHIFT_USEC - 3)) - 1; > + tick_nsec2 = t / HZ; > + f += (t % HZ) << (SHIFT_USEC - 3); > + f <<= 5; > + time_adj2 = f / HZ; > + time_freq_adj2 = f % HZ; > + > + printk("tr: %ld.%09ld(%ld,%ld,%ld,%ld) - %ld.%09ld(%ld,%ld,%ld)\n", > + xtime.tv_sec, xtime.tv_sec, > + tick_nsec, time_freq, time_offset, time_next_adjust, > + xtime2.tv_sec, xtime2.tv_nsec, > + tick_nsec2, time_adj2, time_freq_adj2); > +} > > /* > * this routine handles the overflow of the microsecond field > @@ -739,6 +768,16 @@ static void second_overflow(void) > #endif > } > > +static void second_overflow2(void) > +{ > + time_adj2_cur = time_adj2; > + time_freq_phase2 += time_freq_adj2; > + if (time_freq_phase2 > HZ) { > + time_freq_phase2 -= HZ; > + time_adj2_cur++; > + } > +} > + > /* in the NTP reference this is called "hardclock()" */ > static void update_wall_time_one_tick(void) > { > @@ -786,6 +825,20 @@ static void update_wall_time_one_tick(vo > time_adjust = time_next_adjust; > time_next_adjust = 0; > } > + > + delta_nsec = tick_nsec2; > + time_phase2 += time_adj2_cur; > + if (time_phase2 >= (1 << (SHIFT_USEC + 2))) { > + long ltemp = time_phase2 >> (SHIFT_USEC + 2); > + time_phase2 -= ltemp << (SHIFT_USEC + 2); > + delta_nsec += ltemp; > + } > + xtime2.tv_nsec += delta_nsec; > + if (xtime2.tv_nsec >= NSEC_PER_SEC) { > + xtime2.tv_nsec -= NSEC_PER_SEC; > + xtime2.tv_sec++; > + second_overflow2(); > + } > } > > /* > - > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >
-- George Anzinger george@mvista.com HRT (High-res-timers): http://sourceforge.net/projects/high-res-timers/ - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |