svn commit: r239187 - head/sys/kern

David Xu davidxu at FreeBSD.org
Sat Aug 11 00:06:57 UTC 2012


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);


More information about the svn-src-all mailing list