From owner-freebsd-current Sat Apr 4 00:05:46 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id AAA14234 for freebsd-current-outgoing; Sat, 4 Apr 1998 00:05:46 -0800 (PST) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from critter.freebsd.dk (critter.freebsd.dk [195.8.129.14]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id AAA14220 for ; Sat, 4 Apr 1998 00:05:31 -0800 (PST) (envelope-from phk@critter.freebsd.dk) Received: from critter.freebsd.dk (localhost [127.0.0.1]) by critter.freebsd.dk (8.8.7/8.8.5) with ESMTP id KAA04700; Sat, 4 Apr 1998 10:04:41 +0200 (CEST) To: Alex cc: current Subject: Re: Working patch *with* splhigh() (Was Re: More info RE: X slowdown in -current) In-reply-to: Your message of "Fri, 03 Apr 1998 18:22:45 -0800." Date: Sat, 04 Apr 1998 10:04:41 +0200 Message-ID: <4698.891677081@critter.freebsd.dk> From: Poul-Henning Kamp Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Ok, I have spent too much of the night already on this, lets take another attack, can you try out this kernel patch: Poul-Henning Index: i386/i386/exception.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/exception.s,v retrieving revision 1.48 diff -u -r1.48 exception.s --- exception.s 1998/03/23 19:52:23 1.48 +++ exception.s 1998/04/02 16:15:36 @@ -343,8 +343,10 @@ ENTRY(fork_trampoline) call _spl0 - pushl $_runtime - call _microtime + movl _curproc,%eax + addl $P_RUNTIME,%eax + pushl %eax + call _getmicroruntime popl %eax /* Index: i386/i386/genassym.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/genassym.c,v retrieving revision 1.51 diff -u -r1.51 genassym.c --- genassym.c 1998/02/01 18:53:09 1.51 +++ genassym.c 1998/04/02 16:07:20 @@ -95,6 +95,7 @@ printf("#define\tP_WCHAN %p\n", &p->p_wchan); printf("#define\tP_FLAG %p\n", &p->p_flag); printf("#define\tP_PID %p\n", &p->p_pid); + printf("#define\tP_RUNTIME %p\n", &p->p_runtime); #ifdef SMP printf("#define\tP_ONCPU %p\n", &p->p_oncpu); printf("#define\tP_LASTCPU %p\n", &p->p_lastcpu); Index: i386/i386/locore.s =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/locore.s,v retrieving revision 1.105 diff -u -r1.105 locore.s --- locore.s 1998/03/23 19:52:27 1.105 +++ locore.s 1998/04/01 06:10:23 @@ -105,7 +105,7 @@ .set _prv_CPAGE3,_SMP_prvstart + ((5 + UPAGES) * PAGE_SIZE) .set _SMP_ioapic,_SMP_prvstart + (16 * PAGE_SIZE) - .globl _cpuid,_curproc,_curpcb,_npxproc,_runtime,_cpu_lockid + .globl _cpuid,_curproc,_curpcb,_npxproc,_cpu_lockid .globl _common_tss,_other_cpus,_my_idlePTD,_ss_tpr .globl _prv_CMAP1,_prv_CMAP2,_prv_CMAP3 .globl _inside_intr @@ -113,7 +113,7 @@ .set _curproc,_SMP_prvpage+4 /* [1] */ .set _curpcb,_SMP_prvpage+8 /* [2] */ .set _npxproc,_SMP_prvpage+12 /* [3] */ - .set _runtime,_SMP_prvpage+16 /* [4,5] */ + /* [4,5] was runtime, free */ .set _cpu_lockid,_SMP_prvpage+24 /* [6] */ .set _other_cpus,_SMP_prvpage+28 /* [7] bitmap of available CPUs, excluding ourself */ Index: i386/include/asnames.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/asnames.h,v retrieving revision 1.17 diff -u -r1.17 asnames.h --- asnames.h 1998/03/04 09:55:13 1.17 +++ asnames.h 1998/04/01 06:10:23 @@ -316,7 +316,6 @@ #define _rel_mplock rel_mplock #define _round_reg round_reg #define _rtqs rtqs -#define _runtime runtime #define _s_lock s_lock #define _s_unlock s_unlock #define _secondary_main secondary_main Index: i386/isa/syscons.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/syscons.c,v retrieving revision 1.256 diff -u -r1.256 syscons.c --- syscons.c 1998/02/13 17:54:53 1.256 +++ syscons.c 1998/04/01 06:10:23 @@ -158,7 +158,7 @@ static int delayed_next_scr = FALSE; static long scrn_blank_time = 0; /* screen saver timeout value */ int scrn_blanked = 0; /* screen saver active flag */ -static long scrn_time_stamp; +static struct timeval scrn_time_stamp; u_char scr_map[256]; u_char scr_rmap[256]; char *video_mode_ptr = NULL; @@ -1030,7 +1030,7 @@ return EINVAL; scrn_blank_time = *(int *)data; if (scrn_blank_time == 0) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; case CONS_CURSORTYPE: /* set cursor type blink/noblink */ @@ -1385,7 +1385,7 @@ return EINVAL; } /* make screensaver happy */ - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); return 0; } @@ -2228,6 +2228,7 @@ static void scrn_timer(void *arg) { + struct timeval tv; scr_stat *scp = cur_console; int s; @@ -2269,9 +2270,10 @@ } /* should we stop the screen saver? */ + getmicroruntime(&tv); if (panicstr) - scrn_time_stamp = mono_time.tv_sec; - if (mono_time.tv_sec <= scrn_time_stamp + scrn_blank_time) + scrn_time_stamp = tv; + if (tv.tv_sec <= scrn_time_stamp.tv_sec + scrn_blank_time) if (scrn_blanked > 0) stop_scrn_saver(current_saver); scp = cur_console; @@ -2279,7 +2281,7 @@ scrn_update(scp, TRUE); /* should we activate the screen saver? */ if ((scrn_blank_time != 0) - && (mono_time.tv_sec > scrn_time_stamp + scrn_blank_time)) + && (tv.tv_sec > scrn_time_stamp.tv_sec + scrn_blank_time)) (*current_saver)(TRUE); timeout(scrn_timer, NULL, hz / 25); @@ -2387,7 +2389,7 @@ stop_scrn_saver(void (*saver)(int)) { (*saver)(FALSE); - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); mark_all(cur_console); } @@ -3038,7 +3040,7 @@ /* make screensaver happy */ if (scp == cur_console) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); write_in_progress++; outloop: @@ -3488,7 +3490,7 @@ /* make screensaver happy */ if (!(scancode & 0x80)) - scrn_time_stamp = mono_time.tv_sec; + getmicroruntime(&scrn_time_stamp); if (!(flags & SCGETC_CN)) { /* do the /dev/random device a favour */ Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.85 diff -u -r1.85 init_main.c --- init_main.c 1998/03/30 09:49:52 1.85 +++ init_main.c 1998/04/02 16:54:11 @@ -104,10 +104,6 @@ SYSCTL_INT(_kern, OID_AUTO, shutdown_timeout, CTLFLAG_RW, &shutdowntimeout, 0, ""); -#ifndef SMP /* per-cpu on smp */ -struct timeval runtime; -#endif - /* * Promiscuous argument pass for start_init() * @@ -441,21 +437,21 @@ void *dummy; { struct timeval tv; + struct timespec ts; /* * Now can look at time, having had a chance to verify the time * from the file system. Reset p->p_rtime as it may have been * munched in mi_switch() after the time got set. */ - getmicrotime(&boottime); - proc0.p_stats->p_start = runtime = mono_time = boottime; + proc0.p_stats->p_start = boottime; proc0.p_rtime.tv_sec = proc0.p_rtime.tv_usec = 0; /* * Give the ``random'' number generator a thump. */ - microtime(&tv); - srandom(tv.tv_sec ^ tv.tv_usec); + nanotime(&ts); + srandom(ts.tv_sec ^ ts.tv_nsec); /* Initialize signal state for process 0. */ siginit(&proc0); Index: kern/kern_clock.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_clock.c,v retrieving revision 1.62 diff -u -r1.62 kern_clock.c --- kern_clock.c 1998/03/31 10:47:01 1.62 +++ kern_clock.c 1998/04/02 17:03:15 @@ -138,8 +138,6 @@ static int psdiv, pscnt; /* prof => stat divider */ int psratio; /* ratio: prof / stat */ -volatile struct timeval mono_time; - /* * Initialize clock frequencies and start both clocks running. */ @@ -232,7 +230,6 @@ { register unsigned long ticks; register long sec, usec; - int s; /* * If the number of usecs in the whole seconds part of the time @@ -292,7 +289,6 @@ hzto(tv) struct timeval *tv; { - register long sec, usec; struct timeval t2; getmicrotime(&t2); @@ -512,12 +508,71 @@ struct timecounter *tc; tc = timecounter; + *tvp = tc->microtime; +} + +void +getnanotime(struct timespec *tsp) +{ + struct timecounter *tc; + + tc = timecounter; + *tsp = tc->nanotime; +} + +void +microtime(struct timeval *tv) +{ + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + tv->tv_usec = tc->offset_micro; + tv->tv_usec += + ((u_int64_t)tc->get_timedelta(tc) * tc->scale_micro) >> 32; + tv->tv_usec += boottime.tv_usec; + tv->tv_sec += boottime.tv_sec; + if (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } +} + +void +nanotime(struct timespec *tv) +{ + u_int count; + u_int64_t delta; + struct timecounter *tc; + + tc = (struct timecounter *)timecounter; + tv->tv_sec = tc->offset_sec; + count = tc->get_timedelta(tc); + delta = tc->offset_nano; + delta += ((u_int64_t)count * tc->scale_nano_f); + delta >>= 32; + delta += ((u_int64_t)count * tc->scale_nano_i); + delta += boottime.tv_usec * 1000; + tv->tv_sec += boottime.tv_sec; + if (delta >= 1000000000) { + delta -= 1000000000; + tv->tv_sec++; + } + tv->tv_nsec = delta; +} + +void +getmicroruntime(struct timeval *tvp) +{ + struct timecounter *tc; + + tc = timecounter; tvp->tv_sec = tc->offset_sec; tvp->tv_usec = tc->offset_micro; } void -getnanotime(struct timespec *tsp) +getnanoruntime(struct timespec *tsp) { struct timecounter *tc; @@ -527,7 +582,7 @@ } void -microtime(struct timeval *tv) +microruntime(struct timeval *tv) { struct timecounter *tc; @@ -543,7 +598,7 @@ } void -nanotime(struct timespec *tv) +nanoruntime(struct timespec *tv) { u_int count; u_int64_t delta; @@ -601,7 +656,7 @@ tc[2] = tc[1] = tc[0]; tc[1].other = &tc[2]; tc[2].other = &tc[1]; - if (!timecounter) + if (!timecounter || !strcmp(timecounter->name, "dummy")) timecounter = &tc[2]; tc = &tc[1]; @@ -634,27 +689,21 @@ void set_timecounter(struct timespec *ts) { - struct timecounter *tc, *tco; - int s; + struct timespec ts2; - /* - * XXX we must be called at splclock() to preven *ts becoming - * invalid, so there is no point in spls here. - */ - s = splclock(); - tc = timecounter->other; - tco = tc->other; - *tc = *timecounter; - tc->other = tco; - tc->offset_sec = ts->tv_sec; - tc->offset_nano = (u_int64_t)ts->tv_nsec << 32; - tc->offset_micro = ts->tv_nsec / 1000; - tc->offset_count = tc->get_timecount(); - time_second = tc->offset_sec; - timecounter = tc; - splx(s); + nanoruntime(&ts2); + boottime.tv_sec = ts->tv_sec - ts2.tv_sec; + boottime.tv_usec = (ts->tv_nsec - ts2.tv_nsec) / 1000; + if (boottime.tv_usec < 0) { + boottime.tv_usec += 1000000; + boottime.tv_sec--; + } + /* fiddle all the little crinkly bits around the fiords... */ + tco_forward(); } + +#if 0 /* Currently unused */ void switch_timecounter(struct timecounter *newtc) { @@ -676,6 +725,7 @@ timecounter = newtc; splx(s); } +#endif static struct timecounter * sync_other_counter(void) @@ -703,14 +753,8 @@ tc = sync_other_counter(); if (timedelta != 0) { tc->offset_nano += (u_int64_t)(tickdelta * 1000) << 32; - mono_time.tv_usec += tickdelta; timedelta -= tickdelta; } - mono_time.tv_usec += tick; - if (mono_time.tv_usec >= 1000000) { - mono_time.tv_usec -= 1000000; - mono_time.tv_sec++; - } if (tc->offset_nano >= 1000000000ULL << 32) { tc->offset_nano -= 1000000000ULL << 32; @@ -723,7 +767,17 @@ tc->offset_micro = (tc->offset_nano / 1000) >> 32; - time_second = tc->offset_sec; + /* Figure out the wall-clock time */ + tc->nanotime.tv_sec = tc->offset_sec + boottime.tv_sec; + tc->nanotime.tv_nsec = (tc->offset_nano >> 32) + boottime.tv_usec * 1000; + tc->microtime.tv_usec = tc->offset_micro + boottime.tv_usec; + if (tc->nanotime.tv_nsec > 1000000000) { + tc->nanotime.tv_nsec -= 1000000000; + tc->microtime.tv_usec -= 1000000; + tc->nanotime.tv_sec++; + } + time_second = tc->microtime.tv_sec = tc->nanotime.tv_sec; + timecounter = tc; } @@ -775,8 +829,7 @@ }; static void -initdummytimecounter(dummy) - void *dummy; +initdummytimecounter(void *dummy) { init_timecounter(dummy_timecounter); } Index: kern/kern_resource.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v retrieving revision 1.33 diff -u -r1.33 kern_resource.c --- kern_resource.c 1998/03/04 10:25:52 1.33 +++ kern_resource.c 1998/04/02 16:52:09 @@ -491,6 +491,7 @@ int s; struct timeval tv; + /* XXX: why spl-protect ? worst case is an off-by-one report */ s = splstatclock(); st = p->p_sticks; ut = p->p_uticks; @@ -505,23 +506,25 @@ sec = p->p_rtime.tv_sec; usec = p->p_rtime.tv_usec; - if (p == curproc) { /* XXX what if it's running on another cpu?? */ +#ifdef SMP + if (p->p_oncpu != 0xff) { +#else + if (p == curproc) { +#endif /* * Adjust for the current time slice. This is actually fairly * important since the error here is on the order of a time * quantum, which is much greater than the sampling error. */ - microtime(&tv); - sec += tv.tv_sec - runtime.tv_sec; - usec += tv.tv_usec - runtime.tv_usec; + microruntime(&tv); + sec += tv.tv_sec - p->p_runtime.tv_sec; + usec += tv.tv_usec - p->p_runtime.tv_usec; } totusec = (quad_t)sec * 1000000 + usec; if (totusec < 0) { -#ifndef SMP /* sigh, microtime and fork/exit madness here */ /* XXX no %qd in kernel. Truncate. */ printf("calcru: negative time of %ld usec for pid %d (%s)\n", (long)totusec, p->p_pid, p->p_comm); -#endif totusec = 0; } u = totusec; Index: kern/kern_synch.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v retrieving revision 1.53 diff -u -r1.53 kern_synch.c --- kern_synch.c 1998/03/28 18:16:29 1.53 +++ kern_synch.c 1998/04/01 06:10:24 @@ -621,9 +621,9 @@ * Compute the amount of time during which the current * process was running, and add that to its total so far. */ - microtime(&tv); - u = p->p_rtime.tv_usec + (tv.tv_usec - runtime.tv_usec); - s = p->p_rtime.tv_sec + (tv.tv_sec - runtime.tv_sec); + microruntime(&tv); + u = p->p_rtime.tv_usec + (tv.tv_usec - p->p_runtime.tv_usec); + s = p->p_rtime.tv_sec + (tv.tv_sec - p->p_runtime.tv_sec); if (u < 0) { u += 1000000; s--; @@ -660,7 +660,7 @@ */ cnt.v_swtch++; cpu_switch(p); - microtime(&runtime); + microruntime(&p->p_runtime); splx(x); } Index: kern/kern_time.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_time.c,v retrieving revision 1.44 diff -u -r1.44 kern_time.c --- kern_time.c 1998/03/30 09:50:23 1.44 +++ kern_time.c 1998/04/02 16:56:13 @@ -84,9 +84,8 @@ s = splclock(); microtime(&tv1); - delta.tv_sec = tv->tv_sec - tv1.tv_sec; - delta.tv_usec = tv->tv_usec - tv1.tv_usec; - timevalfix(&delta); + delta = *tv; + timevalsub(&delta, &tv1); /* * If the system is secure, we do not allow the time to be @@ -103,13 +102,9 @@ ts.tv_nsec = tv->tv_usec * 1000; set_timecounter(&ts); (void) splsoftclock(); - timevaladd(&boottime, &delta); - timevaladd(&runtime, &delta); for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { if (timerisset(&p->p_realtimer.it_value)) timevaladd(&p->p_realtimer.it_value, &delta); - if (p->p_sleepend) - timevaladd(p->p_sleepend, &delta); } lease_updatetime(delta.tv_sec); splx(s); @@ -203,69 +198,44 @@ struct proc *p; struct timespec *rqt, *rmt; { - struct timeval atv, utv, rtv; - int error, s, timo, i, n; + struct timespec ts, ts2; + int error, timo; if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) return (EINVAL); if (rqt->tv_sec < 0 || rqt->tv_sec == 0 && rqt->tv_nsec == 0) return (0); - TIMESPEC_TO_TIMEVAL(&atv, rqt) - if (itimerfix(&atv)) { - n = atv.tv_sec / 100000000; - rtv = atv; - rtv.tv_sec %= 100000000; - (void)itimerfix(&rtv); - } else - n = 0; - - for (i = 0, error = EWOULDBLOCK; i <= n && error == EWOULDBLOCK; i++) { - if (n > 0) { - if (i == n) - atv = rtv; - else { - atv.tv_sec = 100000000; - atv.tv_usec = 0; - } + getnanoruntime(&ts); + timespecadd(&ts, rqt); + error = 0; + while (1) { + getnanoruntime(&ts2); + if (timespeccmp(&ts2, &ts, >=)) + break; + else if (ts2.tv_sec + 60 * 60 * 24 * hz < ts.tv_sec) + timo = 60 * 60 * 24 * hz; + else if (ts2.tv_sec + 2 < ts.tv_sec) { + /* Leave one second for the difference in tv_nsec */ + timo = ts.tv_sec - ts2.tv_sec - 1; + timo *= hz; + } else { + timo = (ts.tv_sec - ts2.tv_sec) * 1000000000; + timo += ts.tv_nsec - ts2.tv_nsec; + timo /= (1000000000 / hz); + timo ++; } - timo = tvtohz(&atv); - - p->p_sleepend = &atv; error = tsleep(&nanowait, PWAIT | PCATCH, "nanslp", timo); - p->p_sleepend = NULL; - if (error == ERESTART) + if (error == ERESTART) { error = EINTR; - if (rmt != NULL && (i == n || error != EWOULDBLOCK)) { - /*- - * XXX this is unnecessary and possibly wrong if the timeout - * expired. Then the remaining time should be zero. If the - * calculation gives a nonzero value, then we have a bug. - * (1) if settimeofday() was called, then the calculation is - * probably wrong, since `time' has probably become - * inconsistent with the ending time `atv'. - * XXX (1) should be fixed now with p->p_sleepend; - * (2) otherwise, our calculation of `timo' was wrong, perhaps - * due to `tick' being wrong when hzto() was called or - * changing afterwards (it can be wrong or change due to - * hzto() not knowing about adjtime(2) or tickadj(8)). - * Then we should be sleeping again instead instead of - * returning. Rounding up in hzto() probably fixes this - * problem for small timeouts, but the absolute error may - * be large for large timeouts. - */ - getmicrotime(&utv); - if (i != n) { - atv.tv_sec += (n - i - 1) * 100000000; - timevaladd(&atv, &rtv); - } - timevalsub(&atv, &utv); - if (atv.tv_sec < 0) - timerclear(&atv); - TIMEVAL_TO_TIMESPEC(&atv, rmt); + break; } } - return (error == EWOULDBLOCK ? 0 : error); + if (rmt) { + *rmt = ts; + timespecsub(rmt, &ts2); + } + return(error); } #ifndef _SYS_SYSPROTO_H_ Index: kern/sys_generic.c =================================================================== RCS file: /home/ncvs/src/sys/kern/sys_generic.c,v retrieving revision 1.35 diff -u -r1.35 sys_generic.c --- sys_generic.c 1998/04/02 07:22:17 1.35 +++ sys_generic.c 1998/04/02 16:59:41 @@ -538,8 +538,8 @@ */ fd_mask s_selbits[howmany(2048, NFDBITS)]; fd_mask *ibits[3], *obits[3], *selbits, *sbp; - struct timeval atv; - int s, ncoll, error, timo, term; + struct timeval atv, rtv, ttv; + int s, ncoll, error, timo; u_int nbufbytes, ncpbytes, nfdbits; if (uap->nd < 0) @@ -600,21 +600,29 @@ error = EINVAL; goto done; } - term = ticks + tvtohz(&atv); - } else - term = 0; + getmicroruntime(&rtv); + timevaladd(&atv, &rtv); + } else { + atv.tv_sec = 0; + atv.tv_usec = 0; + } + timo = 0; retry: ncoll = nselcoll; p->p_flag |= P_SELECT; error = selscan(p, ibits, obits, uap->nd); if (error || p->p_retval[0]) goto done; - s = splhigh(); - if (term && term <= ticks) { - splx(s); - goto done; + if (atv.tv_sec) { + getmicroruntime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + goto done; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); } - timo = term ? term - ticks : 0; + s = splhigh(); if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { splx(s); goto retry; @@ -701,8 +709,8 @@ { caddr_t bits; char smallbits[32 * sizeof(struct pollfd)]; - struct timeval atv; - int s, ncoll, error = 0, timo, term; + struct timeval atv, rtv, ttv; + int s, ncoll, error = 0, timo; size_t ni; if (SCARG(uap, nfds) > p->p_fd->fd_nfiles) { @@ -724,21 +732,29 @@ error = EINVAL; goto done; } - term = ticks + tvtohz(&atv); - } else - term = 0; + getmicroruntime(&rtv); + timevaladd(&atv, &rtv); + } else { + atv.tv_sec = 0; + atv.tv_usec = 0; + } + timo = 0; retry: ncoll = nselcoll; p->p_flag |= P_SELECT; error = pollscan(p, (struct pollfd *)bits, SCARG(uap, nfds)); if (error || p->p_retval[0]) goto done; + if (atv.tv_sec) { + getmicroruntime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + goto done; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); + } s = splhigh(); - if (term && term <= ticks) { - splx(s); - goto done; - } - timo = term ? term - ticks : 0; if ((p->p_flag & P_SELECT) == 0 || nselcoll != ncoll) { splx(s); goto retry; Index: kern/uipc_socket2.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_socket2.c,v retrieving revision 1.31 diff -u -r1.31 uipc_socket2.c --- uipc_socket2.c 1998/03/01 19:39:19 1.31 +++ uipc_socket2.c 1998/04/01 06:10:25 @@ -157,13 +157,14 @@ { register struct socket *so; unsigned int i, j, qlen; - static int rnd; - static long old_mono_secs; + static struct timeval old_runtime; static unsigned int cur_cnt, old_cnt; + struct timeval tv; - if ((i = (mono_time.tv_sec - old_mono_secs)) != 0) { - old_mono_secs = mono_time.tv_sec; + getmicroruntime(&tv); + if ((i = (tv.tv_sec - old_runtime.tv_sec)) != 0) { + old_runtime = tv; old_cnt = cur_cnt / i; cur_cnt = 0; } Index: msdosfs/msdosfs_denode.c =================================================================== RCS file: /home/ncvs/src/sys/msdosfs/msdosfs_denode.c,v retrieving revision 1.34 diff -u -r1.34 msdosfs_denode.c --- msdosfs_denode.c 1998/03/26 20:52:51 1.34 +++ msdosfs_denode.c 1998/04/01 06:10:25 @@ -198,6 +198,7 @@ struct vnode *nvp; struct buf *bp; struct proc *p = curproc; /* XXX */ + struct timeval tv; #ifdef MSDOSFS_DEBUG printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n", @@ -345,8 +346,9 @@ } } else nvp->v_type = VREG; - SETHIGH(ldep->de_modrev, mono_time.tv_sec); - SETLOW(ldep->de_modrev, mono_time.tv_usec * 4294); + getmicroruntime(&tv); + SETHIGH(ldep->de_modrev, tv.tv_sec); + SETLOW(ldep->de_modrev, tv.tv_usec * 4294); VREF(ldep->de_devvp); *depp = ldep; return (0); Index: net/if_spppsubr.c =================================================================== RCS file: /home/ncvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.35 diff -u -r1.35 if_spppsubr.c --- if_spppsubr.c 1998/03/30 09:52:06 1.35 +++ if_spppsubr.c 1998/04/01 06:10:26 @@ -1018,8 +1018,10 @@ struct ppp_header *h; struct cisco_packet *ch; struct mbuf *m; - u_long t = (time_second - boottime.tv_sec) * 1000; + struct timeval tv; + getmicroruntime(&tv); + MGETHDR (m, M_DONTWAIT, MT_DATA); if (! m) return; @@ -1036,8 +1038,8 @@ ch->par1 = htonl (par1); ch->par2 = htonl (par2); ch->rel = -1; - ch->time0 = htons ((u_short) (t >> 16)); - ch->time1 = htons ((u_short) t); + ch->time0 = htons ((u_short) (tv.tv_sec >> 16)); + ch->time1 = htons ((u_short) tv.tv_sec); if (debug) log(LOG_DEBUG, Index: sys/kernel.h =================================================================== RCS file: /home/ncvs/src/sys/sys/kernel.h,v retrieving revision 1.37 diff -u -r1.37 kernel.h --- kernel.h 1998/03/28 11:50:35 1.37 +++ kernel.h 1998/04/01 06:10:26 @@ -58,11 +58,8 @@ extern char kernelname[MAXPATHLEN]; /* 1.2 */ -extern volatile struct timeval mono_time; extern struct timeval boottime; -extern struct timeval runtime; -extern struct timeval time; /* nonvolatile at ipl >= splclock() */ extern struct timezone tz; /* XXX */ extern int tick; /* usec per tick (1000000 / hz) */ Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.56 diff -u -r1.56 proc.h --- proc.h 1998/03/28 10:33:23 1.56 +++ proc.h 1998/04/01 09:34:17 @@ -135,10 +135,10 @@ struct itimerval p_realtimer; /* Alarm timer. */ struct timeval p_rtime; /* Real time. */ + struct timeval p_runtime; /* When last scheduled */ u_quad_t p_uticks; /* Statclock hits in user mode. */ u_quad_t p_sticks; /* Statclock hits in system mode. */ u_quad_t p_iticks; /* Statclock hits processing intr. */ - struct timeval *p_sleepend; /* Wake time for nanosleep & friends */ int p_traceflag; /* Kernel trace points. */ struct vnode *p_tracep; /* Trace to vnode. */ Index: sys/time.h =================================================================== RCS file: /home/ncvs/src/sys/sys/time.h,v retrieving revision 1.22 diff -u -r1.22 time.h --- time.h 1998/03/30 09:55:35 1.22 +++ time.h 1998/04/02 08:40:36 @@ -149,10 +149,45 @@ u_int32_t offset_sec; u_int32_t offset_micro; u_int64_t offset_nano; + struct timeval microtime; + struct timespec nanotime; struct timecounter *other; struct timecounter *tweak; }; +#ifdef KERNEL +/* Operations on timespecs */ +#define timespecclear(tvp) (tvp)->tv_sec = (tvp)->tv_nsec = 0 +#define timespecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) +#define timespeccmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#define timespecadd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_nsec += (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec >= 1000000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_nsec -= 1000000000; \ + } \ + } while (0) +#define timespecsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_nsec -= (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_nsec += 1000000000; \ + } \ + } while (0) +/* Operations on timevals. */ +#define timevalcmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec) ? \ + ((tvp)->tv_usec cmp (uvp)->tv_usec) : \ + ((tvp)->tv_sec cmp (uvp)->tv_sec)) +#endif /* KERNEL */ + /* Operations on timevals. */ #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) @@ -225,13 +260,16 @@ void forward_timecounter __P((void)); void getmicrotime __P((struct timeval *tv)); +void getmicroruntime __P((struct timeval *tv)); void getnanotime __P((struct timespec *tv)); +void getnanoruntime __P((struct timespec *tv)); void init_timecounter __P((struct timecounter *tc)); int itimerfix __P((struct timeval *tv)); int itimerdecr __P((struct itimerval *itp, int usec)); void microtime __P((struct timeval *tv)); +void microruntime __P((struct timeval *tv)); void nanotime __P((struct timespec *ts)); -void second_overflow __P((u_int32_t *psec)); +void nanoruntime __P((struct timespec *ts)); void set_timecounter __P((struct timespec *ts)); void timevaladd __P((struct timeval *, struct timeval *)); void timevalsub __P((struct timeval *, struct timeval *)); Index: ufs/ufs/ufs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.81 diff -u -r1.81 ufs_vnops.c --- ufs_vnops.c 1998/03/30 09:56:37 1.81 +++ ufs_vnops.c 1998/04/01 06:10:27 @@ -1965,6 +1965,7 @@ { struct inode *ip; struct vnode *vp, *nvp; + struct timeval tv; vp = *vpp; ip = VTOI(vp); @@ -2003,8 +2004,9 @@ /* * Initialize modrev times */ - SETHIGH(ip->i_modrev, mono_time.tv_sec); - SETLOW(ip->i_modrev, mono_time.tv_usec * 4294); + getmicroruntime(&tv); + SETHIGH(ip->i_modrev, tv.tv_sec); + SETLOW(ip->i_modrev, tv.tv_usec * 4294); *vpp = vp; return (0); } -- Poul-Henning Kamp FreeBSD coreteam member phk@FreeBSD.ORG "Real hackers run -current on their laptop." "Drink MONO-tonic, it goes down but it will NEVER come back up!" To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message