summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1998-04-04 13:26:20 +0000
committerphk <phk@FreeBSD.org>1998-04-04 13:26:20 +0000
commit5e9a131f20894d1df9e8c1768be6eb1cc29a3cf4 (patch)
tree76909c92c472744745de10e5dacc307ea5f7af45 /sys/kern
parentddcbf85eb29fd2d50ce1afa0243be370d4893370 (diff)
downloadFreeBSD-src-5e9a131f20894d1df9e8c1768be6eb1cc29a3cf4.zip
FreeBSD-src-5e9a131f20894d1df9e8c1768be6eb1cc29a3cf4.tar.gz
Time changes mark 2:
* Figure out UTC relative to boottime. Four new functions provide time relative to boottime. * move "runtime" into struct proc. This helps fix the calcru() problem in SMP. * kill mono_time. * add timespec{add|sub|cmp} macros to time.h. (XXX: These may change!) * nanosleep, select & poll takes long sleeps one day at a time Reviewed by: bde Tested by: ache and others
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c14
-rw-r--r--sys/kern/kern_clock.c127
-rw-r--r--sys/kern/kern_resource.c17
-rw-r--r--sys/kern/kern_synch.c10
-rw-r--r--sys/kern/kern_tc.c127
-rw-r--r--sys/kern/kern_time.c90
-rw-r--r--sys/kern/sys_generic.c58
-rw-r--r--sys/kern/uipc_sockbuf.c11
-rw-r--r--sys/kern/uipc_socket2.c11
9 files changed, 279 insertions, 186 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 2372c26..d4bb6d1 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
- * $Id: init_main.c,v 1.84 1998/02/15 04:16:57 dyson Exp $
+ * $Id: init_main.c,v 1.85 1998/03/30 09:49:52 phk Exp $
*/
#include "opt_devfs.h"
@@ -104,10 +104,6 @@ static int shutdowntimeout = 120;
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 @@ proc0_post(dummy)
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);
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index e3fb798..cf25a46 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -39,7 +39,7 @@ static volatile int print_tci = 1;
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.61 1998/03/31 10:44:56 phk Exp $
+ * $Id: kern_clock.c,v 1.62 1998/03/31 10:47:01 phk Exp $
*/
#include <sys/param.h>
@@ -138,8 +138,6 @@ int ticks;
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 @@ tvtohz(tv)
{
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 @@ int
hzto(tv)
struct timeval *tv;
{
- register long sec, usec;
struct timeval t2;
getmicrotime(&t2);
@@ -512,12 +508,71 @@ getmicrotime(struct timeval *tvp)
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 @@ getnanotime(struct timespec *tsp)
}
void
-microtime(struct timeval *tv)
+microruntime(struct timeval *tv)
{
struct timecounter *tc;
@@ -543,7 +598,7 @@ microtime(struct timeval *tv)
}
void
-nanotime(struct timespec *tv)
+nanoruntime(struct timespec *tv)
{
u_int count;
u_int64_t delta;
@@ -601,7 +656,7 @@ init_timecounter(struct timecounter *tc)
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 @@ init_timecounter(struct timecounter *tc)
void
set_timecounter(struct timespec *ts)
{
- struct timecounter *tc, *tco;
- int s;
-
- /*
- * 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);
+ struct timespec ts2;
+
+ 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 @@ switch_timecounter(struct timecounter *newtc)
timecounter = newtc;
splx(s);
}
+#endif
static struct timecounter *
sync_other_counter(void)
@@ -703,14 +753,8 @@ tco_forward(void)
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 @@ tco_forward(void)
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 struct timecounter dummy_timecounter[3] = {
};
static void
-initdummytimecounter(dummy)
- void *dummy;
+initdummytimecounter(void *dummy)
{
init_timecounter(dummy_timecounter);
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 1b034ca..004a446 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_resource.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_resource.c,v 1.32 1998/02/09 06:09:24 eivind Exp $
+ * $Id: kern_resource.c,v 1.33 1998/03/04 10:25:52 dufault Exp $
*/
#include "opt_compat.h"
@@ -491,6 +491,7 @@ calcru(p, up, sp, ip)
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 @@ calcru(p, up, sp, ip)
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;
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index c2f7eb0..4499554 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
- * $Id: kern_synch.c,v 1.52 1998/03/28 11:49:55 dufault Exp $
+ * $Id: kern_synch.c,v 1.53 1998/03/28 18:16:29 dufault Exp $
*/
#include "opt_ktrace.h"
@@ -621,9 +621,9 @@ mi_switch()
* 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 @@ mi_switch()
*/
cnt.v_swtch++;
cpu_switch(p);
- microtime(&runtime);
+ microruntime(&p->p_runtime);
splx(x);
}
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index e3fb798..cf25a46 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -39,7 +39,7 @@ static volatile int print_tci = 1;
* SUCH DAMAGE.
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
- * $Id: kern_clock.c,v 1.61 1998/03/31 10:44:56 phk Exp $
+ * $Id: kern_clock.c,v 1.62 1998/03/31 10:47:01 phk Exp $
*/
#include <sys/param.h>
@@ -138,8 +138,6 @@ int ticks;
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 @@ tvtohz(tv)
{
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 @@ int
hzto(tv)
struct timeval *tv;
{
- register long sec, usec;
struct timeval t2;
getmicrotime(&t2);
@@ -512,12 +508,71 @@ getmicrotime(struct timeval *tvp)
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 @@ getnanotime(struct timespec *tsp)
}
void
-microtime(struct timeval *tv)
+microruntime(struct timeval *tv)
{
struct timecounter *tc;
@@ -543,7 +598,7 @@ microtime(struct timeval *tv)
}
void
-nanotime(struct timespec *tv)
+nanoruntime(struct timespec *tv)
{
u_int count;
u_int64_t delta;
@@ -601,7 +656,7 @@ init_timecounter(struct timecounter *tc)
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 @@ init_timecounter(struct timecounter *tc)
void
set_timecounter(struct timespec *ts)
{
- struct timecounter *tc, *tco;
- int s;
-
- /*
- * 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);
+ struct timespec ts2;
+
+ 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 @@ switch_timecounter(struct timecounter *newtc)
timecounter = newtc;
splx(s);
}
+#endif
static struct timecounter *
sync_other_counter(void)
@@ -703,14 +753,8 @@ tco_forward(void)
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 @@ tco_forward(void)
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 struct timecounter dummy_timecounter[3] = {
};
static void
-initdummytimecounter(dummy)
- void *dummy;
+initdummytimecounter(void *dummy)
{
init_timecounter(dummy_timecounter);
}
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index f0897d7..786f67f 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_time.c 8.1 (Berkeley) 6/10/93
- * $Id: kern_time.c,v 1.43 1998/03/26 20:51:41 phk Exp $
+ * $Id: kern_time.c,v 1.44 1998/03/30 09:50:23 phk Exp $
*/
#include <sys/param.h>
@@ -84,9 +84,8 @@ settime(tv)
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 @@ settime(tv)
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 @@ nanosleep1(p, rqt, rmt)
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_
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index fb0034f..ee056f0 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)sys_generic.c 8.5 (Berkeley) 1/21/94
- * $Id: sys_generic.c,v 1.34 1998/03/30 09:50:29 phk Exp $
+ * $Id: sys_generic.c,v 1.35 1998/04/02 07:22:17 phk Exp $
*/
#include "opt_ktrace.h"
@@ -538,8 +538,8 @@ select(p, uap)
*/
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 @@ select(p, uap)
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 @@ poll(p, uap)
{
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 @@ poll(p, uap)
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;
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 997442d..47df800 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.30 1997/09/07 16:53:48 bde Exp $
+ * $Id: uipc_socket2.c,v 1.31 1998/03/01 19:39:19 guido Exp $
*/
#include <sys/param.h>
@@ -157,13 +157,14 @@ sodropablereq(head)
{
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;
}
diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c
index 997442d..47df800 100644
--- a/sys/kern/uipc_socket2.c
+++ b/sys/kern/uipc_socket2.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
- * $Id: uipc_socket2.c,v 1.30 1997/09/07 16:53:48 bde Exp $
+ * $Id: uipc_socket2.c,v 1.31 1998/03/01 19:39:19 guido Exp $
*/
#include <sys/param.h>
@@ -157,13 +157,14 @@ sodropablereq(head)
{
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;
}
OpenPOWER on IntegriCloud