The consensus is now to switch syscall doing sleeps to use tsleep_nsec(9).
Our direct goal is to stop expressing time as ticks, more might come
later.
Diff below introduces the previously discussed TIMESPEC_TO_NSEC(9) macro
and makes use of it in 3 syscalls.
Comments? Oks?
Index: kern/kern_sig.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.240
diff -u -p -r1.240 kern_sig.c
--- kern/kern_sig.c 8 Jan 2020 16:27:41 -0000 1.240
+++ kern/kern_sig.c 12 Jan 2020 12:36:40 -0000
@@ -1699,7 +1699,7 @@ sys___thrsigdivert(struct proc *p, void
sigset_t *m;
sigset_t mask = SCARG(uap, sigmask) &~ sigcantmask;
siginfo_t si;
- uint64_t to_ticks = 0;
+ uint64_t nsecs = INFSLP;
int timeinvalid = 0;
int error = 0;
@@ -1715,14 +1715,8 @@ sys___thrsigdivert(struct proc *p, void
#endif
if (!timespecisvalid(&ts))
timeinvalid = 1;
- else {
- to_ticks = (uint64_t)hz * ts.tv_sec +
- ts.tv_nsec / (tick * 1000);
- if (to_ticks > INT_MAX)
- to_ticks = INT_MAX;
- if (to_ticks == 0 && ts.tv_nsec)
- to_ticks = 1;
- }
+ else
+ nsecs = TIMESPEC_TO_NSEC(&ts);
}
dosigsuspend(p, p->p_sigmask &~ mask);
@@ -1749,14 +1743,14 @@ sys___thrsigdivert(struct proc *p, void
if (timeinvalid)
error = EINVAL;
- if (SCARG(uap, timeout) != NULL && to_ticks == 0)
+ if (SCARG(uap, timeout) != NULL && nsecs == INFSLP)
error = EAGAIN;
if (error != 0)
break;
- error = tsleep(&sigwaitsleep, PPAUSE|PCATCH, "sigwait",
- (int)to_ticks);
+ error = tsleep_nsec(&sigwaitsleep, PPAUSE|PCATCH, "sigwait",
+ nsecs);
}
if (error == 0) {
Index: kern/sys_futex.c
===================================================================
RCS file: /cvs/src/sys/kern/sys_futex.c,v
retrieving revision 1.13
diff -u -p -r1.13 sys_futex.c
--- kern/sys_futex.c 10 Jul 2019 15:52:17 -0000 1.13
+++ kern/sys_futex.c 31 Dec 2019 10:19:49 -0000
@@ -213,7 +213,7 @@ futex_wait(uint32_t *uaddr, uint32_t val
{
struct proc *p = curproc;
struct futex *f;
- uint64_t to_ticks = 0;
+ uint64_t nsecs = INFSLP;
uint32_t cval;
int error;
@@ -244,17 +244,14 @@ futex_wait(uint32_t *uaddr, uint32_t val
#endif
if (ts.tv_sec < 0 || !timespecisvalid(&ts))
return EINVAL;
- to_ticks = (uint64_t)hz * ts.tv_sec +
- (ts.tv_nsec + tick * 1000 - 1) / (tick * 1000) + 1;
- if (to_ticks > INT_MAX)
- to_ticks = INT_MAX;
+ nsecs = TIMESPEC_TO_NSEC(&ts);
}
f = futex_get(uaddr, flags | FT_CREATE);
TAILQ_INSERT_TAIL(&f->ft_threads, p, p_fut_link);
p->p_futex = f;
- error = rwsleep(p, &ftlock, PWAIT|PCATCH, "fsleep", (int)to_ticks);
+ error = rwsleep_nsec(p, &ftlock, PWAIT|PCATCH, "fsleep", nsecs);
if (error == ERESTART)
error = ECANCELED;
else if (error == EWOULDBLOCK) {
Index: kern/kern_synch.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.156
diff -u -p -r1.156 kern_synch.c
--- kern/kern_synch.c 12 Jan 2020 00:01:12 -0000 1.156
+++ kern/kern_synch.c 12 Jan 2020 11:42:20 -0000
@@ -641,7 +641,7 @@ thrsleep(struct proc *p, struct sys___th
long ident = (long)SCARG(uap, ident);
struct timespec *tsp = (struct timespec *)SCARG(uap, tp);
void *lock = SCARG(uap, lock);
- uint64_t to_ticks = 0;
+ uint64_t nsecs = INFSLP;
int abort, error;
clockid_t clock_id = SCARG(uap, clock_id);
@@ -665,10 +665,7 @@ thrsleep(struct proc *p, struct sys___th
}
timespecsub(tsp, &now, tsp);
- to_ticks = (uint64_t)hz * tsp->tv_sec +
- (tsp->tv_nsec + tick * 1000 - 1) / (tick * 1000) + 1;
- if (to_ticks > INT_MAX)
- to_ticks = INT_MAX;
+ nsecs = TIMESPEC_TO_NSEC(tsp);
}
p->p_thrslpid = ident;
@@ -692,8 +689,7 @@ thrsleep(struct proc *p, struct sys___th
void *sleepaddr = &p->p_thrslpid;
if (ident == -1)
sleepaddr = &globalsleepaddr;
- error = tsleep(sleepaddr, PWAIT|PCATCH, "thrsleep",
- (int)to_ticks);
+ error = tsleep_nsec(sleepaddr, PWAIT|PCATCH, "thrsleep", nsecs);
}
out:
Index: sys/time.h
===================================================================
RCS file: /cvs/src/sys/sys/time.h,v
retrieving revision 1.48
diff -u -p -r1.48 time.h
--- sys/time.h 1 Jan 2020 14:09:59 -0000 1.48
+++ sys/time.h 12 Jan 2020 12:21:33 -0000
@@ -370,6 +383,14 @@ USEC_TO_NSEC(uint64_t microseconds)
if (microseconds > UINT64_MAX / 1000ULL)
return UINT64_MAX;
return microseconds * 1000ULL;
+}
+
+static inline uint64_t
+TIMESPEC_TO_NSEC(const struct timespec *ts)
+{
+ if (ts->tv_sec > (UINT64_MAX - ts->tv_nsec) / 1000000000ULL)
+ return UINT64_MAX;
+ return ts->tv_sec * 1000000000ULL + ts->tv_nsec;
}
#else /* !_KERNEL */