Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Jun 2004 20:12:07 +1000 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        current@freebsd.org
Subject:   fix for calcru() on running non-current threads
Message-ID:  <20040624201018.L41701@gamplex.bde.org>

next in thread | raw e-mail | index | archive | help
Accessing switchtime for other CPUs turned out to be easy.

Please test and review.  (Tests should show no difference for the non-SMP
case.)

%%%
Index: kern_resource.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.140
diff -u -2 -r1.140 kern_resource.c
--- kern_resource.c	21 Jun 2004 17:46:27 -0000	1.140
+++ kern_resource.c	24 Jun 2004 07:31:05 -0000
@@ -48,4 +48,5 @@
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
@@ -707,5 +708,5 @@
 	/* {user, system, interrupt, total} {ticks, usec}; previous tu: */
 	u_int64_t ut, uu, st, su, it, iu, tt, tu, ptu;
-	int problemcase;
+	int bt_valid;

 	mtx_assert(&sched_lock, MA_OWNED);
@@ -722,27 +723,20 @@
 	}
 	rt = p->p_runtime;
-	problemcase = 0;
+	bt_valid = 0;
 	FOREACH_THREAD_IN_PROC(p, td) {
-		/*
-		 * Adjust for the current time slice.  This is actually fairly
-		 * important since the error here is on the order of a time
-		 * quantum, which is much greater than the sampling error.
-		 */
-		if (td == curthread) {
-			binuptime(&bt);
-			bintime_sub(&bt, PCPU_PTR(switchtime));
-			bintime_add(&rt, &bt);
-		} else if (TD_IS_RUNNING(td)) {
+		if (TD_IS_RUNNING(td)) {
 			/*
-			 * XXX: this case should add the difference between
-			 * the current time and the switch time as above,
-			 * but the switch time is inaccessible, so we can't
-			 * do the adjustment and will end up with a wrong
-			 * runtime.  A previous call with a different
-			 * curthread may have obtained a (right or wrong)
-			 * runtime that is in advance of ours.  Just set a
-			 * flag to avoid warning about this known problem.
+			 * Adjust for the current time slice.  This is
+			 * important since the adjustment is on the order
+			 * of a time quantum, which is much greater than
+			 * precision of binuptime().
 			 */
-			problemcase = 1;
+			if (!bt_valid) {
+				binuptime(&bt);
+				bt_valid = 1;
+			}
+			bintime_add(&rt, &bt);
+			bintime_sub(&rt,
+			    &pcpu_find(td->td_oncpu)->pc_switchtime);
 		}
 	}
@@ -751,8 +745,7 @@
 	ptu = p->p_uu + p->p_su + p->p_iu;
 	if (tu < ptu) {
-		if (!problemcase)
-			printf(
+		printf(
 "calcru: runtime went backwards from %ju usec to %ju usec for pid %d (%s)\n",
-			    (uintmax_t)ptu, (uintmax_t)tu, p->p_pid, p->p_comm);
+		    (uintmax_t)ptu, (uintmax_t)tu, p->p_pid, p->p_comm);
 		tu = ptu;
 	}
%%%

Bruce



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