fix for calcru() on running non-current threads

From: Bruce Evans <bde_at_zeta.org.au>
Date: Thu, 24 Jun 2004 20:12:07 +1000 (EST)
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
_at__at_ -48,4 +48,5 _at__at_
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/pcpu.h>
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
_at__at_ -707,5 +708,5 _at__at_
 	/* {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);
_at__at_ -722,27 +723,20 _at__at_
 	}
 	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);
 		}
 	}
_at__at_ -751,8 +745,7 _at__at_
 	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
Received on Thu Jun 24 2004 - 08:12:16 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:58 UTC