Author: davidxu
Date: Sat Aug 11 00:06:56 2012
New Revision: 239187
URL: http://svn.freebsd.org/changeset/base/239187

Log:
  tvtohz will print out an error message if a negative value is given
  to it, avoid this problem by detecting timeout earlier.
  
  Reported by: pho

Modified:
  head/sys/kern/kern_umtx.c

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c   Fri Aug 10 21:11:00 2012        (r239186)
+++ head/sys/kern/kern_umtx.c   Sat Aug 11 00:06:56 2012        (r239187)
@@ -587,11 +587,10 @@ abs_timeout_init2(struct abs_timeout *ti
                &umtxtime->_timeout);
 }
 
-static int
+static void
 abs_timeout_update(struct abs_timeout *timo)
 {
        kern_clock_gettime(curthread, timo->clockid, &timo->cur);
-       return (timespeccmp(&timo->cur, &timo->end, >=));
 }
 
 static int
@@ -601,6 +600,8 @@ abs_timeout_gethz(struct abs_timeout *ti
 
        tts = timo->end;
        timespecsub(&tts, &timo->cur);
+       if (tts.tv_sec < 0 || (tts.tv_sec == 0 && tts.tv_nsec == 0))
+               return (-1);
        return (tstohz(&tts));
 }
 
@@ -613,22 +614,25 @@ umtxq_sleep(struct umtx_q *uq, const cha
 {
        struct umtxq_chain *uc;
        int error;
+       int pulse;
 
        uc = umtxq_getchain(&uq->uq_key);
        UMTXQ_LOCKED_ASSERT(uc);
        for (;;) {
                if (!(uq->uq_flags & UQF_UMTXQ))
                        return (0);
-               error = msleep(uq, &uc->uc_lock, PCATCH, wmesg,
-                   timo == NULL ? 0 : abs_timeout_gethz(timo));
-               if (error != EWOULDBLOCK)
-                       break;
-               umtxq_unlock(&uq->uq_key);
-               if (abs_timeout_update(timo)) {
-                       error = ETIMEDOUT;
+               if (timo != NULL) {
+                       pulse = abs_timeout_gethz(timo);
+                       if (pulse < 0)
+                               return (ETIMEDOUT);
+               } else
+                       pulse = 0;
+               error = msleep(uq, &uc->uc_lock, PCATCH|PDROP, wmesg, pulse);
+               if (error != EWOULDBLOCK) {
                        umtxq_lock(&uq->uq_key);
                        break;
                }
+               abs_timeout_update(timo);
                umtxq_lock(&uq->uq_key);
        }
        return (error);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to