]> granicus.if.org Git - zfs/commitdiff
Fix cv_timedwait_hires
authorBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 25 Aug 2016 20:24:01 +0000 (20:24 +0000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 29 Aug 2016 17:54:14 +0000 (10:54 -0700)
The user space implementation of cv_timedwait_hires() was always passing
a relative time to pthread_cond_timedwait() when an absolute time is
expected.  This was accidentally introduced in commit 206971d2.

Replace two magic values with their corresponding preprocessor macro.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <ryao@gentoo.org>
Closes #5024

lib/libzpool/kernel.c

index 549dd4c5c21e074d1fb0e5ba448e2da1eab6c468..7ac505a64b915f5b808b2e5539153c143c1ddbad 100644 (file)
@@ -509,7 +509,7 @@ cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
        VERIFY(gettimeofday(&tv, NULL) == 0);
 
        ts.tv_sec = tv.tv_sec + delta / hz;
-       ts.tv_nsec = tv.tv_usec * 1000 + (delta % hz) * (NANOSEC / hz);
+       ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % hz) * (NANOSEC / hz);
        if (ts.tv_nsec >= NANOSEC) {
                ts.tv_sec++;
                ts.tv_nsec -= NANOSEC;
@@ -534,6 +534,7 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
     int flag)
 {
        int error;
+       struct timeval tv;
        timestruc_t ts;
        hrtime_t delta;
 
@@ -546,11 +547,17 @@ cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
        if (delta <= 0)
                return (-1);
 
-       ts.tv_sec = delta / NANOSEC;
-       ts.tv_nsec = delta % NANOSEC;
+       VERIFY(gettimeofday(&tv, NULL) == 0);
+
+       ts.tv_sec = tv.tv_sec + delta / NANOSEC;
+       ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC + (delta % NANOSEC);
+       if (ts.tv_nsec >= NANOSEC) {
+               ts.tv_sec++;
+               ts.tv_nsec -= NANOSEC;
+       }
 
        ASSERT(mutex_owner(mp) == curthread);
-       mp->m_owner = NULL;
+       mp->m_owner = MTX_INIT;
        error = pthread_cond_timedwait(&cv->cv, &mp->m_lock, &ts);
        mp->m_owner = curthread;