-/* $OpenBSD: kern_time.c,v 1.89 2014/12/07 02:58:14 deraadt Exp $ */
+/* $OpenBSD: kern_time.c,v 1.90 2015/04/28 20:54:18 kettenis Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
}
+struct mutex itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK);
+
/*
* Get value of an interval timer. The process virtual and
* profiling virtual time timers are kept internally in the
syscallarg(struct itimerval *) itv;
} */ *uap = v;
struct itimerval aitv;
- int s;
int which;
which = SCARG(uap, which);
if (which < ITIMER_REAL || which > ITIMER_PROF)
return (EINVAL);
memset(&aitv, 0, sizeof(aitv));
- s = splclock();
+ mtx_enter(&itimer_mtx);
aitv.it_interval.tv_sec = p->p_p->ps_timer[which].it_interval.tv_sec;
aitv.it_interval.tv_usec = p->p_p->ps_timer[which].it_interval.tv_usec;
aitv.it_value.tv_sec = p->p_p->ps_timer[which].it_value.tv_sec;
aitv.it_value.tv_usec = p->p_p->ps_timer[which].it_value.tv_usec;
+ mtx_leave(&itimer_mtx);
if (which == ITIMER_REAL) {
struct timeval now;
&aitv.it_value);
}
}
- splx(s);
+
return (copyout(&aitv, SCARG(uap, itv), sizeof (struct itimerval)));
}
}
pr->ps_timer[ITIMER_REAL] = aitv;
} else {
- int s;
-
itimerround(&aitv.it_interval);
- s = splclock();
+ mtx_enter(&itimer_mtx);
pr->ps_timer[which] = aitv;
- splx(s);
+ mtx_leave(&itimer_mtx);
}
return (0);
int
itimerdecr(struct itimerval *itp, int usec)
{
-
+ mtx_enter(&itimer_mtx);
if (itp->it_value.tv_usec < usec) {
if (itp->it_value.tv_sec == 0) {
/* expired, and already in next interval */
}
itp->it_value.tv_usec -= usec;
usec = 0;
- if (timerisset(&itp->it_value))
+ if (timerisset(&itp->it_value)) {
+ mtx_leave(&itimer_mtx);
return (1);
+ }
/* expired, exactly at end of interval */
expire:
if (timerisset(&itp->it_interval)) {
}
} else
itp->it_value.tv_usec = 0; /* sec is already 0 */
+ mtx_leave(&itimer_mtx);
return (0);
}