--- src/sys/kern/kern_clock.c 2004/11/12 17:50:56 1.26 +++ src/sys/kern/kern_clock.c 2004/11/20 20:25:09 1.27 @@ -189,45 +189,22 @@ initclocks_pcpu(void) gd->gd_time_seconds = globaldata_find(0)->gd_time_seconds; gd->gd_cpuclock_base = globaldata_find(0)->gd_cpuclock_base; } - systimer_init_periodic(&gd->gd_hardclock, hardclock, NULL, hz); - systimer_init_periodic(&gd->gd_statclock, statclock, NULL, stathz); + + /* + * Use a non-queued periodic systimer to prevent multiple ticks from + * building up if the sysclock jumps forward (8254 gets reset). The + * sysclock will never jump backwards. Our time sync is based on + * the actual sysclock, not the ticks count. + */ + systimer_init_periodic_nq(&gd->gd_hardclock, hardclock, NULL, hz); + systimer_init_periodic_nq(&gd->gd_statclock, statclock, NULL, stathz); /* XXX correct the frequency for scheduler / estcpu tests */ - systimer_init_periodic(&gd->gd_schedclock, schedclock, + systimer_init_periodic_nq(&gd->gd_schedclock, schedclock, NULL, ESTCPUFREQ); crit_exit(); } /* - * Resynchronize gd_cpuclock_base after the system has been woken up from - * a sleep. It is absolutely essential that all the cpus be properly - * synchronized. Resynching is required because nanouptime() and friends - * will overflow intermediate multiplications if more then 2 seconds - * worth of cputimer_cont() delta has built up. - */ -#ifdef SMP - -static -void -restoreclocks_remote(lwkt_cpusync_t poll) -{ - mycpu->gd_cpuclock_base = *(sysclock_t *)poll->cs_data; - mycpu->gd_time_seconds = globaldata_find(0)->gd_time_seconds; -} - -#endif - -void -restoreclocks(void) -{ - sysclock_t base = cputimer_count(); -#ifdef SMP - lwkt_cpusync_simple(-1, restoreclocks_remote, &base); -#else - mycpu->gd_cpuclock_base = base; -#endif -} - -/* * This sets the current real time of day. Timespecs are in seconds and * nanoseconds. We do not mess with gd_time_seconds and gd_cpuclock_base, * instead we adjust basetime so basetime + gd_* results in the current