From 08fd92bac5e0de8b8378b6fda2171f61a9a20b81 Mon Sep 17 00:00:00 2001 From: cube Date: Mon, 11 Jul 2005 19:50:42 +0000 Subject: [PATCH] Split sys_getitimer and sys_setitimer to make it possible to share the relevant code with the COMPAT_NETBSD32 version, and make the latter use the new functions. This fixes netbsd32_setitimer() which had drifted from the native syscall and did not work properly anymore. --- sys/compat/netbsd32/netbsd32_time.c | 110 +++++----------------------- sys/kern/kern_time.c | 47 ++++++++---- sys/sys/time.h | 5 +- 3 files changed, 53 insertions(+), 109 deletions(-) diff --git a/sys/compat/netbsd32/netbsd32_time.c b/sys/compat/netbsd32/netbsd32_time.c index d9640ce315bf..dc6a5e3034a2 100644 --- a/sys/compat/netbsd32/netbsd32_time.c +++ b/sys/compat/netbsd32/netbsd32_time.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_time.c,v 1.9 2005/05/31 00:41:09 christos Exp $ */ +/* $NetBSD: netbsd32_time.c,v 1.10 2005/07/11 19:50:42 cube Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -29,7 +29,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.9 2005/05/31 00:41:09 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.10 2005/07/11 19:50:42 cube Exp $"); #if defined(_KERNEL_OPT) #include "opt_ntp.h" @@ -286,81 +286,30 @@ netbsd32_setitimer(l, v, retval) syscallarg(netbsd32_itimervalp_t) oitv; } */ *uap = v; struct proc *p = l->l_proc; - struct netbsd32_itimerval s32it, *itvp; + struct netbsd32_itimerval s32it, *itv32; int which = SCARG(uap, which); struct netbsd32_getitimer_args getargs; struct itimerval aitv; - int s, error; - struct ptimer *pt; + int error; if ((u_int)which > ITIMER_PROF) return (EINVAL); - itvp = (struct netbsd32_itimerval *)NETBSD32PTR64(SCARG(uap, itv)); - if (itvp && (error = copyin(itvp, &s32it, sizeof(s32it)))) - return (error); - netbsd32_to_itimerval(&s32it, &aitv); + itv32 = (struct netbsd32_itimerval *)NETBSD32PTR64(SCARG(uap, itv)); + if (itv32) { + if ((error = copyin(itv32, &s32it, sizeof(s32it)))) + return (error); + netbsd32_to_itimerval(&s32it, &aitv); + } if (SCARG(uap, oitv) != 0) { SCARG(&getargs, which) = which; SCARG(&getargs, itv) = SCARG(uap, oitv); if ((error = netbsd32_getitimer(l, &getargs, retval)) != 0) return (error); } - if (itvp == 0) - return (0); - if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) - return (EINVAL); + if (itv32 == 0) + return 0; -/* XXX there should be a way to share code with kern_time */ -/* XXX just copied some from there */ - /* - * Don't bother allocating data structures if the process just - * wants to clear the timer. - */ - if (!timerisset(&aitv.it_value) && - ((p->p_timers == NULL) || (p->p_timers->pts_timers[which] == NULL))) - return (0); - - if (p->p_timers == NULL) - timers_alloc(p); - if (p->p_timers->pts_timers[which] == NULL) { - pt = pool_get(&ptimer_pool, PR_WAITOK); - callout_init(&pt->pt_ch); - pt->pt_ev.sigev_notify = SIGEV_SIGNAL; - pt->pt_overruns = 0; - pt->pt_proc = p; - pt->pt_type = which; - switch (which) { - case ITIMER_REAL: - pt->pt_ev.sigev_signo = SIGALRM; - break; - case ITIMER_VIRTUAL: - pt->pt_ev.sigev_signo = SIGVTALRM; - break; - case ITIMER_PROF: - pt->pt_ev.sigev_signo = SIGPROF; - break; - } - } else - pt = p->p_timers->pts_timers[which]; - - pt->pt_time = aitv; - p->p_timers->pts_timers[which] = pt; - if (which == ITIMER_REAL) { - s = splclock(); - callout_stop(&pt->pt_ch); - if (timerisset(&pt->pt_time.it_value)) { - timeradd(&pt->pt_time.it_value, &time, - &pt->pt_time.it_value); - /* - * Don't need to check hzto() return value, here. - * callout_reset() does it for us. - */ - callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), - realtimerexpire, pt); - } - splx(s); - } - return (0); + return dosetitimer(p, which, &aitv); } int @@ -374,39 +323,14 @@ netbsd32_getitimer(l, v, retval) syscallarg(netbsd32_itimervalp_t) itv; } */ *uap = v; struct proc *p = l->l_proc; - int which = SCARG(uap, which); struct netbsd32_itimerval s32it; struct itimerval aitv; - int s; + int error; - if ((u_int)which > ITIMER_PROF) - return (EINVAL); + error = dogetitimer(p, SCARG(uap, which), &aitv); + if (error) + return error; -/* XXX same as setitimer */ - if ((p->p_timers == NULL) || (p->p_timers->pts_timers[which] == NULL)) { - timerclear(&aitv.it_value); - timerclear(&aitv.it_interval); - } else { - s = splclock(); - if (which == ITIMER_REAL) { - /* - * Convert from absolute to relative time in - * .it_value part of real time timer. If time - * for real time timer has passed return 0, - * else return difference between current time - * and time for the timer to go off. - */ - aitv = p->p_timers->pts_timers[ITIMER_REAL]->pt_time; - if (timerisset(&aitv.it_value)) { - if (timercmp(&aitv.it_value, &time, <)) - timerclear(&aitv.it_value); - else - timersub(&aitv.it_value, &time, &aitv.it_value); - } - } else - aitv = p->p_timers->pts_timers[which]->pt_time; - splx(s); - } netbsd32_from_itimerval(&aitv, &s32it); return (copyout(&s32it, (caddr_t)NETBSD32PTR64(SCARG(uap, itv)), sizeof(s32it))); diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 9a5992501cb6..7987600c0a37 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $NetBSD: kern_time.c,v 1.90 2005/06/23 23:15:12 thorpej Exp $ */ +/* $NetBSD: kern_time.c,v 1.91 2005/07/11 19:50:42 cube Exp $ */ /*- * Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.90 2005/06/23 23:15:12 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_time.c,v 1.91 2005/07/11 19:50:42 cube Exp $"); #include "fs_nfs.h" #include "opt_nfs.h" @@ -936,24 +936,32 @@ sys_getitimer(struct lwp *l, void *v, register_t *retval) } */ *uap = v; struct proc *p = l->l_proc; struct itimerval aitv; - int s, which; + int error; - which = SCARG(uap, which); + error = dogetitimer(p, SCARG(uap, which), &aitv); + if (error) + return error; + return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval))); +} + +int +dogetitimer(struct proc *p, int which, struct itimerval *itvp) +{ + int s; if ((u_int)which > ITIMER_PROF) return (EINVAL); if ((p->p_timers == NULL) || (p->p_timers->pts_timers[which] == NULL)){ - timerclear(&aitv.it_value); - timerclear(&aitv.it_interval); + timerclear(&itvp->it_value); + timerclear(&itvp->it_interval); } else { s = splclock(); - timer_gettime(p->p_timers->pts_timers[which], &aitv); + timer_gettime(p->p_timers->pts_timers[which], itvp); splx(s); } - return (copyout(&aitv, SCARG(uap, itv), sizeof(struct itimerval))); - + return 0; } /* BSD routine to set/arm an interval timer. */ @@ -969,10 +977,9 @@ sys_setitimer(struct lwp *l, void *v, register_t *retval) struct proc *p = l->l_proc; int which = SCARG(uap, which); struct sys_getitimer_args getargs; - struct itimerval aitv; const struct itimerval *itvp; - struct ptimer *pt; - int s, error; + struct itimerval aitv; + int error; if ((u_int)which > ITIMER_PROF) return (EINVAL); @@ -988,14 +995,24 @@ sys_setitimer(struct lwp *l, void *v, register_t *retval) } if (itvp == 0) return (0); - if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval)) + + return dosetitimer(p, which, &aitv); +} + +int +dosetitimer(struct proc *p, int which, struct itimerval *itvp) +{ + struct ptimer *pt; + int s; + + if (itimerfix(&itvp->it_value) || itimerfix(&itvp->it_interval)) return (EINVAL); /* * Don't bother allocating data structures if the process just * wants to clear the timer. */ - if (!timerisset(&aitv.it_value) && + if (!timerisset(&itvp->it_value) && ((p->p_timers == NULL) ||(p->p_timers->pts_timers[which] == NULL))) return (0); @@ -1026,7 +1043,7 @@ sys_setitimer(struct lwp *l, void *v, register_t *retval) } else pt = p->p_timers->pts_timers[which]; - pt->pt_time = aitv; + pt->pt_time = *itvp; p->p_timers->pts_timers[which] = pt; s = splclock(); diff --git a/sys/sys/time.h b/sys/sys/time.h index e254a25d26a5..96093dca85b8 100644 --- a/sys/sys/time.h +++ b/sys/sys/time.h @@ -1,4 +1,4 @@ -/* $NetBSD: time.h,v 1.46 2005/03/17 20:51:00 kleink Exp $ */ +/* $NetBSD: time.h,v 1.47 2005/07/11 19:50:42 cube Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -225,6 +225,9 @@ void timer_gettime(struct ptimer *, struct itimerval *); void timers_alloc(struct proc *); void timers_free(struct proc *, int); void realtimerexpire(void *); + +int dogetitimer(struct proc *, int, struct itimerval *); +int dosetitimer(struct proc *, int, struct itimerval *); #else /* !_KERNEL */ #ifndef _STANDALONE