From: Kenn H. <ke...@us...> - 2003-02-16 02:10:07
|
Update of /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel In directory sc8-pr-cvs1:/tmp/cvs-serv11034 Modified Files: time.c Log Message: 2.5.35 has nanosecond-resolution in the internal time-of-day clock Index: time.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel/time.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- time.c 9 Feb 2003 01:32:36 -0000 1.7 +++ time.c 16 Feb 2003 02:10:03 -0000 1.8 @@ -32,6 +32,10 @@ spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; extern rwlock_t xtime_lock; +extern unsigned long wall_jiffies; /* kernel/timer.c */ + +#define TICK_SIZE (tick_nsec / 1000) + /* last time the cmos clock got updated */ static long last_rtc_update; @@ -50,7 +54,7 @@ mv->clock_init(); /* read cmos time */ - xtime.tv_usec = 0; + xtime.tv_nsec = 0; xtime.tv_sec = get_cmos_time(); if (request_irq(0x30, do_timer_interrupt, 0, "timer", NULL)) { @@ -164,8 +168,8 @@ */ if ((time_status & STA_UNSYNC) == 0 && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 && - xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) { + (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && + (xtime.tv_nsec / 1000 ) <= 500000 + ((unsigned) TICK_SIZE) / 2) { if (set_rtc_mmss(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else @@ -209,46 +213,53 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long usec, sec; read_lock_irqsave(&xtime_lock, flags); - *tv = xtime; - tv->tv_usec += do_gettimeoffset(); - - spin_unlock_irqrestore(&xtime_lock, flags); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; + usec += (xtime.tv_nsec / 1000); + read_unlock_irqrestore(&xtime_lock, flags); + + while (usec >= 1000000) { + usec -= 1000000; + sec++; } + + tv->tv_sec = sec; + tv->tv_usec = usec; } void do_settimeofday(struct timeval *tv) { - unsigned long flags; - - write_lock_irqsave(&xtime_lock, flags); - /* This is revolting. We need to set the xtime.tv_usec - * correctly. However, the value in this location is - * is value at the last tick. - * Discover what correction gettimeofday - * would have done, and then undo it! + write_lock_irq(&xtime_lock); + /* + * This is revolting. We need to set "xtime" correctly. However, the + * value in this location is the value at the most recent update of + * wall time. Discover what correction gettimeofday() would have + * made, and then undo it! */ tv->tv_usec -= do_gettimeoffset(); + tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ); - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } - xtime = *tv; - time_adjust = 0; /* stop active adjtime() */ + xtime.tv_sec = tv->tv_sec; + xtime.tv_nsec = (tv->tv_usec * 1000); + time_adjust = 0; /* stop active adjtime() */ time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - xtime = *tv; - - spin_unlock_irqrestore(&xtime_lock, flags); + write_unlock_irq(&xtime_lock); } /* nicked from the i386 port, but we use the same chip, hee hee */ |