Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Aug 2012 00:06:56 +0000 (UTC)
From:      David Xu <davidxu@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r239187 - head/sys/kern
Message-ID:  <201208110006.q7B06uPR092724@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208110006.q7B06uPR092724>