patch-2.2.7 linux/arch/alpha/kernel/time.c
Next file: linux/arch/alpha/lib/clear_user.S
Previous file: linux/arch/alpha/kernel/setup.c
Back to the patch index
Back to the overall index
- Lines: 86
- Date:
Sat Apr 24 17:54:08 1999
- Orig file:
v2.2.6/linux/arch/alpha/kernel/time.c
- Orig date:
Tue Mar 23 14:35:46 1999
diff -u --recursive --new-file v2.2.6/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
@@ -18,6 +18,9 @@
* fixed tick loss calculation in timer_interrupt
* (round system clock to nearest tick instead of truncating)
* fixed algorithm in time_init for getting time from CMOS clock
+ * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net)
+ * fixed algorithm in do_gettimeofday() for calculating the precise time
+ * from processor cycle counter (now taking lost_ticks into account)
*/
#include <linux/config.h>
#include <linux/errno.h>
@@ -223,7 +226,7 @@
{
void (*irq_handler)(int, void *, struct pt_regs *);
unsigned int year, mon, day, hour, min, sec, cc1, cc2;
- unsigned long cycle_freq;
+ unsigned long cycle_freq, diff, one_percent;
/*
* The Linux interpretation of the CMOS clock register contents:
@@ -237,19 +240,30 @@
/* Read cycle counter exactly on falling edge of update flag */
cc1 = rpcc();
- /* If our cycle frequency isn't valid, go another round and give
- a guess at what it should be. */
- cycle_freq = hwrpb->cycle_freq;
- if (cycle_freq == 0) {
- printk("HWRPB cycle frequency bogus. Estimating... ");
-
+ if (!est_cycle_freq) {
+ /* Sometimes the hwrpb->cycle_freq value is bogus.
+ Go another round to check up on it and see. */
do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP));
do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
cc2 = rpcc();
- est_cycle_freq = cycle_freq = cc2 - cc1;
+ est_cycle_freq = cc2 - cc1;
cc1 = cc2;
+ }
- printk("%lu Hz\n", cycle_freq);
+ /* If the given value is within 1% of what we calculated,
+ accept it. Otherwise, use what we found. */
+ cycle_freq = hwrpb->cycle_freq;
+ one_percent = cycle_freq / 100;
+ diff = cycle_freq - est_cycle_freq;
+ if (diff < 0)
+ diff = -diff;
+ if (diff > one_percent) {
+ cycle_freq = est_cycle_freq;
+ printk("HWRPB cycle frequency bogus. Estimated %lu Hz\n",
+ cycle_freq);
+ }
+ else {
+ est_cycle_freq = 0;
}
/* From John Bowman <bowman@math.ualberta.ca>: allow the values
@@ -314,8 +328,10 @@
void
do_gettimeofday(struct timeval *tv)
{
- unsigned long flags, now, delta_cycles, delta_usec;
+ unsigned long flags, delta_cycles, delta_usec;
unsigned long sec, usec;
+ __u32 now;
+ extern volatile unsigned long lost_ticks; /*kernel/sched.c*/
now = rpcc();
save_and_cli(flags);
@@ -337,8 +353,14 @@
* with no clear gain.
*/
- delta_usec = delta_cycles * state.scaled_ticks_per_cycle * 15625;
+ delta_usec = (delta_cycles * state.scaled_ticks_per_cycle
+ + state.partial_tick
+ + (lost_ticks << FIX_SHIFT) ) * 15625;
delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2;
+
+ /* the 'lost_tics' term above implements this:
+ * delta_usec += lost_ticks * (1000000 / HZ);
+ */
usec += delta_usec;
if (usec >= 1000000) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)