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 */

Reply via email to