Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 04 Apr 1998 10:04:41 +0200
From:      Poul-Henning Kamp <phk@critter.freebsd.dk>
To:        Alex <garbanzo@hooked.net>
Cc:        current <current@FreeBSD.ORG>
Subject:   Re: Working patch *with* splhigh() (Was Re: More info RE: X slowdown in -current) 
Message-ID:  <4698.891677081@critter.freebsd.dk>
In-Reply-To: Your message of "Fri, 03 Apr 1998 18:22:45 -0800." <Pine.BSF.3.96.980403182000.3483A-100000@zippy.dyn.ml.org> 

next in thread | previous in thread | raw e-mail | index | archive | help

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4698.891677081>