summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_time.c
diff options
context:
space:
mode:
authorcheloha <cheloha@openbsd.org>2018-12-31 18:54:00 +0000
committercheloha <cheloha@openbsd.org>2018-12-31 18:54:00 +0000
commit353098857730fce409d995974ae8d26b78f379fa (patch)
tree2d3c327731179bc94d9f8d69b47f2ce415b76821 /sys/kern/kern_time.c
parentImplement fractional PLL frequencies for RK3328 and use them for APLL and (diff)
downloadwireguard-openbsd-353098857730fce409d995974ae8d26b78f379fa.tar.xz
wireguard-openbsd-353098857730fce409d995974ae8d26b78f379fa.zip
nanosleep: loop tsleep(9) to ensure coverage of the full timeout range.
tsleep(9)'s maximum timeout shrinks as HZ grows, so this ensures we do not return early from longer timeouts on alpha or on custom kernels. POSIX says you cannot return early unless a signal is delivered, so this makes us more compliant with the standard. While here, remove the 100 million second upper bound. It is an artifact from itimerfix() and it serves no discernible purpose. ok tedu@ visa@
Diffstat (limited to 'sys/kern/kern_time.c')
-rw-r--r--sys/kern/kern_time.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index c9e54fb141b..1e40e8ccd84 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.104 2018/12/29 19:02:30 cheloha Exp $ */
+/* $OpenBSD: kern_time.c,v 1.105 2018/12/31 18:54:00 cheloha Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -281,26 +281,29 @@ sys_nanosleep(struct proc *p, void *v, register_t *retval)
}
#endif
- if (request.tv_sec > 100000000 || timespecfix(&request))
+ if (request.tv_sec < 0 || request.tv_nsec < 0 ||
+ request.tv_nsec >= 1000000000)
return (EINVAL);
- if (rmtp)
+ do {
getnanouptime(&start);
+ error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep",
+ MAX(1, tstohz(&request)));
+ getnanouptime(&stop);
+ timespecsub(&stop, &start, &elapsed);
+ timespecsub(&request, &elapsed, &request);
+ if (error != EWOULDBLOCK)
+ break;
+ } while (request.tv_sec >= 0 && timespecisset(&request));
- error = tsleep(&nanowait, PWAIT | PCATCH, "nanosleep",
- MAX(1, tstohz(&request)));
if (error == ERESTART)
error = EINTR;
if (error == EWOULDBLOCK)
error = 0;
if (rmtp) {
- getnanouptime(&stop);
-
memset(&remainder, 0, sizeof(remainder));
- timespecsub(&stop, &start, &elapsed);
- timespecsub(&request, &elapsed, &remainder);
-
+ remainder = request;
if (remainder.tv_sec < 0)
timespecclear(&remainder);