Index: sys/kern/kern_clock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_clock.c,v retrieving revision 1.83 diff -u -r1.83 kern_clock.c --- kern_clock.c 1998/10/26 06:13:18 1.83 +++ kern_clock.c 1998/11/06 07:09:50 @@ -74,6 +74,8 @@ #define NTIMECOUNTER 2 #endif +#define TIMECOUNTER_DIAGNOSTIC 1 + static MALLOC_DEFINE(M_TIMECOUNTER, "timecounter", "Timecounter stable storage"); @@ -491,6 +493,34 @@ SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD, 0, 0, sysctl_kern_clockrate, "S,clockinfo",""); +#ifdef TIMECOUNTER_DIAGNOSTIC +#define TC_DIAG_BUFFER_SIZE 8 +#define TC_DIAG_BUFFER_MASK ((1 << TC_DIAG_BUFFER_SIZE) - 1) + +unsigned tc_diag_buffer[1 << TC_DIAG_BUFFER_SIZE]; +int tc_diag_index, tc_diag_stop; +int tc_diag_index, tc_diag_stop, tc_diag_maxforward; + +SYSCTL_OPAQUE(_debug, OID_AUTO, tc_diag_buffer, CTLFLAG_RD, + tc_diag_buffer, sizeof tc_diag_buffer, "I", ""); + +SYSCTL_INT(_debug, OID_AUTO, tc_diag_index, CTLFLAG_RD, &tc_diag_index, 0, ""); +SYSCTL_INT(_debug, OID_AUTO, tc_diag_stop, CTLFLAG_RW, &tc_diag_stop, 0, ""); +SYSCTL_INT(_debug, OID_AUTO, tc_diag_maxforward, CTLFLAG_RW, &tc_diag_maxforward, 0, ""); + +static __inline unsigned +tco_delta(struct timecounter *tc) +{ + unsigned u; + + u = ((tc->tc_get_timecount(tc) - tc->tc_offset_count) & + tc->tc_counter_mask); + if (!tc_diag_stop) + tc_diag_buffer[tc_diag_index++ & TC_DIAG_BUFFER_MASK] = u; + return (u); +} + +#else /* !TIMECOUNTER_DIAGNOSTIC */ static __inline unsigned tco_delta(struct timecounter *tc) { @@ -498,6 +528,7 @@ return ((tc->tc_get_timecount(tc) - tc->tc_offset_count) & tc->tc_counter_mask); } +#endif /* * We have four functions for looking at the clock, two for microseconds @@ -540,6 +571,17 @@ tv->tv_usec -= 1000000; tv->tv_sec++; } +#ifdef TIMECOUNTER_DIAGNOSTIC + if (tv->tv_usec < 0) { + printf("Negative tv_usec (%ld.%06ld) in microtime.", + tv->tv_sec, tv->tv_usec); + printf("Ref: %d.%06d. Boot: %ld.%06ld.\n", + tc->tc_offset_sec, tc->tc_offset_micro, + boottime.tv_sec, boottime.tv_usec); + tc_diag_stop = 1; + } +#endif + } void @@ -563,6 +605,16 @@ ts->tv_sec++; } ts->tv_nsec = delta; +#ifdef TIMECOUNTER_DIAGNOSTIC + if (ts->tv_nsec < 0) { + printf("Negative tv_nsec (%ld.%09ld) in nanotime.", + ts->tv_sec, ts->tv_nsec); + printf("Ref: %d.%09lu. Boot: %ld.%06ld.\n", + tc->tc_offset_sec, (u_long)(tc->tc_offset_nano >> 32), + boottime.tv_sec, boottime.tv_usec); + tc_diag_stop = 1; + } +#endif } void @@ -621,17 +673,26 @@ tv->tv_usec -= 1000000; tv->tv_sec++; } +#ifdef TIMECOUNTER_DIAGNOSTIC + if (tv->tv_usec < 0) { + printf("Negative tv_usec (%ld.%06ld) in microuptime.", + tv->tv_sec, tv->tv_usec); + printf("Ref: %d.%06d\n", + tc->tc_offset_sec, tc->tc_offset_micro); + tc_diag_stop = 1; + } +#endif } void -nanouptime(struct timespec *tv) +nanouptime(struct timespec *ts) { unsigned count; u_int64_t delta; struct timecounter *tc; tc = (struct timecounter *)timecounter; - tv->tv_sec = tc->tc_offset_sec; + ts->tv_sec = tc->tc_offset_sec; count = tco_delta(tc); delta = tc->tc_offset_nano; delta += ((u_int64_t)count * tc->tc_scale_nano_f); @@ -639,9 +700,18 @@ delta += ((u_int64_t)count * tc->tc_scale_nano_i); if (delta >= 1000000000) { delta -= 1000000000; - tv->tv_sec++; + ts->tv_sec++; + } + ts->tv_nsec = delta; +#ifdef TIMECOUNTER_DIAGNOSTIC + if (ts->tv_nsec < 0) { + printf("Negative tv_nsec (%ld.%09ld) in nanouptime.", + ts->tv_sec, ts->tv_nsec); + printf("Ref: %d.%09ld\n", + tc->tc_offset_sec, (u_long)(tc->tc_offset_nano >> 32)); + tc_diag_stop = 1; } - tv->tv_nsec = delta; +#endif } static void @@ -749,6 +819,15 @@ *tc = *tco; tc->tc_other = tcn; delta = tco_delta(tc); +#ifdef TIMECOUNTER_DIAGNOSTIC + if (delta > tc_diag_maxforward) + tc_diag_maxforward = delta; + if (delta & (~tc->tc_counter_mask)) { + printf("Extra bits in delta in sync_other_counter %x %x\n", + delta, tc->tc_counter_mask); + tc_diag_stop = 1; + } +#endif tc->tc_offset_count += delta; tc->tc_offset_count &= tc->tc_counter_mask; tc->tc_offset_nano += (u_int64_t)delta * tc->tc_scale_nano_f; @@ -760,6 +839,14 @@ tco_forward(void) { struct timecounter *tc, *tco; +#ifdef TIMECOUNTER_DIAGNOSTIC + static int recurse; + + if (recurse++) { + printf("tco_forward recursing\n"); + tc_diag_stop = 1; + } +#endif tco = timecounter; tc = sync_other_counter(); @@ -775,6 +862,15 @@ if (tco->tc_poll_pps) tco->tc_poll_pps(tco); if (timedelta != 0) { +#ifdef TIMECOUNTER_DIAGNOSTIC + if (tickdelta < 0 && + tc->tc_offset_nano < + -((u_int64_t)(tickdelta * 1000) << 32)) { + printf("-tickdelta tco_forward() tickdelta %d", + tickdelta); + tc_diag_stop = 1; + } +#endif tc->tc_offset_nano += (u_int64_t)(tickdelta * 1000) << 32; timedelta -= tickdelta; } @@ -789,6 +885,13 @@ } tc->tc_offset_micro = (tc->tc_offset_nano / 1000) >> 32; +#ifdef TIMECOUNTER_DIAGNOSTIC + if (tc->tc_offset_micro < 0) { + printf("Negative tc_offset_micro (%d.%09d) in tco_forward.", + tc->tc_offset_sec, tc->tc_offset_micro); + tc_diag_stop = 1; + } +#endif /* Figure out the wall-clock time */ tc->tc_nanotime.tv_sec = tc->tc_offset_sec + boottime.tv_sec; @@ -800,9 +903,24 @@ tc->tc_microtime.tv_usec -= 1000000; tc->tc_nanotime.tv_sec++; } +#ifdef TIMECOUNTER_DIAGNOSTIC + if (tc->tc_microtime.tv_usec < 0 || tc->tc_microtime.tv_usec > 999999) { + printf("tc_microtime.tv_nsec (%ld.%06ld) in tco_forward.", + tc->tc_microtime.tv_sec, tc->tc_microtime.tv_usec); + tc_diag_stop = 1; + } + if (tc->tc_nanotime.tv_nsec < 0 || tc->tc_nanotime.tv_nsec > 999999999) { + printf("tc_nanotime.tv_nsec (%ld.%09ld) in tco_forward.", + tc->tc_nanotime.tv_sec, tc->tc_nanotime.tv_nsec); + tc_diag_stop = 1; + } +#endif time_second = tc->tc_microtime.tv_sec = tc->tc_nanotime.tv_sec; timecounter = tc; +#ifdef TIMECOUNTER_DIAGNOSTIC + recurse--; +#endif } static int Index: usr.sbin/sysctl/sysctl.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/sysctl/sysctl.c,v retrieving revision 1.18 diff -u -r1.18 sysctl.c --- sysctl.c 1998/08/25 07:38:19 1.18 +++ sysctl.c 1998/11/05 16:34:56 @@ -389,7 +389,13 @@ case 'I': if (!nflag) printf("%s: ", name); - printf("%d", *(int *)p); + val = ""; + while (len >= sizeof(int)) { + printf("%s%d", val, *(int *)p); + val = " "; + len -= sizeof (int); + p += sizeof (int); + } return (0); case 'L': Index: sys/alpha/alpha/clock.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/clock.c,v retrieving revision 1.4 diff -u -r1.4 clock.c --- clock.c 1998/10/06 08:40:18 1.4 +++ clock.c 1998/11/05 19:21:01 @@ -77,7 +77,7 @@ static timecounter_get_t alpha_get_timecount; static timecounter_pps_t alpha_poll_pps; -static struct timecounter alpha_timecounter[3] = { +static struct timecounter alpha_timecounter = { alpha_get_timecount, /* get_timecount */ 0, /* no poll_pps */ ~0u, /* counter_mask */ @@ -86,7 +86,7 @@ }; SYSCTL_OPAQUE(_debug, OID_AUTO, alpha_timecounter, CTLFLAG_RD, - alpha_timecounter, sizeof(alpha_timecounter), "S,timecounter", ""); + &alpha_timecounter, sizeof(alpha_timecounter), "S,timecounter", ""); /* Values for timerX_state: */ #define RELEASED 0 @@ -178,8 +178,8 @@ scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / cycles_per_sec; max_cycles_per_tick = 2*cycles_per_sec / hz; - alpha_timecounter[0].tc_frequency = cycles_per_sec; - init_timecounter(alpha_timecounter); + alpha_timecounter.tc_frequency = cycles_per_sec; + init_timecounter(&alpha_timecounter); platform.clockintr = (void (*) __P((void *))) handleclock;