summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2004-10-05 18:51:11 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2004-10-05 18:51:11 +0000
commit78c85e8dfc1c4a90a3ecb51acf35c33fe1faf331 (patch)
tree61af271e7225bd0154aaa08a967c5ce027c7bc2a /sys/kern
parenta55db2b6e63b4d36024857d89a7ab59747f17d97 (diff)
Notes
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_acct.c4
-rw-r--r--sys/kern/kern_clock.c8
-rw-r--r--sys/kern/kern_exit.c36
-rw-r--r--sys/kern/kern_proc.c25
-rw-r--r--sys/kern/kern_resource.c192
-rw-r--r--sys/kern/kern_synch.c6
-rw-r--r--sys/kern/kern_time.c14
-rw-r--r--sys/kern/subr_trap.c2
-rw-r--r--sys/kern/tty.c15
10 files changed, 170 insertions, 136 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 6acb6b01252f..e23e44608108 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -468,8 +468,8 @@ proc0_post(void *dummy __unused)
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
microuptime(&p->p_stats->p_start);
- p->p_runtime.sec = 0;
- p->p_runtime.frac = 0;
+ p->p_rux.rux_runtime.sec = 0;
+ p->p_rux.rux_runtime.frac = 0;
}
sx_sunlock(&allproc_lock);
binuptime(PCPU_PTR(switchtime));
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index 5dca0f60dd13..2b810edc47ca 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -249,9 +249,7 @@ acct_process(td)
bcopy(p->p_comm, acct.ac_comm, sizeof acct.ac_comm);
/* (2) The amount of user and system time that was used */
- mtx_lock_spin(&sched_lock);
- calcru(p, &ut, &st, NULL);
- mtx_unlock_spin(&sched_lock);
+ calcru(p, &ut, &st);
acct.ac_utime = encode_comp_t(ut.tv_sec, ut.tv_usec);
acct.ac_stime = encode_comp_t(st.tv_sec, st.tv_usec);
diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 21d627551c31..ab2f12957ec1 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -363,7 +363,7 @@ stopprofclock(p)
* Statistics clock. Grab profile sample, and if divider reaches 0,
* do process and kernel statistics. Most of the statistics are only
* used by user-level statistics programs. The main exceptions are
- * ke->ke_uticks, p->p_sticks, p->p_iticks, and p->p_estcpu.
+ * ke->ke_uticks, p->p_rux.rux_sticks, p->p_rux.rux_iticks, and p->p_estcpu.
* This should be called by all active processors.
*/
void
@@ -386,7 +386,7 @@ statclock(frame)
*/
if (p->p_flag & P_SA)
thread_statclock(1);
- p->p_uticks++;
+ p->p_rux.rux_uticks++;
if (p->p_nice > NZERO)
cp_time[CP_NICE]++;
else
@@ -405,13 +405,13 @@ statclock(frame)
* in ``non-process'' (i.e., interrupt) work.
*/
if ((td->td_ithd != NULL) || td->td_intr_nesting_level >= 2) {
- p->p_iticks++;
+ p->p_rux.rux_iticks++;
cp_time[CP_INTR]++;
} else {
if (p->p_flag & P_SA)
thread_statclock(0);
td->td_sticks++;
- p->p_sticks++;
+ p->p_rux.rux_sticks++;
if (p != PCPU_GET(idlethread)->td_proc)
cp_time[CP_SYS]++;
else
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index cd7e2a46f46f..ae44fc348b14 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -410,20 +410,16 @@ retry:
}
/*
- * Save exit status and final rusage info, adding in child rusage
- * info and self times.
+ * Save exit status and finalize rusage info except for times,
+ * adding in child rusage info.
*/
- mtx_lock(&Giant);
PROC_LOCK(p);
p->p_xstat = rv;
p->p_xthread = td;
+ p->p_stats->p_ru.ru_nvcsw++;
*p->p_ru = p->p_stats->p_ru;
- mtx_lock_spin(&sched_lock);
- calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL);
- mtx_unlock_spin(&sched_lock);
- ruadd(p->p_ru, &p->p_stats->p_cru);
+ ruadd(p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux);
- mtx_unlock(&Giant);
/*
* Notify interested parties of our demise.
*/
@@ -487,9 +483,6 @@ retry:
PROC_LOCK(p->p_pptr);
sx_xunlock(&proctree_lock);
- while (mtx_owned(&Giant))
- mtx_unlock(&Giant);
-
/*
* We have to wait until after acquiring all locks before
* changing p_state. We need to avoid all possible context
@@ -508,8 +501,8 @@ retry:
/* Do the same timestamp bookkeeping that mi_switch() would do. */
binuptime(&new_switchtime);
- bintime_add(&p->p_runtime, &new_switchtime);
- bintime_sub(&p->p_runtime, PCPU_PTR(switchtime));
+ bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
+ bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
PCPU_SET(switchtime, new_switchtime);
PCPU_SET(switchticks, ticks);
cnt.v_swtch++;
@@ -556,10 +549,14 @@ owait(struct thread *td, struct owait_args *uap __unused)
int
wait4(struct thread *td, struct wait_args *uap)
{
- struct rusage ru;
+ struct rusage ru, *rup;
int error, status;
- error = kern_wait(td, uap->pid, &status, uap->options, &ru);
+ if (uap->rusage != NULL)
+ rup = &ru;
+ else
+ rup = NULL;
+ error = kern_wait(td, uap->pid, &status, uap->options, rup);
if (uap->status != NULL && error == 0)
error = copyout(&status, uap->status, sizeof(status));
if (uap->rusage != NULL && error == 0)
@@ -612,8 +609,10 @@ loop:
td->td_retval[0] = p->p_pid;
if (status)
*status = p->p_xstat; /* convert to int */
- if (rusage)
+ if (rusage) {
bcopy(p->p_ru, rusage, sizeof(struct rusage));
+ calcru(p, &rusage->ru_utime, &rusage->ru_stime);
+ }
/*
* If we got the child via a ptrace 'attach',
@@ -648,16 +647,15 @@ loop:
* all other writes to this proc are visible now, so
* no more locking is needed for p.
*/
- mtx_lock(&Giant);
PROC_LOCK(p);
p->p_xstat = 0; /* XXX: why? */
PROC_UNLOCK(p);
PROC_LOCK(q);
- ruadd(&q->p_stats->p_cru, p->p_ru);
+ ruadd(&q->p_stats->p_cru, &q->p_crux, p->p_ru,
+ &p->p_rux);
PROC_UNLOCK(q);
FREE(p->p_ru, M_ZOMBIE);
p->p_ru = NULL;
- mtx_unlock(&Giant);
/*
* Decrement the count of procs running with this uid.
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 2f8b4df28ba9..f4f564847877 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -674,23 +674,11 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp)
kp->ki_dsize = vm->vm_dsize;
kp->ki_ssize = vm->vm_ssize;
}
- if ((p->p_sflag & PS_INMEM) && p->p_stats) {
- kp->ki_start = p->p_stats->p_start;
- timevaladd(&kp->ki_start, &boottime);
- kp->ki_rusage = p->p_stats->p_ru;
- calcru(p, &kp->ki_rusage.ru_utime, &kp->ki_rusage.ru_stime,
- NULL);
- kp->ki_childstime = p->p_stats->p_cru.ru_stime;
- kp->ki_childutime = p->p_stats->p_cru.ru_utime;
- /* Some callers want child-times in a single value */
- kp->ki_childtime = kp->ki_childstime;
- timevaladd(&kp->ki_childtime, &kp->ki_childutime);
- }
kp->ki_sflag = p->p_sflag;
kp->ki_swtime = p->p_swtime;
kp->ki_pid = p->p_pid;
kp->ki_nice = p->p_nice;
- bintime2timeval(&p->p_runtime, &tv);
+ bintime2timeval(&p->p_rux.rux_runtime, &tv);
kp->ki_runtime = tv.tv_sec * (u_int64_t)1000000 + tv.tv_usec;
if (p->p_state != PRS_ZOMBIE) {
#if 0
@@ -758,6 +746,17 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp)
kp->ki_stat = SZOMB;
}
mtx_unlock_spin(&sched_lock);
+ if ((p->p_sflag & PS_INMEM) && p->p_stats != NULL) {
+ kp->ki_start = p->p_stats->p_start;
+ timevaladd(&kp->ki_start, &boottime);
+ kp->ki_rusage = p->p_stats->p_ru;
+ calcru(p, &kp->ki_rusage.ru_utime, &kp->ki_rusage.ru_stime);
+ calccru(p, &kp->ki_childutime, &kp->ki_childstime);
+
+ /* Some callers want child-times in a single value */
+ kp->ki_childtime = kp->ki_childstime;
+ timevaladd(&kp->ki_childtime, &kp->ki_childutime);
+ }
sp = NULL;
tp = NULL;
if (p->p_pgrp) {
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index e0a6655c6997..d9e25c81d6f5 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/resourcevar.h>
#include <sys/sched.h>
#include <sys/sx.h>
+#include <sys/syscallsubr.h>
#include <sys/sysent.h>
#include <sys/time.h>
@@ -67,6 +68,8 @@ static struct mtx uihashtbl_mtx;
static LIST_HEAD(uihashhead, uidinfo) *uihashtbl;
static u_long uihash; /* size of hash table - 1 */
+static void calcru1(struct proc *p, struct rusage_ext *ruxp,
+ struct timeval *up, struct timeval *sp);
static int donice(struct thread *td, struct proc *chgp, int n);
static struct uidinfo *uilookup(uid_t uid);
@@ -691,65 +694,84 @@ getrlimit(td, uap)
* system, and interrupt time usage.
*/
void
-calcru(p, up, sp, ip)
+calcru(p, up, sp)
struct proc *p;
struct timeval *up;
struct timeval *sp;
- struct timeval *ip;
{
- struct bintime bt, rt;
- struct timeval tv;
+ struct bintime bt;
+ struct rusage_ext rux;
struct thread *td;
- /* {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);
- /* XXX: why spl-protect ? worst case is an off-by-one report */
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ mtx_assert(&sched_lock, MA_NOTOWNED);
+ bt_valid = 0;
+ mtx_lock_spin(&sched_lock);
+ rux = p->p_rux;
+ FOREACH_THREAD_IN_PROC(p, td) {
+ if (TD_IS_RUNNING(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 precision of binuptime().
+ */
+ KASSERT(td->td_oncpu != NOCPU,
+ ("%s: running thread has no CPU", __func__));
+ if (!bt_valid) {
+ binuptime(&bt);
+ bt_valid = 1;
+ }
+ bintime_add(&rux.rux_runtime, &bt);
+ bintime_sub(&rux.rux_runtime,
+ &pcpu_find(td->td_oncpu)->pc_switchtime);
+ }
+ }
+ mtx_unlock_spin(&sched_lock);
+ calcru1(p, &rux, up, sp);
+ p->p_rux.rux_uu = rux.rux_uu;
+ p->p_rux.rux_su = rux.rux_su;
+ p->p_rux.rux_iu = rux.rux_iu;
+}
- ut = p->p_uticks;
- st = p->p_sticks;
- it = p->p_iticks;
+void
+calccru(p, up, sp)
+ struct proc *p;
+ struct timeval *up;
+ struct timeval *sp;
+{
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ calcru1(p, &p->p_crux, up, sp);
+}
+
+static void
+calcru1(p, ruxp, up, sp)
+ struct proc *p;
+ struct rusage_ext *ruxp;
+ struct timeval *up;
+ struct timeval *sp;
+{
+ struct timeval tv;
+ /* {user, system, interrupt, total} {ticks, usec}; previous tu: */
+ u_int64_t ut, uu, st, su, it, iu, tt, tu, ptu;
+ ut = ruxp->rux_uticks;
+ st = ruxp->rux_sticks;
+ it = ruxp->rux_iticks;
tt = ut + st + it;
if (tt == 0) {
st = 1;
tt = 1;
}
- rt = p->p_runtime;
- problemcase = 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)) {
- /*
- * 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.
- */
- problemcase = 1;
- }
- }
- bintime2timeval(&rt, &tv);
+ bintime2timeval(&ruxp->rux_runtime, &tv);
tu = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
- ptu = p->p_uu + p->p_su + p->p_iu;
+ ptu = ruxp->rux_uu + ruxp->rux_su + ruxp->rux_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;
}
if ((int64_t)tu < 0) {
@@ -764,38 +786,34 @@ calcru(p, up, sp, ip)
iu = tu - uu - su;
/* Enforce monotonicity. */
- if (uu < p->p_uu || su < p->p_su || iu < p->p_iu) {
- if (uu < p->p_uu)
- uu = p->p_uu;
- else if (uu + p->p_su + p->p_iu > tu)
- uu = tu - p->p_su - p->p_iu;
+ if (uu < ruxp->rux_uu || su < ruxp->rux_su || iu < ruxp->rux_iu) {
+ if (uu < ruxp->rux_uu)
+ uu = ruxp->rux_uu;
+ else if (uu + ruxp->rux_su + ruxp->rux_iu > tu)
+ uu = tu - ruxp->rux_su - ruxp->rux_iu;
if (st == 0)
- su = p->p_su;
+ su = ruxp->rux_su;
else {
su = ((tu - uu) * st) / (st + it);
- if (su < p->p_su)
- su = p->p_su;
- else if (uu + su + p->p_iu > tu)
- su = tu - uu - p->p_iu;
+ if (su < ruxp->rux_su)
+ su = ruxp->rux_su;
+ else if (uu + su + ruxp->rux_iu > tu)
+ su = tu - uu - ruxp->rux_iu;
}
- KASSERT(uu + su + p->p_iu <= tu,
+ KASSERT(uu + su + ruxp->rux_iu <= tu,
("calcru: monotonisation botch 1"));
iu = tu - uu - su;
- KASSERT(iu >= p->p_iu,
+ KASSERT(iu >= ruxp->rux_iu,
("calcru: monotonisation botch 2"));
}
- p->p_uu = uu;
- p->p_su = su;
- p->p_iu = iu;
+ ruxp->rux_uu = uu;
+ ruxp->rux_su = su;
+ ruxp->rux_iu = iu;
up->tv_sec = uu / 1000000;
up->tv_usec = uu % 1000000;
sp->tv_sec = su / 1000000;
sp->tv_usec = su % 1000000;
- if (ip != NULL) {
- ip->tv_sec = iu / 1000000;
- ip->tv_usec = iu % 1000000;
- }
}
#ifndef _SYS_SYSPROTO_H_
@@ -807,51 +825,67 @@ struct getrusage_args {
/*
* MPSAFE
*/
-/* ARGSUSED */
int
getrusage(td, uap)
register struct thread *td;
register struct getrusage_args *uap;
{
struct rusage ru;
+ int error;
+
+ error = kern_getrusage(td, uap->who, &ru);
+ if (error == 0)
+ error = copyout(&ru, uap->rusage, sizeof(struct rusage));
+ return (error);
+}
+
+int
+kern_getrusage(td, who, rup)
+ struct thread *td;
+ int who;
+ struct rusage *rup;
+{
struct proc *p;
p = td->td_proc;
- switch (uap->who) {
+ PROC_LOCK(p);
+ switch (who) {
case RUSAGE_SELF:
- mtx_lock(&Giant);
- mtx_lock_spin(&sched_lock);
- calcru(p, &p->p_stats->p_ru.ru_utime, &p->p_stats->p_ru.ru_stime,
- NULL);
- mtx_unlock_spin(&sched_lock);
- ru = p->p_stats->p_ru;
- mtx_unlock(&Giant);
+ *rup = p->p_stats->p_ru;
+ calcru(p, &rup->ru_utime, &rup->ru_stime);
break;
case RUSAGE_CHILDREN:
- mtx_lock(&Giant);
- ru = p->p_stats->p_cru;
- mtx_unlock(&Giant);
+ *rup = p->p_stats->p_cru;
+ calccru(p, &rup->ru_utime, &rup->ru_stime);
break;
default:
+ PROC_UNLOCK(p);
return (EINVAL);
- break;
}
- return (copyout(&ru, uap->rusage, sizeof(struct rusage)));
+ PROC_UNLOCK(p);
+ return (0);
}
void
-ruadd(ru, ru2)
+ruadd(ru, rux, ru2, rux2)
struct rusage *ru;
+ struct rusage_ext *rux;
struct rusage *ru2;
+ struct rusage_ext *rux2;
{
register long *ip, *ip2;
register int i;
- timevaladd(&ru->ru_utime, &ru2->ru_utime);
- timevaladd(&ru->ru_stime, &ru2->ru_stime);
+ bintime_add(&rux->rux_runtime, &rux2->rux_runtime);
+ rux->rux_uticks += rux2->rux_uticks;
+ rux->rux_sticks += rux2->rux_sticks;
+ rux->rux_iticks += rux2->rux_iticks;
+ rux->rux_uu += rux2->rux_uu;
+ rux->rux_su += rux2->rux_su;
+ rux->rux_iu += rux2->rux_iu;
if (ru->ru_maxrss < ru2->ru_maxrss)
ru->ru_maxrss = ru2->ru_maxrss;
ip = &ru->ru_first;
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 13749e460f58..52863e39b966 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -302,8 +302,8 @@ mi_switch(int flags, struct thread *newtd)
* process was running, and add that to its total so far.
*/
binuptime(&new_switchtime);
- bintime_add(&p->p_runtime, &new_switchtime);
- bintime_sub(&p->p_runtime, PCPU_PTR(switchtime));
+ bintime_add(&p->p_rux.rux_runtime, &new_switchtime);
+ bintime_sub(&p->p_rux.rux_runtime, PCPU_PTR(switchtime));
td->td_generation++; /* bump preempt-detect counter */
@@ -322,7 +322,7 @@ mi_switch(int flags, struct thread *newtd)
* over max, arrange to kill the process in ast().
*/
if (p->p_cpulimit != RLIM_INFINITY &&
- p->p_runtime.sec > p->p_cpulimit) {
+ p->p_rux.rux_runtime.sec > p->p_cpulimit) {
p->p_sflag |= PS_XCPU;
td->td_flags |= TDF_ASTPENDING;
}
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 1a6819835a44..3b62532d9a1f 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -157,21 +157,23 @@ clock_gettime(struct thread *td, struct clock_gettime_args *uap)
{
struct timespec ats;
struct timeval sys, user;
+ struct proc *p;
+ p = td->td_proc;
switch (uap->clock_id) {
case CLOCK_REALTIME:
nanotime(&ats);
break;
case CLOCK_VIRTUAL:
- mtx_lock_spin(&sched_lock);
- calcru(td->td_proc, &user, &sys, NULL);
- mtx_unlock_spin(&sched_lock);
+ PROC_LOCK(p);
+ calcru(p, &user, &sys);
+ PROC_UNLOCK(p);
TIMEVAL_TO_TIMESPEC(&user, &ats);
break;
case CLOCK_PROF:
- mtx_lock_spin(&sched_lock);
- calcru(td->td_proc, &user, &sys, NULL);
- mtx_unlock_spin(&sched_lock);
+ PROC_LOCK(p);
+ calcru(p, &user, &sys);
+ PROC_UNLOCK(p);
timevaladd(&user, &sys);
TIMEVAL_TO_TIMESPEC(&user, &ats);
break;
diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
index 7753823eb008..86026a41b23a 100644
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -221,7 +221,7 @@ ast(struct trapframe *framep)
PROC_LOCK(p);
lim_rlimit(p, RLIMIT_CPU, &rlim);
mtx_lock_spin(&sched_lock);
- if (p->p_runtime.sec >= rlim.rlim_max) {
+ if (p->p_rux.rux_runtime.sec >= rlim.rlim_max) {
mtx_unlock_spin(&sched_lock);
killproc(p, "exceeded maximum CPU limit");
} else {
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index bcb3f9e8e7e0..b1956598a29c 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -2550,9 +2550,9 @@ ttyinfo(struct tty *tp)
tp->t_rocount = 0;
return;
}
- PGRP_LOCK(tp->t_pgrp);
- if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
- PGRP_UNLOCK(tp->t_pgrp);
+ sx_slock(&proctree_lock);
+ if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == NULL) {
+ sx_sunlock(&proctree_lock);
ttyprintf(tp, "empty foreground process group\n");
tp->t_rocount = 0;
return;
@@ -2567,10 +2567,9 @@ ttyinfo(struct tty *tp)
* too much.
*/
mtx_lock_spin(&sched_lock);
- for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
+ for (pick = NULL; p != NULL; p = LIST_NEXT(p, p_pglist))
if (proc_compare(pick, p))
pick = p;
- PGRP_UNLOCK(tp->t_pgrp);
td = FIRST_THREAD_IN_PROC(pick); /* XXXKSE */
#if 0
@@ -2578,6 +2577,7 @@ ttyinfo(struct tty *tp)
#else
if (td == NULL) {
mtx_unlock_spin(&sched_lock);
+ sx_sunlock(&proctree_lock);
ttyprintf(tp, "foreground process without thread\n");
tp->t_rocount = 0;
return;
@@ -2603,13 +2603,15 @@ ttyinfo(struct tty *tp)
state = "intrwait";
else
state = "unknown";
- calcru(pick, &utime, &stime, NULL);
pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT;
if (pick->p_state == PRS_NEW || pick->p_state == PRS_ZOMBIE)
rss = 0;
else
rss = pgtok(vmspace_resident_count(pick->p_vmspace));
mtx_unlock_spin(&sched_lock);
+ PROC_LOCK(pick);
+ calcru(pick, &utime, &stime);
+ PROC_UNLOCK(pick);
/* Print command, pid, state, utime, stime, %cpu, and rss. */
ttyprintf(tp,
@@ -2619,6 +2621,7 @@ ttyinfo(struct tty *tp)
(long)stime.tv_sec, stime.tv_usec / 10000,
pctcpu / 100, rss);
tp->t_rocount = 0;
+ sx_sunlock(&proctree_lock);
}
/*