diff --git a/sys/kern/subr_time.c b/sys/kern/subr_time.c index 8a2815fcdb43..9e657be37caf 100644 --- a/sys/kern/subr_time.c +++ b/sys/kern/subr_time.c @@ -207,6 +207,7 @@ inittimeleft(struct timespec *ts, struct timespec *sleepts) if (itimespecfix(ts)) { return -1; } + KASSERT(ts->tv_sec >= 0); getnanouptime(sleepts); return 0; } @@ -214,15 +215,23 @@ inittimeleft(struct timespec *ts, struct timespec *sleepts) int gettimeleft(struct timespec *ts, struct timespec *sleepts) { - struct timespec sleptts; + struct timespec now, sleptts; + + KASSERT(ts->tv_sec >= 0); /* * Reduce ts by elapsed time based on monotonic time scale. */ - getnanouptime(&sleptts); - timespecadd(ts, sleepts, ts); + getnanouptime(&now); + KASSERT(timespeccmp(sleepts, &now, <=)); + timespecsub(&now, sleepts, &sleptts); + *sleepts = now; + + if (timespeccmp(ts, &sleptts, <=)) { /* timed out */ + timespecclear(ts); + return 0; + } timespecsub(ts, &sleptts, ts); - *sleepts = sleptts; return tstohz(ts); }