Use more timespecs internally. From Alexander Shishkin and me.

Welcome to 4.99.70, 30 more to go for 100.
This commit is contained in:
christos 2008-07-15 16:18:08 +00:00
parent 03df89373a
commit aa389c698d
10 changed files with 155 additions and 150 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: altq_rmclass.c,v 1.20 2007/03/04 05:59:02 christos Exp $ */
/* $NetBSD: altq_rmclass.c,v 1.21 2008/07/15 16:18:08 christos Exp $ */
/* $KAME: altq_rmclass.c,v 1.19 2005/04/13 03:44:25 suz Exp $ */
/*
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.20 2007/03/04 05:59:02 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.21 2008/07/15 16:18:08 christos Exp $");
/* #ident "@(#)rm_class.c 1.48 97/12/05 SMI" */
@ -1448,11 +1448,10 @@ rmc_dropall(struct rm_class *cl)
}
#if (__FreeBSD_version > 300000)
/* hzto() is removed from FreeBSD-3.0 */
static int hzto(struct timeval *);
static int tvhzto(struct timeval *);
static int
hzto(struct timeval *tv)
tvhzto(struct timeval *tv)
{
struct timeval t2;
@ -1524,10 +1523,10 @@ rmc_delay_action(struct rm_class *cl, struct rm_class *borrow)
if (ndelay > tick * 2) {
#ifdef __FreeBSD__
/* FreeBSD rounds up the tick */
t = hzto(&cl->undertime_);
t = tvhzto(&cl->undertime_);
#else
/* other BSDs round down the tick */
t = hzto(&cl->undertime_) + 1;
t = tvhzto(&cl->undertime_) + 1;
#endif
} else
t = 2;

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_misc_notalpha.c,v 1.102 2008/04/28 20:23:43 martin Exp $ */
/* $NetBSD: linux_misc_notalpha.c,v 1.103 2008/07/15 16:18:08 christos Exp $ */
/*-
* Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.102 2008/04/28 20:23:43 martin Exp $");
__KERNEL_RCSID(0, "$NetBSD: linux_misc_notalpha.c,v 1.103 2008/07/15 16:18:08 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -97,8 +97,8 @@ linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_
syscallarg(unsigned int) secs;
} */
struct proc *p = l->l_proc;
struct timeval now;
struct itimerval *itp, it;
struct timespec now;
struct itimerspec *itp, it;
struct ptimer *ptp, *spare;
extern kmutex_t timer_lock;
struct ptimers *pts;
@ -118,16 +118,16 @@ linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_
*/
if (itp) {
callout_stop(&pts->pts_timers[ITIMER_REAL]->pt_ch);
timerclear(&itp->it_interval);
getmicrotime(&now);
if (timerisset(&itp->it_value) &&
timercmp(&itp->it_value, &now, >))
timersub(&itp->it_value, &now, &itp->it_value);
timespecclear(&itp->it_interval);
getnanotime(&now);
if (timespecisset(&itp->it_value) &&
timespeccmp(&itp->it_value, &now, >))
timespecsub(&itp->it_value, &now, &itp->it_value);
/*
* Return how many seconds were left (rounded up)
*/
retval[0] = itp->it_value.tv_sec;
if (itp->it_value.tv_usec)
if (itp->it_value.tv_nsec)
retval[0]++;
} else {
retval[0] = 0;
@ -138,7 +138,7 @@ linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_
*/
if (SCARG(uap, secs) == 0) {
if (itp)
timerclear(&itp->it_value);
timespecclear(&itp->it_value);
mutex_spin_exit(&timer_lock);
return 0;
}
@ -146,10 +146,10 @@ linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_
/*
* Check the new alarm time for sanity, and set it.
*/
timerclear(&it.it_interval);
timespecclear(&it.it_interval);
it.it_value.tv_sec = SCARG(uap, secs);
it.it_value.tv_usec = 0;
if (itimerfix(&it.it_value) || itimerfix(&it.it_interval)) {
it.it_value.tv_nsec = 0;
if (itimespecfix(&it.it_value) || itimespecfix(&it.it_interval)) {
mutex_spin_exit(&timer_lock);
return (EINVAL);
}
@ -175,14 +175,14 @@ linux_sys_alarm(struct lwp *l, const struct linux_sys_alarm_args *uap, register_
pts->pts_timers[ITIMER_REAL] = ptp;
}
if (timerisset(&it.it_value)) {
if (timespecisset(&it.it_value)) {
/*
* Don't need to check hzto() return value, here.
* Don't need to check tvhzto() return value, here.
* callout_reset() does it for us.
*/
getmicrotime(&now);
timeradd(&it.it_value, &now, &it.it_value);
callout_reset(&ptp->pt_ch, hzto(&it.it_value),
getnanotime(&now);
timespecadd(&it.it_value, &now, &it.it_value);
callout_reset(&ptp->pt_ch, tshzto(&it.it_value),
realtimerexpire, ptp);
}
ptp->pt_time = it;

View File

@ -1,4 +1,4 @@
/* $NetBSD: netbsd32_time.c,v 1.33 2008/05/29 14:51:26 mrg Exp $ */
/* $NetBSD: netbsd32_time.c,v 1.34 2008/07/15 16:18:08 christos Exp $ */
/*
* Copyright (c) 1998, 2001 Matthew R. Green
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.33 2008/05/29 14:51:26 mrg Exp $");
__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.34 2008/07/15 16:18:08 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ntp.h"
@ -418,9 +418,7 @@ netbsd32_nanosleep(struct lwp *l, const struct netbsd32_nanosleep_args *uap, reg
} */
static int nanowait;
struct netbsd32_timespec ts32;
struct timespec rqt;
struct timespec rmt;
struct timeval atv, utv, ctime;
struct timespec rqt, ctime, rmt;
int error, timo;
error = copyin(SCARG_P32(uap, rqtp), &ts32, sizeof(ts32));
@ -428,13 +426,12 @@ netbsd32_nanosleep(struct lwp *l, const struct netbsd32_nanosleep_args *uap, reg
return (error);
netbsd32_to_timespec(&ts32, &rqt);
TIMESPEC_TO_TIMEVAL(&atv,&rqt);
if (itimerfix(&atv))
if (itimespecfix(&rqt))
return (EINVAL);
getmicrotime(&ctime);
timeradd(&atv,&ctime,&atv);
timo = hzto(&atv);
getnanotime(&ctime);
timespecadd(&rqt, &ctime, &rqt);
timo = tshzto(&rqt);
/*
* Avoid inadvertantly sleeping forever
*/
@ -450,13 +447,12 @@ netbsd32_nanosleep(struct lwp *l, const struct netbsd32_nanosleep_args *uap, reg
if (SCARG_P32(uap, rmtp)) {
int error1;
getmicrotime(&utv);
getnanotime(&rmt);
timersub(&atv, &utv, &utv);
if (utv.tv_sec < 0)
timerclear(&utv);
timespecsub(&rqt, &rmt, &rmt);
if (rmt.tv_sec < 0)
timespecclear(&rmt);
TIMEVAL_TO_TIMESPEC(&utv,&rmt);
netbsd32_from_timespec(&rmt, &ts32);
error1 = copyout(&ts32, SCARG_P32(uap,rmtp), sizeof(ts32));
if (error1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: isp_netbsd.c,v 1.77 2008/04/08 12:07:26 cegger Exp $ */
/* $NetBSD: isp_netbsd.c,v 1.78 2008/07/15 16:18:08 christos Exp $ */
/*
* Platform (NetBSD) dependent common attachment code for Qlogic adapters.
*/
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: isp_netbsd.c,v 1.77 2008/04/08 12:07:26 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: isp_netbsd.c,v 1.78 2008/07/15 16:18:08 christos Exp $");
#include <dev/ic/isp_netbsd.h>
#include <dev/ic/isp_ioctl.h>
@ -1582,7 +1582,7 @@ isp_mbox_wait_complete(struct ispsoftc *isp, mbreg_t *mbp)
}
}
timeradd(&tv, &start, &tv);
to = hzto(&tv);
to = tvhzto(&tv);
if (to == 0)
to = 1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sequencer.c,v 1.49 2008/06/12 23:06:14 cegger Exp $ */
/* $NetBSD: sequencer.c,v 1.50 2008/07/15 16:18:08 christos Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.49 2008/06/12 23:06:14 cegger Exp $");
__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.50 2008/07/15 16:18:08 christos Exp $");
#include "sequencer.h"
@ -904,7 +904,7 @@ seq_timer_waitabs(struct sequencer_softc *sc, uint32_t divs)
DPRINTFN(4, ("seq_timer_waitabs: adjdivs=%d, sleep when=%ld.%06ld",
divs, when.tv_sec, when.tv_usec));
ADDTIMEVAL(&when, &t->reftime); /* abstime for end */
ticks = hzto(&when);
ticks = tvhzto(&when);
DPRINTFN(4, (" when+start=%ld.%06ld, tick=%d\n",
when.tv_sec, when.tv_usec, ticks));
if (ticks > 0) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_time.c,v 1.149 2008/07/08 20:53:02 christos Exp $ */
/* $NetBSD: kern_time.c,v 1.150 2008/07/15 16:18:08 christos Exp $ */
/*-
* Copyright (c) 2000, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.149 2008/07/08 20:53:02 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.150 2008/07/15 16:18:08 christos Exp $");
#include <sys/param.h>
#include <sys/resourcevar.h>
@ -590,7 +590,7 @@ timer_create1(timer_t *tid, clockid_t id, struct sigevent *evp,
pt->pt_poverruns = 0;
pt->pt_entry = timerid;
pt->pt_queued = false;
timerclear(&pt->pt_time.it_value);
timespecclear(&pt->pt_time.it_value);
if (id == CLOCK_REALTIME)
callout_init(&pt->pt_ch, 0);
else
@ -631,7 +631,7 @@ sys_timer_delete(struct lwp *l, const struct sys_timer_delete_args *uap,
ptn = LIST_NEXT(pt, pt_list);
LIST_REMOVE(pt, pt_list);
for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
timeradd(&pt->pt_time.it_value,
timespecadd(&pt->pt_time.it_value,
&ptn->pt_time.it_value,
&ptn->pt_time.it_value);
pt->pt_active = 0;
@ -658,12 +658,12 @@ timer_settime(struct ptimer *pt)
if (pt->pt_type == CLOCK_REALTIME) {
callout_stop(&pt->pt_ch);
if (timerisset(&pt->pt_time.it_value)) {
if (timespecisset(&pt->pt_time.it_value)) {
/*
* Don't need to check hzto() return value, here.
* Don't need to check tshzto() return value, here.
* callout_reset() does it for us.
*/
callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
callout_reset(&pt->pt_ch, tshzto(&pt->pt_time.it_value),
realtimerexpire, pt);
}
} else {
@ -671,21 +671,21 @@ timer_settime(struct ptimer *pt)
ptn = LIST_NEXT(pt, pt_list);
LIST_REMOVE(pt, pt_list);
for ( ; ptn; ptn = LIST_NEXT(ptn, pt_list))
timeradd(&pt->pt_time.it_value,
timespecadd(&pt->pt_time.it_value,
&ptn->pt_time.it_value,
&ptn->pt_time.it_value);
}
if (timerisset(&pt->pt_time.it_value)) {
if (timespecisset(&pt->pt_time.it_value)) {
if (pt->pt_type == CLOCK_VIRTUAL)
ptl = &pt->pt_proc->p_timers->pts_virtual;
else
ptl = &pt->pt_proc->p_timers->pts_prof;
for (ptn = LIST_FIRST(ptl), pptn = NULL;
ptn && timercmp(&pt->pt_time.it_value,
ptn && timespeccmp(&pt->pt_time.it_value,
&ptn->pt_time.it_value, >);
pptn = ptn, ptn = LIST_NEXT(ptn, pt_list))
timersub(&pt->pt_time.it_value,
timespecsub(&pt->pt_time.it_value,
&ptn->pt_time.it_value,
&pt->pt_time.it_value);
@ -695,7 +695,7 @@ timer_settime(struct ptimer *pt)
LIST_INSERT_HEAD(ptl, pt, pt_list);
for ( ; ptn ; ptn = LIST_NEXT(ptn, pt_list))
timersub(&ptn->pt_time.it_value,
timespecsub(&ptn->pt_time.it_value,
&pt->pt_time.it_value,
&ptn->pt_time.it_value);
@ -706,14 +706,14 @@ timer_settime(struct ptimer *pt)
}
void
timer_gettime(struct ptimer *pt, struct itimerval *aitv)
timer_gettime(struct ptimer *pt, struct itimerspec *aits)
{
struct timeval now;
struct timespec now;
struct ptimer *ptn;
KASSERT(mutex_owned(&timer_lock));
*aitv = pt->pt_time;
*aits = pt->pt_time;
if (pt->pt_type == CLOCK_REALTIME) {
/*
* Convert from absolute to relative time in .it_value
@ -722,13 +722,13 @@ timer_gettime(struct ptimer *pt, struct itimerval *aitv)
* between current time and time for the timer to go
* off.
*/
if (timerisset(&aitv->it_value)) {
getmicrotime(&now);
if (timercmp(&aitv->it_value, &now, <))
timerclear(&aitv->it_value);
if (timespecisset(&aits->it_value)) {
getnanotime(&now);
if (timespeccmp(&aits->it_value, &now, <))
timespecclear(&aits->it_value);
else
timersub(&aitv->it_value, &now,
&aitv->it_value);
timespecsub(&aits->it_value, &now,
&aits->it_value);
}
} else if (pt->pt_active) {
if (pt->pt_type == CLOCK_VIRTUAL)
@ -736,11 +736,11 @@ timer_gettime(struct ptimer *pt, struct itimerval *aitv)
else
ptn = LIST_FIRST(&pt->pt_proc->p_timers->pts_prof);
for ( ; ptn && ptn != pt; ptn = LIST_NEXT(ptn, pt_list))
timeradd(&aitv->it_value,
&ptn->pt_time.it_value, &aitv->it_value);
timespecadd(&aits->it_value,
&ptn->pt_time.it_value, &aits->it_value);
KASSERT(ptn != NULL); /* pt should be findable on the list */
} else
timerclear(&aitv->it_value);
timespecclear(&aits->it_value);
}
@ -780,8 +780,8 @@ int
dotimer_settime(int timerid, struct itimerspec *value,
struct itimerspec *ovalue, int flags, struct proc *p)
{
struct timeval now;
struct itimerval val, oval;
struct timespec now;
struct itimerspec val, oval;
struct ptimers *pts;
struct ptimer *pt;
@ -789,15 +789,14 @@ dotimer_settime(int timerid, struct itimerspec *value,
if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
return EINVAL;
TIMESPEC_TO_TIMEVAL(&val.it_value, &value->it_value);
TIMESPEC_TO_TIMEVAL(&val.it_interval, &value->it_interval);
if (itimerfix(&val.it_value) || itimerfix(&val.it_interval))
return (EINVAL);
val = *value;
if (itimespecfix(&val.it_value) || itimespecfix(&val.it_interval))
return EINVAL;
mutex_spin_enter(&timer_lock);
if ((pt = pts->pts_timers[timerid]) == NULL) {
mutex_spin_exit(&timer_lock);
return (EINVAL);
return EINVAL;
}
oval = pt->pt_time;
@ -810,22 +809,22 @@ dotimer_settime(int timerid, struct itimerspec *value,
* to zero, which would cancel the timer, or let it go
* negative, which would confuse the comparison tests.
*/
if (timerisset(&pt->pt_time.it_value)) {
if (timespecisset(&pt->pt_time.it_value)) {
if (pt->pt_type == CLOCK_REALTIME) {
if ((flags & TIMER_ABSTIME) == 0) {
getmicrotime(&now);
timeradd(&pt->pt_time.it_value, &now,
getnanotime(&now);
timespecadd(&pt->pt_time.it_value, &now,
&pt->pt_time.it_value);
}
} else {
if ((flags & TIMER_ABSTIME) != 0) {
getmicrotime(&now);
timersub(&pt->pt_time.it_value, &now,
getnanotime(&now);
timespecsub(&pt->pt_time.it_value, &now,
&pt->pt_time.it_value);
if (!timerisset(&pt->pt_time.it_value) ||
if (!timespecisset(&pt->pt_time.it_value) ||
pt->pt_time.it_value.tv_sec < 0) {
pt->pt_time.it_value.tv_sec = 0;
pt->pt_time.it_value.tv_usec = 1;
pt->pt_time.it_value.tv_nsec = 1;
}
}
}
@ -834,10 +833,8 @@ dotimer_settime(int timerid, struct itimerspec *value,
timer_settime(pt);
mutex_spin_exit(&timer_lock);
if (ovalue) {
TIMEVAL_TO_TIMESPEC(&oval.it_value, &ovalue->it_value);
TIMEVAL_TO_TIMESPEC(&oval.it_interval, &ovalue->it_interval);
}
if (ovalue)
*ovalue = oval;
return (0);
}
@ -866,7 +863,6 @@ dotimer_gettime(int timerid, struct proc *p, struct itimerspec *its)
{
struct ptimer *pt;
struct ptimers *pts;
struct itimerval aitv;
pts = p->p_timers;
if (pts == NULL || timerid < 2 || timerid >= TIMER_MAX)
@ -876,12 +872,9 @@ dotimer_gettime(int timerid, struct proc *p, struct itimerspec *its)
mutex_spin_exit(&timer_lock);
return (EINVAL);
}
timer_gettime(pt, &aitv);
timer_gettime(pt, its);
mutex_spin_exit(&timer_lock);
TIMEVAL_TO_TIMESPEC(&aitv.it_interval, &its->it_interval);
TIMEVAL_TO_TIMESPEC(&aitv.it_value, &its->it_value);
return 0;
}
@ -930,7 +923,7 @@ void
realtimerexpire(void *arg)
{
uint64_t last_val, next_val, interval, now_ms;
struct timeval now, next;
struct timespec now, next;
struct ptimer *pt;
int backwards;
@ -939,24 +932,22 @@ realtimerexpire(void *arg)
mutex_spin_enter(&timer_lock);
itimerfire(pt);
if (!timerisset(&pt->pt_time.it_interval)) {
timerclear(&pt->pt_time.it_value);
if (!timespecisset(&pt->pt_time.it_interval)) {
timespecclear(&pt->pt_time.it_value);
mutex_spin_exit(&timer_lock);
return;
}
getmicrotime(&now);
backwards = (timercmp(&pt->pt_time.it_value, &now, >));
timeradd(&pt->pt_time.it_value, &pt->pt_time.it_interval, &next);
getnanotime(&now);
backwards = (timespeccmp(&pt->pt_time.it_value, &now, >));
timespecadd(&pt->pt_time.it_value, &pt->pt_time.it_interval, &next);
/* Handle the easy case of non-overflown timers first. */
if (!backwards && timercmp(&next, &now, >)) {
if (!backwards && timespeccmp(&next, &now, >)) {
pt->pt_time.it_value = next;
} else {
#define TV2MS(x) (((uint64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)
now_ms = TV2MS(&now);
last_val = TV2MS(&pt->pt_time.it_value);
interval = TV2MS(&pt->pt_time.it_interval);
#undef TV2MS
now_ms = timespec2ns(&now);
last_val = timespec2ns(&pt->pt_time.it_value);
interval = timespec2ns(&pt->pt_time.it_interval);
next_val = now_ms +
(now_ms - last_val + interval - 1) % interval;
@ -966,15 +957,15 @@ realtimerexpire(void *arg)
else
pt->pt_overruns += (now_ms - last_val) / interval;
pt->pt_time.it_value.tv_sec = next_val / 1000000;
pt->pt_time.it_value.tv_usec = next_val % 1000000;
pt->pt_time.it_value.tv_sec = next_val / 1000000000;
pt->pt_time.it_value.tv_nsec = next_val % 1000000000;
}
/*
* Don't need to check hzto() return value, here.
* Don't need to check tshzto() return value, here.
* callout_reset() does it for us.
*/
callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value),
callout_reset(&pt->pt_ch, tshzto(&pt->pt_time.it_value),
realtimerexpire, pt);
mutex_spin_exit(&timer_lock);
}
@ -1004,6 +995,7 @@ dogetitimer(struct proc *p, int which, struct itimerval *itvp)
{
struct ptimers *pts;
struct ptimer *pt;
struct itimerspec its;
if ((u_int)which > ITIMER_PROF)
return (EINVAL);
@ -1013,8 +1005,11 @@ dogetitimer(struct proc *p, int which, struct itimerval *itvp)
if (pts == NULL || (pt = pts->pts_timers[which]) == NULL) {
timerclear(&itvp->it_value);
timerclear(&itvp->it_interval);
} else
timer_gettime(pt, itvp);
} else {
TIMEVAL_TO_TIMESPEC(&itvp->it_value, &its.it_value);
TIMEVAL_TO_TIMESPEC(&itvp->it_interval, &its.it_interval);
timer_gettime(pt, &its);
}
mutex_spin_exit(&timer_lock);
return 0;
@ -1059,7 +1054,7 @@ sys_setitimer(struct lwp *l, const struct sys_setitimer_args *uap,
int
dosetitimer(struct proc *p, int which, struct itimerval *itvp)
{
struct timeval now;
struct timespec now;
struct ptimers *pts;
struct ptimer *pt, *spare;
@ -1113,13 +1108,15 @@ dosetitimer(struct proc *p, int which, struct itimerval *itvp)
}
pts->pts_timers[which] = pt;
}
pt->pt_time = *itvp;
if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) {
TIMEVAL_TO_TIMESPEC(&itvp->it_value, &pt->pt_time.it_value);
TIMEVAL_TO_TIMESPEC(&itvp->it_interval, &pt->pt_time.it_interval);
if ((which == ITIMER_REAL) && timespecisset(&pt->pt_time.it_value)) {
/* Convert to absolute time */
/* XXX need to wrap in splclock for timecounters case? */
getmicrotime(&now);
timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value);
getnanotime(&now);
timespecadd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value);
}
timer_settime(pt);
mutex_spin_exit(&timer_lock);
@ -1165,7 +1162,7 @@ timers_free(struct proc *p, int which)
{
struct ptimers *pts;
struct ptimer *ptn;
struct timeval tv;
struct timespec ts;
int i;
if (p->p_timers == NULL)
@ -1177,31 +1174,31 @@ timers_free(struct proc *p, int which)
p->p_timers = NULL;
i = 0;
} else {
timerclear(&tv);
timespecclear(&ts);
for (ptn = LIST_FIRST(&pts->pts_virtual);
ptn && ptn != pts->pts_timers[ITIMER_VIRTUAL];
ptn = LIST_NEXT(ptn, pt_list)) {
KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value, &tv);
timespecadd(&ts, &ptn->pt_time.it_value, &ts);
}
LIST_FIRST(&pts->pts_virtual) = NULL;
if (ptn) {
KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value,
timespecadd(&ts, &ptn->pt_time.it_value,
&ptn->pt_time.it_value);
LIST_INSERT_HEAD(&pts->pts_virtual, ptn, pt_list);
}
timerclear(&tv);
timespecclear(&ts);
for (ptn = LIST_FIRST(&pts->pts_prof);
ptn && ptn != pts->pts_timers[ITIMER_PROF];
ptn = LIST_NEXT(ptn, pt_list)) {
KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value, &tv);
timespecadd(&ts, &ptn->pt_time.it_value, &ts);
}
LIST_FIRST(&pts->pts_prof) = NULL;
if (ptn) {
KASSERT(ptn->pt_type != CLOCK_REALTIME);
timeradd(&tv, &ptn->pt_time.it_value,
timespecadd(&ts, &ptn->pt_time.it_value,
&ptn->pt_time.it_value);
LIST_INSERT_HEAD(&pts->pts_prof, ptn, pt_list);
}
@ -1254,36 +1251,37 @@ itimerfree(struct ptimers *pts, int index)
static int
itimerdecr(struct ptimer *pt, int usec)
{
struct itimerval *itp;
struct itimerspec *itp;
int nsec = usec * 1000;
KASSERT(mutex_owned(&timer_lock));
itp = &pt->pt_time;
if (itp->it_value.tv_usec < usec) {
if (itp->it_value.tv_nsec < nsec) {
if (itp->it_value.tv_sec == 0) {
/* expired, and already in next interval */
usec -= itp->it_value.tv_usec;
nsec -= itp->it_value.tv_nsec;
goto expire;
}
itp->it_value.tv_usec += 1000000;
itp->it_value.tv_nsec += 1000000000;
itp->it_value.tv_sec--;
}
itp->it_value.tv_usec -= usec;
itp->it_value.tv_nsec -= usec;
usec = 0;
if (timerisset(&itp->it_value))
if (timespecisset(&itp->it_value))
return (1);
/* expired, exactly at end of interval */
expire:
if (timerisset(&itp->it_interval)) {
if (timespecisset(&itp->it_interval)) {
itp->it_value = itp->it_interval;
itp->it_value.tv_usec -= usec;
if (itp->it_value.tv_usec < 0) {
itp->it_value.tv_usec += 1000000;
itp->it_value.tv_nsec -= nsec;
if (itp->it_value.tv_nsec < 0) {
itp->it_value.tv_nsec += 1000000000;
itp->it_value.tv_sec--;
}
timer_settime(pt);
} else
itp->it_value.tv_usec = 0; /* sec is already 0 */
itp->it_value.tv_nsec = 0; /* sec is already 0 */
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_time.c,v 1.3 2007/12/22 00:35:32 yamt Exp $ */
/* $NetBSD: subr_time.c,v 1.4 2008/07/15 16:18:08 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.3 2007/12/22 00:35:32 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.4 2008/07/15 16:18:08 christos Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_time.c,v 1.3 2007/12/22 00:35:32 yamt Exp $");
* argument to callout_reset() from an absolute time.
*/
int
hzto(struct timeval *tvp)
tvhzto(const struct timeval *tvp)
{
struct timeval now, tv;
@ -61,7 +61,7 @@ hzto(struct timeval *tvp)
* Compute number of ticks in the specified amount of time.
*/
int
tvtohz(struct timeval *tv)
tvtohz(const struct timeval *tv)
{
unsigned long ticks;
long sec, usec;
@ -97,7 +97,7 @@ tvtohz(struct timeval *tv)
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,
* This is different from the legacy tvhzto() interface,
* and callers need to check for it.
*/
ticks = 0;
@ -116,11 +116,21 @@ tvtohz(struct timeval *tv)
return ((int)ticks);
}
int
tshzto(const struct timespec *tsp)
{
struct timespec now, ts;
ts = *tsp; /* Don't modify original tsp. */
getnanotime(&now);
timespecsub(&ts, &now, &ts);
return tstohz(&ts);
}
/*
* Compute number of ticks in the specified amount of time.
*/
int
tstohz(struct timespec *ts)
tstohz(const struct timespec *ts)
{
struct timeval tv;

View File

@ -1,4 +1,4 @@
/* $NetBSD: param.h,v 1.325 2008/07/02 16:45:20 matt Exp $ */
/* $NetBSD: param.h,v 1.326 2008/07/15 16:18:08 christos Exp $ */
/*-
* Copyright (c) 1982, 1986, 1989, 1993
@ -63,7 +63,7 @@
* 2.99.9 (299000900)
*/
#define __NetBSD_Version__ 499006900 /* NetBSD 4.99.69 */
#define __NetBSD_Version__ 499007000 /* NetBSD 4.99.70 */
#define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
(m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

View File

@ -1,4 +1,4 @@
/* $NetBSD: time.h,v 1.61 2008/03/16 13:19:55 yamt Exp $ */
/* $NetBSD: time.h,v 1.62 2008/07/15 16:18:09 christos Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -221,6 +221,7 @@ timeval2bintime(const struct timeval *tv, struct bintime *bt)
(vsp)->tv_nsec += 1000000000L; \
} \
} while (/* CONSTCOND */ 0)
#define timespec2ns(x) (((uint64_t)(x)->tv_sec) * 1000000000L + (x)->tv_nsec)
#endif /* _NETBSD_SOURCE */
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: timevar.h,v 1.22 2008/04/29 06:53:03 martin Exp $ */
/* $NetBSD: timevar.h,v 1.23 2008/07/15 16:18:09 christos Exp $ */
/*
* Copyright (c) 2005, 2008 The NetBSD Foundation.
@ -77,7 +77,7 @@ struct ptimer {
} pt_nonreal;
} pt_data;
struct sigevent pt_ev;
struct itimerval pt_time;
struct itimerspec pt_time;
struct ksiginfo pt_info;
int pt_overruns; /* Overruns currently accumulating */
int pt_poverruns; /* Overruns associated w/ a delivery */
@ -152,7 +152,8 @@ int dosetitimer(struct proc *, int, struct itimerval *);
int dotimer_gettime(int, struct proc *, struct itimerspec *);
int dotimer_settime(int, struct itimerspec *, struct itimerspec *, int,
struct proc *);
int hzto(struct timeval *);
int tshzto(const struct timespec *);
int tvhzto(const struct timeval *);
void inittimecounter(void);
int itimerfix(struct timeval *);
int itimespecfix(struct timespec *);
@ -165,13 +166,13 @@ int settimeofday1(const struct timeval *, bool,
const void *, struct lwp *, bool);
int timer_create1(timer_t *, clockid_t, struct sigevent *, copyin_t,
struct lwp *);
void timer_gettime(struct ptimer *, struct itimerval *);
void timer_gettime(struct ptimer *, struct itimerspec *);
void timer_settime(struct ptimer *);
struct ptimers *timers_alloc(struct proc *);
void timers_free(struct proc *, int);
void timer_tick(struct lwp *, bool);
int tstohz(struct timespec *);
int tvtohz(struct timeval *);
int tstohz(const struct timespec *);
int tvtohz(const struct timeval *);
int inittimeleft(struct timeval *, struct timeval *);
int gettimeleft(struct timeval *, struct timeval *);
void timerupcall(struct lwp *);