Index: sys/proc.h =================================================================== RCS file: /home/ncvs/src/sys/sys/proc.h,v retrieving revision 1.498 diff -u -r1.498 proc.h --- sys/proc.h 16 Dec 2007 06:21:20 -0000 1.498 +++ sys/proc.h 10 Jan 2008 08:37:52 -0000 @@ -244,6 +244,7 @@ u_int td_estcpu; /* (t) estimated cpu utilization */ u_int td_slptick; /* (t) Time at sleep. */ struct rusage td_ru; /* (t) rusage information */ + uint64_t td_incruntime; /* (t) Cpu ticks to transfer to proc. */ uint64_t td_runtime; /* (t) How many cpu ticks we've run. */ u_int td_pticks; /* (t) Statclock hits for profiling */ u_int td_sticks; /* (t) Statclock hits in system mode. */ Index: kern/init_main.c =================================================================== RCS file: /home/ncvs/src/sys/kern/init_main.c,v retrieving revision 1.289 diff -u -r1.289 init_main.c --- kern/init_main.c 22 Dec 2007 04:56:48 -0000 1.289 +++ kern/init_main.c 10 Jan 2008 17:46:14 -0000 @@ -514,6 +514,7 @@ struct timespec ts; struct proc *p; struct rusage ru; + struct thread *td; /* * Now we can look at the time, having had a chance to verify the @@ -529,6 +530,9 @@ p->p_rux.rux_uticks = 0; p->p_rux.rux_sticks = 0; p->p_rux.rux_iticks = 0; + FOREACH_THREAD_IN_PROC(p, td) { + td->td_runtime = 0; + } } sx_sunlock(&allproc_lock); PCPU_SET(switchtime, cpu_ticks()); Index: kern/kern_proc.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v retrieving revision 1.260 diff -u -r1.260 kern_proc.c --- kern/kern_proc.c 10 Jan 2008 01:10:52 -0000 1.260 +++ kern/kern_proc.c 10 Jan 2008 09:09:04 -0000 @@ -84,7 +84,8 @@ static void doenterpgrp(struct proc *, struct pgrp *); static void orphanpg(struct pgrp *pg); static void fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp); -static void fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp); +static void fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, + int flags); static void pgadjustjobc(struct pgrp *pgrp, int entering); static void pgdelete(struct pgrp *); static int proc_ctor(void *mem, int size, void *arg, int flags); @@ -765,11 +766,12 @@ } /* - * Fill in information that is thread specific. - * Must be called with p_slock locked. + * Fill in information that is thread specific. Must be called with p_slock + * locked. If 'preferthread' is set, overwrite certain process-related + * fields that are maintained for both threads and processes. */ static void -fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp) +fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) { struct proc *p; @@ -829,6 +831,9 @@ kp->ki_pri.pri_class = td->td_pri_class; kp->ki_pri.pri_user = td->td_user_pri; + if (preferthread) + kp->ki_runtime = cputick2usec(td->td_runtime); + /* We can't get this anymore but ps etc never used it anyway. */ kp->ki_rqindex = 0; @@ -848,7 +853,7 @@ fill_kinfo_proc_only(p, kp); PROC_SLOCK(p); if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp); + fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0); PROC_SUNLOCK(p); } @@ -918,7 +923,8 @@ if (flags & KERN_PROC_NOTHREADS) { PROC_SLOCK(p); if (FIRST_THREAD_IN_PROC(p) != NULL) - fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), &kinfo_proc); + fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), + &kinfo_proc, 0); PROC_SUNLOCK(p); error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); @@ -926,7 +932,7 @@ PROC_SLOCK(p); if (FIRST_THREAD_IN_PROC(p) != NULL) FOREACH_THREAD_IN_PROC(p, td) { - fill_kinfo_thread(td, &kinfo_proc); + fill_kinfo_thread(td, &kinfo_proc, 1); error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc, sizeof(kinfo_proc)); if (error) Index: kern/kern_resource.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v retrieving revision 1.181 diff -u -r1.181 kern_resource.c --- kern/kern_resource.c 11 Dec 2007 08:25:35 -0000 1.181 +++ kern/kern_resource.c 10 Jan 2008 04:33:21 -0000 @@ -849,7 +849,7 @@ } /* Make sure the per-thread stats are current. */ FOREACH_THREAD_IN_PROC(p, td) { - if (td->td_runtime == 0) + if (td->td_incruntime == 0) continue; thread_lock(td); ruxagg(&p->p_rux, td); @@ -1021,11 +1021,11 @@ THREAD_LOCK_ASSERT(td, MA_OWNED); PROC_SLOCK_ASSERT(td->td_proc, MA_OWNED); - rux->rux_runtime += td->td_runtime; + rux->rux_runtime += td->td_incruntime; rux->rux_uticks += td->td_uticks; rux->rux_sticks += td->td_sticks; rux->rux_iticks += td->td_iticks; - td->td_runtime = 0; + td->td_incruntime = 0; td->td_uticks = 0; td->td_iticks = 0; td->td_sticks = 0; Index: kern/kern_synch.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v retrieving revision 1.304 diff -u -r1.304 kern_synch.c --- kern/kern_synch.c 14 Nov 2007 06:51:33 -0000 1.304 +++ kern/kern_synch.c 10 Jan 2008 04:34:02 -0000 @@ -371,7 +371,7 @@ void mi_switch(int flags, struct thread *newtd) { - uint64_t new_switchtime; + uint64_t runtime, new_switchtime; struct thread *td; struct proc *p; @@ -409,7 +409,9 @@ * thread was running, and add that to its total so far. */ new_switchtime = cpu_ticks(); - td->td_runtime += new_switchtime - PCPU_GET(switchtime); + runtime = new_switchtime - PCPU_GET(switchtime); + td->td_runtime += runtime; + td->td_incruntime += runtime; PCPU_SET(switchtime, new_switchtime); td->td_generation++; /* bump preempt-detect counter */ PCPU_INC(cnt.v_swtch);