version 1.109, 2007/07/09 21:10:51 |
version 1.109.6.2, 2007/10/04 15:44:51 |
Line 292 long pps_stbcnt = 0; /* stability limit |
|
Line 292 long pps_stbcnt = 0; /* stability limit |
|
*/ |
*/ |
int clock_count = 0; /* CPU clock counter */ |
int clock_count = 0; /* CPU clock counter */ |
|
|
#ifdef HIGHBALL |
|
/* |
|
* The clock_offset and clock_cpu variables are used by the HIGHBALL |
|
* interface. The clock_offset variable defines the offset between |
|
* system time and the HIGBALL counters. The clock_cpu variable contains |
|
* the offset between the system clock and the HIGHBALL clock for use in |
|
* disciplining the kernel time variable. |
|
*/ |
|
extern struct timeval clock_offset; /* Highball clock offset */ |
|
long clock_cpu = 0; /* CPU clock adjust */ |
|
#endif /* HIGHBALL */ |
|
#endif /* EXT_CLOCK */ |
#endif /* EXT_CLOCK */ |
#endif /* NTP */ |
#endif /* NTP */ |
|
|
Line 591 hardclock(struct clockframe *frame) |
|
Line 580 hardclock(struct clockframe *frame) |
|
time_phase -= ltemp << SHIFT_SCALE; |
time_phase -= ltemp << SHIFT_SCALE; |
time_update += ltemp; |
time_update += ltemp; |
} |
} |
|
|
#ifdef HIGHBALL |
|
/* |
|
* If the HIGHBALL board is installed, we need to adjust the |
|
* external clock offset in order to close the hardware feedback |
|
* loop. This will adjust the external clock phase and frequency |
|
* in small amounts. The additional phase noise and frequency |
|
* wander this causes should be minimal. We also need to |
|
* discipline the kernel time variable, since the PLL is used to |
|
* discipline the external clock. If the Highball board is not |
|
* present, we discipline kernel time with the PLL as usual. We |
|
* assume that the external clock phase adjustment (time_update) |
|
* and kernel phase adjustment (clock_cpu) are less than the |
|
* value of tick. |
|
*/ |
|
clock_offset.tv_usec += time_update; |
|
if (clock_offset.tv_usec >= 1000000) { |
|
clock_offset.tv_sec++; |
|
clock_offset.tv_usec -= 1000000; |
|
} |
|
if (clock_offset.tv_usec < 0) { |
|
clock_offset.tv_sec--; |
|
clock_offset.tv_usec += 1000000; |
|
} |
|
time.tv_usec += clock_cpu; |
|
clock_cpu = 0; |
|
#else |
|
time.tv_usec += time_update; |
time.tv_usec += time_update; |
#endif /* HIGHBALL */ |
|
|
|
/* |
/* |
* On rollover of the second the phase adjustment to be used for |
* On rollover of the second the phase adjustment to be used for |
Line 850 hardclock(struct clockframe *frame) |
|
Line 811 hardclock(struct clockframe *frame) |
|
delta.tv_sec = 0; |
delta.tv_sec = 0; |
delta.tv_usec = 0; |
delta.tv_usec = 0; |
} |
} |
#ifdef HIGHBALL |
|
clock_cpu = delta.tv_usec; |
|
#else /* HIGHBALL */ |
|
hardupdate(delta.tv_usec); |
hardupdate(delta.tv_usec); |
#endif /* HIGHBALL */ |
|
} |
} |
#endif /* EXT_CLOCK */ |
#endif /* EXT_CLOCK */ |
} |
} |
Line 870 hardclock(struct clockframe *frame) |
|
Line 827 hardclock(struct clockframe *frame) |
|
callout_hardclock(); |
callout_hardclock(); |
} |
} |
|
|
#ifdef __HAVE_TIMECOUNTER |
|
/* |
|
* Compute number of hz until specified time. Used to compute second |
|
* argument to callout_reset() from an absolute time. |
|
*/ |
|
int |
|
hzto(struct timeval *tvp) |
|
{ |
|
struct timeval now, tv; |
|
|
|
tv = *tvp; /* Don't modify original tvp. */ |
|
getmicrotime(&now); |
|
timersub(&tv, &now, &tv); |
|
return tvtohz(&tv); |
|
} |
|
#endif /* __HAVE_TIMECOUNTER */ |
|
|
|
/* |
|
* Compute number of ticks in the specified amount of time. |
|
*/ |
|
int |
|
tvtohz(struct timeval *tv) |
|
{ |
|
unsigned long ticks; |
|
long sec, usec; |
|
|
|
/* |
|
* If the number of usecs in the whole seconds part of the time |
|
* difference fits in a long, then the total number of usecs will |
|
* fit in an unsigned long. Compute the total and convert it to |
|
* ticks, rounding up and adding 1 to allow for the current tick |
|
* to expire. Rounding also depends on unsigned long arithmetic |
|
* to avoid overflow. |
|
* |
|
* Otherwise, if the number of ticks in the whole seconds part of |
|
* the time difference fits in a long, then convert the parts to |
|
* ticks separately and add, using similar rounding methods and |
|
* overflow avoidance. This method would work in the previous |
|
* case, but it is slightly slower and assumes that hz is integral. |
|
* |
|
* Otherwise, round the time difference down to the maximum |
|
* representable value. |
|
* |
|
* If ints are 32-bit, then the maximum value for any timeout in |
|
* 10ms ticks is 248 days. |
|
*/ |
|
sec = tv->tv_sec; |
|
usec = tv->tv_usec; |
|
|
|
if (usec < 0) { |
|
sec--; |
|
usec += 1000000; |
|
} |
|
|
|
if (sec < 0 || (sec == 0 && usec <= 0)) { |
|
/* |
|
* Would expire now or in the past. Return 0 ticks. |
|
* This is different from the legacy hzto() interface, |
|
* and callers need to check for it. |
|
*/ |
|
ticks = 0; |
|
} else if (sec <= (LONG_MAX / 1000000)) |
|
ticks = (((sec * 1000000) + (unsigned long)usec + (tick - 1)) |
|
/ tick) + 1; |
|
else if (sec <= (LONG_MAX / hz)) |
|
ticks = (sec * hz) + |
|
(((unsigned long)usec + (tick - 1)) / tick) + 1; |
|
else |
|
ticks = LONG_MAX; |
|
|
|
if (ticks > INT_MAX) |
|
ticks = INT_MAX; |
|
|
|
return ((int)ticks); |
|
} |
|
|
|
#ifndef __HAVE_TIMECOUNTER |
|
/* |
|
* Compute number of hz until specified time. Used to compute second |
|
* argument to callout_reset() from an absolute time. |
|
*/ |
|
int |
|
hzto(struct timeval *tv) |
|
{ |
|
unsigned long ticks; |
|
long sec, usec; |
|
int s; |
|
|
|
/* |
|
* If the number of usecs in the whole seconds part of the time |
|
* difference fits in a long, then the total number of usecs will |
|
* fit in an unsigned long. Compute the total and convert it to |
|
* ticks, rounding up and adding 1 to allow for the current tick |
|
* to expire. Rounding also depends on unsigned long arithmetic |
|
* to avoid overflow. |
|
* |
|
* Otherwise, if the number of ticks in the whole seconds part of |
|
* the time difference fits in a long, then convert the parts to |
|
* ticks separately and add, using similar rounding methods and |
|
* overflow avoidance. This method would work in the previous |
|
* case, but it is slightly slower and assume that hz is integral. |
|
* |
|
* Otherwise, round the time difference down to the maximum |
|
* representable value. |
|
* |
|
* If ints are 32-bit, then the maximum value for any timeout in |
|
* 10ms ticks is 248 days. |
|
*/ |
|
s = splclock(); |
|
sec = tv->tv_sec - time.tv_sec; |
|
usec = tv->tv_usec - time.tv_usec; |
|
splx(s); |
|
|
|
if (usec < 0) { |
|
sec--; |
|
usec += 1000000; |
|
} |
|
|
|
if (sec < 0 || (sec == 0 && usec <= 0)) { |
|
/* |
|
* Would expire now or in the past. Return 0 ticks. |
|
* This is different from the legacy hzto() interface, |
|
* and callers need to check for it. |
|
*/ |
|
ticks = 0; |
|
} else if (sec <= (LONG_MAX / 1000000)) |
|
ticks = (((sec * 1000000) + (unsigned long)usec + (tick - 1)) |
|
/ tick) + 1; |
|
else if (sec <= (LONG_MAX / hz)) |
|
ticks = (sec * hz) + |
|
(((unsigned long)usec + (tick - 1)) / tick) + 1; |
|
else |
|
ticks = LONG_MAX; |
|
|
|
if (ticks > INT_MAX) |
|
ticks = INT_MAX; |
|
|
|
return ((int)ticks); |
|
} |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
|
|
/* |
|
* Compute number of ticks in the specified amount of time. |
|
*/ |
|
int |
|
tstohz(struct timespec *ts) |
|
{ |
|
struct timeval tv; |
|
|
|
/* |
|
* usec has great enough resolution for hz, so convert to a |
|
* timeval and use tvtohz() above. |
|
*/ |
|
TIMESPEC_TO_TIMEVAL(&tv, ts); |
|
return tvtohz(&tv); |
|
} |
|
|
|
/* |
/* |
* Start profiling on a process. |
* Start profiling on a process. |
* |
* |
Line 1104 proftick(struct clockframe *frame) |
|
Line 904 proftick(struct clockframe *frame) |
|
} |
} |
} |
} |
#endif |
#endif |
#ifdef PROC_PC |
#ifdef LWP_PC |
if (p != NULL) { |
if (p != NULL && (p->p_stflag & PST_PROFIL) != 0) |
mutex_spin_enter(&p->p_stmutex); |
addupc_intr(l, LWP_PC(l)); |
if (p->p_stflag & PST_PROFIL)) |
|
addupc_intr(l, PROC_PC(p)); |
|
mutex_spin_exit(&p->p_stmutex); |
|
} |
|
#endif |
#endif |
} |
} |
} |
} |