diff options
author | attilio <attilio@FreeBSD.org> | 2007-06-09 21:48:44 +0000 |
---|---|---|
committer | attilio <attilio@FreeBSD.org> | 2007-06-09 21:48:44 +0000 |
commit | 12d804e413f2c44d9e10f25ee1b546f2b48c598b (patch) | |
tree | 7fca182049d1ed6ecc1c3b117e1d77c681c922c3 /sys/kern/kern_resource.c | |
parent | 82a09af23776643f85a5e710a09bef3be83823d9 (diff) | |
download | FreeBSD-src-12d804e413f2c44d9e10f25ee1b546f2b48c598b.zip FreeBSD-src-12d804e413f2c44d9e10f25ee1b546f2b48c598b.tar.gz |
rufetch and calcru sometimes should be called atomically together.
This patch fixes places where they should be called atomically changing
their locking requirements (both assume per-proc spinlock held) and
introducing rufetchcalc which wrappers both calls to be performed in
atomic way.
Reviewed by: jeff
Approved by: jeff (mentor)
Diffstat (limited to 'sys/kern/kern_resource.c')
-rw-r--r-- | sys/kern/kern_resource.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index 5982066..9f47402 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -829,12 +829,11 @@ calccru(p, up, sp) void calcru(struct proc *p, struct timeval *up, struct timeval *sp) { - struct rusage_ext rux; struct thread *td; uint64_t u; PROC_LOCK_ASSERT(p, MA_OWNED); - PROC_SLOCK(p); + PROC_SLOCK_ASSERT(p, MA_OWNED); /* * If we are getting stats for the current process, then add in the * stats that this thread has accumulated in its current time slice. @@ -847,14 +846,7 @@ calcru(struct proc *p, struct timeval *up, struct timeval *sp) p->p_rux.rux_runtime += u - PCPU_GET(switchtime); PCPU_SET(switchtime, u); } - /* Work on a copy of p_rux so we can let go of p_slock */ - rux = p->p_rux; - PROC_SUNLOCK(p); - calcru1(p, &rux, up, sp); - /* Update the result from the p_rux copy */ - p->p_rux.rux_uu = rux.rux_uu; - p->p_rux.rux_su = rux.rux_su; - p->p_rux.rux_tu = rux.rux_tu; + calcru1(p, &p->p_rux, up, sp); } static void @@ -965,8 +957,8 @@ kern_getrusage(td, who, rup) switch (who) { case RUSAGE_SELF: - rufetch(p, rup); - calcru(p, &rup->ru_utime, &rup->ru_stime); + rufetchcalc(p, rup, &rup->ru_utime, + &rup->ru_stime); break; case RUSAGE_CHILDREN: @@ -1039,7 +1031,8 @@ rufetch(struct proc *p, struct rusage *ru) { struct thread *td; - PROC_SLOCK(p); + PROC_SLOCK_ASSERT(p, MA_OWNED); + *ru = p->p_ru; if (p->p_numthreads > 0) { FOREACH_THREAD_IN_PROC(p, td) { @@ -1049,6 +1042,21 @@ rufetch(struct proc *p, struct rusage *ru) rucollect(ru, &td->td_ru); } } +} + +/* + * Atomically perform a rufetch and a calcru together. + * Consumers, can safely assume the calcru is executed only once + * rufetch is completed. + */ +void +rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up, + struct timeval *sp) +{ + + PROC_SLOCK(p); + rufetch(p, ru); + calcru(p, up, sp); PROC_SUNLOCK(p); } |