summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorcheloha <cheloha@cvs.openbsd.org>2019-08-02 02:17:36 +0000
committercheloha <cheloha@cvs.openbsd.org>2019-08-02 02:17:36 +0000
commitea5f6879636efd4687cdaebb76b2f9c14196dac0 (patch)
tree975954ef233bcae390eb164ae81a1c7ced8563be /sys/kern
parenta7cabbf44ca93fb3c5dbacebc21533116d9f0f73 (diff)
per-process itimers: itimerval -> itimerspec
Loongson runs at 128hz. 128 doesn't divide evenly into a million, but it does divide evenly into a billion. So if we do the per-process itimer bookkeeping with itimerspec structs we can have error-free virtual itimers on loongson just as we do on most other platforms. This change doesn't fix the virtual itimer error alpha, as 1024 does not divide evenly into a billion. But this doesn't make the situation any worse, either. ok deraadt@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_clock.c10
-rw-r--r--sys/kern/kern_exec.c6
-rw-r--r--sys/kern/kern_time.c69
3 files changed, 43 insertions, 42 deletions
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index ee701945966..edaf8cdec61 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_clock.c,v 1.98 2019/01/28 11:49:04 mpi Exp $ */
+/* $OpenBSD: kern_clock.c,v 1.99 2019/08/02 02:17:35 cheloha Exp $ */
/* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */
/*-
@@ -153,13 +153,13 @@ hardclock(struct clockframe *frame)
* Run current process's virtual and profile time, as needed.
*/
if (CLKF_USERMODE(frame) &&
- timerisset(&pr->ps_timer[ITIMER_VIRTUAL].it_value) &&
- itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], tick) == 0) {
+ timespecisset(&pr->ps_timer[ITIMER_VIRTUAL].it_value) &&
+ itimerdecr(&pr->ps_timer[ITIMER_VIRTUAL], tick_nsec) == 0) {
atomic_setbits_int(&p->p_flag, P_ALRMPEND);
need_proftick(p);
}
- if (timerisset(&pr->ps_timer[ITIMER_PROF].it_value) &&
- itimerdecr(&pr->ps_timer[ITIMER_PROF], tick) == 0) {
+ if (timespecisset(&pr->ps_timer[ITIMER_PROF].it_value) &&
+ itimerdecr(&pr->ps_timer[ITIMER_PROF], tick_nsec) == 0) {
atomic_setbits_int(&p->p_flag, P_PROFPEND);
need_proftick(p);
}
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index dedbe6fc73d..9233cbcf5cf 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exec.c,v 1.207 2019/07/15 04:11:03 visa Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.208 2019/08/02 02:17:35 cheloha Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
@@ -654,8 +654,8 @@ sys_execve(struct proc *p, void *v, register_t *retval)
timeout_del(&pr->ps_realit_to);
for (i = 0; i < nitems(pr->ps_timer); i++) {
- timerclear(&pr->ps_timer[i].it_interval);
- timerclear(&pr->ps_timer[i].it_value);
+ timespecclear(&pr->ps_timer[i].it_interval);
+ timespecclear(&pr->ps_timer[i].it_value);
}
splx(s);
}
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 4648c830548..7e67d81bf51 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.121 2019/07/25 15:13:52 cheloha Exp $ */
+/* $OpenBSD: kern_time.c,v 1.122 2019/08/02 02:17:35 cheloha Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -507,18 +507,18 @@ sys_getitimer(struct proc *p, void *v, register_t *retval)
syscallarg(struct itimerval *) itv;
} */ *uap = v;
struct itimerval aitv;
+ struct itimerspec *itimer;
int which;
which = SCARG(uap, which);
if (which < ITIMER_REAL || which > ITIMER_PROF)
return (EINVAL);
+ itimer = &p->p_p->ps_timer[which];
memset(&aitv, 0, sizeof(aitv));
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;
+ TIMESPEC_TO_TIMEVAL(&aitv.it_interval, &itimer->it_interval);
+ TIMESPEC_TO_TIMEVAL(&aitv.it_value, &itimer->it_value);
mtx_leave(&itimer_mtx);
if (which == ITIMER_REAL) {
@@ -552,6 +552,7 @@ sys_setitimer(struct proc *p, void *v, register_t *retval)
syscallarg(struct itimerval *) oitv;
} */ *uap = v;
struct sys_getitimer_args getargs;
+ struct itimerspec aits;
struct itimerval aitv;
const struct itimerval *itvp;
struct itimerval *oitv;
@@ -579,21 +580,22 @@ sys_setitimer(struct proc *p, void *v, register_t *retval)
return (0);
if (itimerfix(&aitv.it_value) || itimerfix(&aitv.it_interval))
return (EINVAL);
+ TIMEVAL_TO_TIMESPEC(&aitv.it_value, &aits.it_value);
+ TIMEVAL_TO_TIMESPEC(&aitv.it_interval, &aits.it_interval);
if (which == ITIMER_REAL) {
- struct timeval ctv;
+ struct timespec cts;
timeout_del(&pr->ps_realit_to);
- getmicrouptime(&ctv);
- if (timerisset(&aitv.it_value)) {
- timo = tvtohz(&aitv.it_value);
+ getnanouptime(&cts);
+ if (timespecisset(&aits.it_value)) {
+ timo = tstohz(&aits.it_value);
timeout_add(&pr->ps_realit_to, timo);
- timeradd(&aitv.it_value, &ctv, &aitv.it_value);
+ timespecadd(&aits.it_value, &cts, &aits.it_value);
}
- pr->ps_timer[ITIMER_REAL] = aitv;
+ pr->ps_timer[ITIMER_REAL] = aits;
} else {
- itimerround(&aitv.it_interval);
mtx_enter(&itimer_mtx);
- pr->ps_timer[which] = aitv;
+ pr->ps_timer[which] = aits;
mtx_leave(&itimer_mtx);
}
@@ -612,23 +614,23 @@ void
realitexpire(void *arg)
{
struct process *pr = arg;
- struct itimerval *tp = &pr->ps_timer[ITIMER_REAL];
+ struct itimerspec *tp = &pr->ps_timer[ITIMER_REAL];
prsignal(pr, SIGALRM);
- if (!timerisset(&tp->it_interval)) {
- timerclear(&tp->it_value);
+ if (!timespecisset(&tp->it_interval)) {
+ timespecclear(&tp->it_value);
return;
}
for (;;) {
- struct timeval ctv, ntv;
+ struct timespec cts, nts;
int timo;
- timeradd(&tp->it_value, &tp->it_interval, &tp->it_value);
- getmicrouptime(&ctv);
- if (timercmp(&tp->it_value, &ctv, >)) {
- ntv = tp->it_value;
- timersub(&ntv, &ctv, &ntv);
- timo = tvtohz(&ntv) - 1;
+ timespecadd(&tp->it_value, &tp->it_interval, &tp->it_value);
+ getnanouptime(&cts);
+ if (timespeccmp(&tp->it_value, &cts, >)) {
+ nts = tp->it_value;
+ timespecsub(&nts, &cts, &nts);
+ timo = tstohz(&nts) - 1;
if (timo <= 0)
timo = 1;
if ((pr->ps_flags & PS_EXITING) == 0)
@@ -668,32 +670,31 @@ itimerround(struct timeval *tv)
}
/*
- * Decrement an interval timer by the given number of microseconds.
+ * Decrement an interval timer by the given number of nanoseconds.
* If the timer expires and it is periodic then reload it. When reloading
* the timer we subtract any overrun from the next period so that the timer
* does not drift.
*/
int
-itimerdecr(struct itimerval *itp, int usec)
+itimerdecr(struct itimerspec *itp, long nsec)
{
- struct timeval decrement;
+ struct timespec decrement;
- decrement.tv_sec = usec / 1000000;
- decrement.tv_usec = usec % 1000000;
+ NSEC_TO_TIMESPEC(nsec, &decrement);
mtx_enter(&itimer_mtx);
- timersub(&itp->it_value, &decrement, &itp->it_value);
- if (itp->it_value.tv_sec >= 0 && timerisset(&itp->it_value)) {
+ timespecsub(&itp->it_value, &decrement, &itp->it_value);
+ if (itp->it_value.tv_sec >= 0 && timespecisset(&itp->it_value)) {
mtx_leave(&itimer_mtx);
return (1);
}
- if (!timerisset(&itp->it_interval)) {
- timerclear(&itp->it_value);
+ if (!timespecisset(&itp->it_interval)) {
+ timespecclear(&itp->it_value);
mtx_leave(&itimer_mtx);
return (0);
}
- while (itp->it_value.tv_sec < 0 || !timerisset(&itp->it_value))
- timeradd(&itp->it_value, &itp->it_interval, &itp->it_value);
+ while (itp->it_value.tv_sec < 0 || !timespecisset(&itp->it_value))
+ timespecadd(&itp->it_value, &itp->it_interval, &itp->it_value);
mtx_leave(&itimer_mtx);
return (0);
}