diff options
author | jhb <jhb@FreeBSD.org> | 2011-07-18 17:33:08 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2011-07-18 17:33:08 +0000 |
commit | 4e1a6d0e6744fbd594114870804c3a5062815280 (patch) | |
tree | c9ca0ce831e01fabc0898005bf23fb41dcc1c5e9 /sys/kern | |
parent | 9a6ff5ad378cfaaa99c5162e2b0f6e4cb6a3c796 (diff) | |
download | FreeBSD-src-4e1a6d0e6744fbd594114870804c3a5062815280.zip FreeBSD-src-4e1a6d0e6744fbd594114870804c3a5062815280.tar.gz |
- 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)
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_proc.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 40 |
2 files changed, 39 insertions, 6 deletions
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 4f1dc45..aac8b39 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -848,6 +848,8 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread) 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, struct kinfo_proc *kp, int preferthread) 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, struct kinfo_proc *kp, int preferthread) kp->ki_siglist = td->td_siglist; kp->ki_sigmask = td->td_sigmask; thread_unlock(td); + if (preferthread) + PROC_SUNLOCK(p); } /* diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 1062703..78a25eb 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -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 *up, struct timeval *sp) 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 *up, struct timeval *sp) 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 who, struct rusage *rup) 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: |