Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2011 17:33:08 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r224188 - in head: sys/kern sys/sys usr.bin/top
Message-ID:  <201107181733.p6IHX8kx032272@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Mon Jul 18 17:33:08 2011
New Revision: 224188
URL: http://svn.freebsd.org/changeset/base/224188

Log:
  - Export each thread's individual resource usage in in struct kinfo_proc's
    ki_rusage member when KERN_PROC_INC_THREAD is passed to one of the
    process sysctls.
  - Correctly account for the current thread's cputime in the thread when
    doing the runtime fixup in calcru().
  - Use TIDs as the key to lookup the previous thread to compute IO stat
    deltas in IO mode in top when thread display is enabled.
  
  Reviewed by:	kib
  Approved by:	re (kib)

Modified:
  head/sys/kern/kern_proc.c
  head/sys/kern/kern_resource.c
  head/sys/sys/resourcevar.h
  head/usr.bin/top/machine.c

Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c	Mon Jul 18 15:19:40 2011	(r224187)
+++ head/sys/kern/kern_proc.c	Mon Jul 18 17:33:08 2011	(r224188)
@@ -848,6 +848,8 @@ fill_kinfo_thread(struct thread *td, str
 	kp->ki_tdaddr = td;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 
+	if (preferthread)
+		PROC_SLOCK(p);
 	thread_lock(td);
 	if (td->td_wmesg != NULL)
 		strlcpy(kp->ki_wmesg, td->td_wmesg, sizeof(kp->ki_wmesg));
@@ -899,6 +901,7 @@ fill_kinfo_thread(struct thread *td, str
 	kp->ki_pri.pri_user = td->td_user_pri;
 
 	if (preferthread) {
+		rufetchtd(td, &kp->ki_rusage);
 		kp->ki_runtime = cputick2usec(td->td_rux.rux_runtime);
 		kp->ki_pctcpu = sched_pctcpu(td);
 		kp->ki_estcpu = td->td_estcpu;
@@ -911,6 +914,8 @@ fill_kinfo_thread(struct thread *td, str
 		kp->ki_siglist = td->td_siglist;
 	kp->ki_sigmask = td->td_sigmask;
 	thread_unlock(td);
+	if (preferthread)
+		PROC_SUNLOCK(p);
 }
 
 /*

Modified: head/sys/kern/kern_resource.c
==============================================================================
--- head/sys/kern/kern_resource.c	Mon Jul 18 15:19:40 2011	(r224187)
+++ head/sys/kern/kern_resource.c	Mon Jul 18 17:33:08 2011	(r224188)
@@ -813,7 +813,7 @@ void
 calcru(struct proc *p, struct timeval *up, struct timeval *sp)
 {
 	struct thread *td;
-	uint64_t u;
+	uint64_t runtime, u;
 
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	PROC_SLOCK_ASSERT(p, MA_OWNED);
@@ -826,7 +826,9 @@ calcru(struct proc *p, struct timeval *u
 	td = curthread;
 	if (td->td_proc == p) {
 		u = cpu_ticks();
-		p->p_rux.rux_runtime += u - PCPU_GET(switchtime);
+		runtime = u - PCPU_GET(switchtime);
+		td->td_runtime += runtime;
+		td->td_incruntime += runtime;
 		PCPU_SET(switchtime, u);
 	}
 	/* Make sure the per-thread stats are current. */
@@ -838,6 +840,34 @@ calcru(struct proc *p, struct timeval *u
 	calcru1(p, &p->p_rux, up, sp);
 }
 
+/* Collect resource usage for a single thread. */
+void
+rufetchtd(struct thread *td, struct rusage *ru)
+{
+	struct proc *p;
+	uint64_t runtime, u;
+
+	p = td->td_proc;
+	PROC_SLOCK_ASSERT(p, MA_OWNED);
+	THREAD_LOCK_ASSERT(td, MA_OWNED);
+	/*
+	 * If we are getting stats for the current thread, then add in the
+	 * stats that this thread has accumulated in its current time slice.
+	 * We reset the thread and CPU state as if we had performed a context
+	 * switch right here.
+	 */
+	if (td == curthread) {
+		u = cpu_ticks();
+		runtime = u - PCPU_GET(switchtime);
+		td->td_runtime += runtime;
+		td->td_incruntime += runtime;
+		PCPU_SET(switchtime, u);
+	}
+	ruxagg(p, td);
+	*ru = td->td_ru;
+	calcru1(p, &td->td_rux, &ru->ru_utime, &ru->ru_stime);
+}
+
 static void
 calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up,
     struct timeval *sp)
@@ -955,12 +985,10 @@ kern_getrusage(struct thread *td, int wh
 
 	case RUSAGE_THREAD:
 		PROC_SLOCK(p);
-		ruxagg(p, td);
-		PROC_SUNLOCK(p);
 		thread_lock(td);
-		*rup = td->td_ru;
-		calcru1(p, &td->td_rux, &rup->ru_utime, &rup->ru_stime);
+		rufetchtd(td, rup);
 		thread_unlock(td);
+		PROC_SUNLOCK(p);
 		break;
 
 	default:

Modified: head/sys/sys/resourcevar.h
==============================================================================
--- head/sys/sys/resourcevar.h	Mon Jul 18 15:19:40 2011	(r224187)
+++ head/sys/sys/resourcevar.h	Mon Jul 18 17:33:08 2011	(r224188)
@@ -136,6 +136,7 @@ void	 rucollect(struct rusage *ru, struc
 void	 rufetch(struct proc *p, struct rusage *ru);
 void	 rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up,
 	    struct timeval *sp);
+void	 rufetchtd(struct thread *td, struct rusage *ru);
 void	 ruxagg(struct proc *p, struct thread *td);
 int	 suswintr(void *base, int word);
 struct uidinfo

Modified: head/usr.bin/top/machine.c
==============================================================================
--- head/usr.bin/top/machine.c	Mon Jul 18 15:19:40 2011	(r224187)
+++ head/usr.bin/top/machine.c	Mon Jul 18 17:33:08 2011	(r224188)
@@ -235,6 +235,7 @@ static int *pcpu_cpu_states;
 
 static int compare_jid(const void *a, const void *b);
 static int compare_pid(const void *a, const void *b);
+static int compare_tid(const void *a, const void *b);
 static const char *format_nice(const struct kinfo_proc *pp);
 static void getsysctl(const char *name, void *ptr, size_t len);
 static int swapmode(int *retavail, int *retfree);
@@ -557,7 +558,7 @@ get_old_proc(struct kinfo_proc *pp)
 	 * cache it.
 	 */
 	oldpp = bsearch(&pp, previous_pref, previous_proc_count,
-	    sizeof(*previous_pref), compare_pid);
+	    sizeof(*previous_pref), ps.thread ? compare_tid : compare_pid);
 	if (oldpp == NULL) {
 		pp->ki_udata = NOPROC;
 		return (NULL);
@@ -652,7 +653,7 @@ get_process_info(struct system_info *si,
 			previous_pref[i] = &previous_procs[i];
 		bcopy(pbase, previous_procs, nproc * sizeof(*previous_procs));
 		qsort(previous_pref, nproc, sizeof(*previous_pref),
-		    compare_pid);
+		    ps.thread ? compare_tid : compare_pid);
 	}
 	previous_proc_count = nproc;
 
@@ -1059,6 +1060,18 @@ compare_pid(const void *p1, const void *
 	return ((*pp1)->ki_pid - (*pp2)->ki_pid);
 }
 
+static int
+compare_tid(const void *p1, const void *p2)
+{
+	const struct kinfo_proc * const *pp1 = p1;
+	const struct kinfo_proc * const *pp2 = p2;
+
+	if ((*pp2)->ki_tid < 0 || (*pp1)->ki_tid < 0)
+		abort();
+
+	return ((*pp1)->ki_tid - (*pp2)->ki_tid);
+}
+
 /*
  *  proc_compare - comparison function for "qsort"
  *	Compares the resource consumption of two processes using five



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