summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttilio Rao <attilio@FreeBSD.org>2009-09-07 09:51:23 +0000
committerAttilio Rao <attilio@FreeBSD.org>2009-09-07 09:51:23 +0000
commited6c6c586ae35c3c1da5bee8815795f80ed4eaa0 (patch)
treec67e3b0e0ef9ce518692f871106e3e9230e0b7ba
parent6b07a17c6140cb49f6dd8e3d1f8d824ca8b80165 (diff)
Notes
-rw-r--r--bin/ps/extern.h3
-rw-r--r--bin/ps/keyword.c21
-rw-r--r--bin/ps/print.c26
-rw-r--r--bin/ps/ps.c3
-rw-r--r--sys/kern/kern_proc.c67
5 files changed, 83 insertions, 37 deletions
diff --git a/bin/ps/extern.h b/bin/ps/extern.h
index 08b6d9bce630..b93ecba1a51e 100644
--- a/bin/ps/extern.h
+++ b/bin/ps/extern.h
@@ -39,7 +39,7 @@ extern fixpt_t ccpu;
extern int cflag, eval, fscale, nlistread, rawcpu;
extern unsigned long mempages;
extern time_t now;
-extern int sumrusage, termwidth, totwidth;
+extern int showthreads, sumrusage, termwidth, totwidth;
extern STAILQ_HEAD(velisthead, varent) varlist;
__BEGIN_DECLS
@@ -71,6 +71,7 @@ void priorityr(KINFO *, VARENT *);
void rgroupname(KINFO *, VARENT *);
void runame(KINFO *, VARENT *);
void rvar(KINFO *, VARENT *);
+int s_comm(KINFO *);
int s_label(KINFO *);
int s_rgroupname(KINFO *);
int s_runame(KINFO *);
diff --git a/bin/ps/keyword.c b/bin/ps/keyword.c
index b7a887bcb88b..3b0c3585d9fa 100644
--- a/bin/ps/keyword.c
+++ b/bin/ps/keyword.c
@@ -79,8 +79,8 @@ static VAR var[] = {
CHAR, NULL, 0},
{"blocked", "", "sigmask", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"caught", "", "sigcatch", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
- {"comm", "COMMAND", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR,
- NULL, 0},
+ {"comm", "COMMAND", NULL, LJUST|DSIZ, ucomm, s_comm,
+ COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0},
{"command", "COMMAND", NULL, COMM|LJUST|USER, command, NULL, 16, 0,
CHAR, NULL, 0},
{"cpu", "CPU", NULL, 0, kvar, NULL, 3, KOFF(ki_estcpu), UINT, "d",
@@ -135,12 +135,13 @@ static VAR var[] = {
LONG, "ld", 0},
{"nvcsw", "NVCSW", NULL, USER, rvar, NULL, 5, ROFF(ru_nvcsw),
LONG, "ld", 0},
- {"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, 8, 0, CHAR, NULL, 0},
+ {"nwchan", "NWCHAN", NULL, LJUST, nwchan, NULL, sizeof(void *) * 2, 0,
+ CHAR, NULL, 0},
{"oublk", "OUBLK", NULL, USER, rvar, NULL, 4, ROFF(ru_oublock),
LONG, "ld", 0},
{"oublock", "", "oublk", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
- {"paddr", "PADDR", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR,
- "lx", 0},
+ {"paddr", "PADDR", NULL, 0, kvar, NULL, sizeof(void *) * 2,
+ KOFF(ki_paddr), KPTR, "lx", 0},
{"pagein", "PAGEIN", NULL, USER, pagein, NULL, 6, 0, CHAR, NULL, 0},
{"pcpu", "", "%cpu", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
{"pending", "", "sig", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
@@ -194,13 +195,13 @@ static VAR var[] = {
{"tsiz", "TSIZ", NULL, 0, kvar, NULL, 4, KOFF(ki_tsize), PGTOK, "ld", 0},
{"tt", "TT ", NULL, 0, tname, NULL, 4, 0, CHAR, NULL, 0},
{"tty", "TTY", NULL, LJUST, longtname, NULL, 8, 0, CHAR, NULL, 0},
- {"ucomm", "UCOMM", NULL, LJUST, ucomm, NULL, MAXCOMLEN, 0, CHAR, NULL,
- 0},
+ {"ucomm", "UCOMM", NULL, LJUST|DSIZ, ucomm, s_comm,
+ COMMLEN + OCOMMLEN + 1, 0, CHAR, NULL, 0},
{"uid", "UID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_uid), UINT,
UIDFMT, 0},
{"upr", "UPR", NULL, 0, upr, NULL, 3, 0, CHAR, NULL, 0},
- {"uprocp", "UPROCP", NULL, 0, kvar, NULL, 8, KOFF(ki_paddr), KPTR,
- "lx", 0},
+ {"uprocp", "UPROCP", NULL, 0, kvar, NULL, sizeof(void *) * 2,
+ KOFF(ki_paddr), KPTR, "lx", 0},
{"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN, 0, CHAR,
NULL, 0},
{"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
@@ -324,6 +325,8 @@ findvar(char *p, int user, char **header)
*/
rflen = strlen(v->alias) + strlen(hp) + 2;
realfmt = malloc(rflen);
+ if (realfmt == NULL)
+ errx(1, "malloc failed");
snprintf(realfmt, rflen, "%s=%s", v->alias, hp);
parsefmt(realfmt, user);
}
diff --git a/bin/ps/print.c b/bin/ps/print.c
index a0dfbfd201b2..1326d4d1c3b1 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -186,6 +186,7 @@ command(KINFO *k, VARENT *ve)
void
ucomm(KINFO *k, VARENT *ve)
{
+ char tmpbuff[COMMLEN + OCOMMLEN + 2];
VAR *v;
v = ve->var;
@@ -193,8 +194,15 @@ ucomm(KINFO *k, VARENT *ve)
if (k->ki_d.prefix)
(void)printf("%s", k->ki_d.prefix);
(void)printf("%s", k->ki_p->ki_comm);
- } else
- (void)printf("%-*s", v->width, k->ki_p->ki_comm);
+ } else {
+ bzero(tmpbuff, sizeof(tmpbuff));
+ if (showthreads && k->ki_p->ki_numthreads > 1)
+ sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm,
+ k->ki_p->ki_ocomm);
+ else
+ sprintf(tmpbuff, "%s", k->ki_p->ki_comm);
+ (void)printf("%-*s", v->width, tmpbuff);
+ }
}
void
@@ -822,6 +830,20 @@ out:
}
int
+s_comm(KINFO *k)
+{
+ char tmpbuff[COMMLEN + OCOMMLEN + 2];
+
+ bzero(tmpbuff, sizeof(tmpbuff));
+ if (showthreads && k->ki_p->ki_numthreads > 1)
+ sprintf(tmpbuff, "%s/%s", k->ki_p->ki_comm,
+ k->ki_p->ki_ocomm);
+ else
+ sprintf(tmpbuff, "%s", k->ki_p->ki_comm);
+ return (strlen(tmpbuff));
+}
+
+int
s_label(KINFO *k)
{
char *string = NULL;
diff --git a/bin/ps/ps.c b/bin/ps/ps.c
index 6d5f97ef0ff8..1c6e5183ef5a 100644
--- a/bin/ps/ps.c
+++ b/bin/ps/ps.c
@@ -100,6 +100,7 @@ int rawcpu; /* -C */
int sumrusage; /* -S */
int termwidth; /* Width of the screen (0 == infinity). */
int totwidth; /* Calculated-width of requested variables. */
+int showthreads; /* will threads be shown? */
struct velisthead varlist = STAILQ_HEAD_INITIALIZER(varlist);
@@ -178,7 +179,7 @@ main(int argc, char *argv[])
char *cols;
int all, ch, elem, flag, _fmt, i, lineno;
int descendancy, nentries, nkept, nselectors;
- int prtheader, showthreads, wflag, what, xkeep, xkeep_implied;
+ int prtheader, wflag, what, xkeep, xkeep_implied;
char errbuf[_POSIX2_LINE_MAX];
(void) setlocale(LC_ALL, "");
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index b04523bdb789..1368933e70a1 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -115,6 +115,7 @@ MALLOC_DEFINE(M_SUBPROC, "subproc", "Proc sub-structures");
static void doenterpgrp(struct proc *, struct pgrp *);
static void orphanpg(struct pgrp *pg);
+static void fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp);
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,
int preferthread);
@@ -670,6 +671,30 @@ DB_SHOW_COMMAND(pgrpdump, pgrpdump)
#endif /* DDB */
/*
+ * Rework the kinfo_proc members which need to be aggregated in the
+ * case of process-ware informations.
+ * Must be called with the target spinlock process held.
+ */
+static void
+fill_kinfo_aggregate(struct proc *p, struct kinfo_proc *kp)
+{
+ struct thread *td;
+
+ PROC_SLOCK_ASSERT(p, MA_OWNED);
+
+ kp->ki_estcpu = 0;
+ kp->ki_pctcpu = 0;
+ kp->ki_runtime = 0;
+ FOREACH_THREAD_IN_PROC(p, td) {
+ thread_lock(td);
+ kp->ki_pctcpu += sched_pctcpu(td);
+ kp->ki_runtime += cputick2usec(td->td_runtime);
+ kp->ki_estcpu += td->td_estcpu;
+ thread_unlock(td);
+ }
+}
+
+/*
* Clear kinfo_proc and fill in any information that is common
* to all threads in the process.
* Must be called with the target process locked.
@@ -868,14 +893,15 @@ fill_kinfo_thread(struct thread *td, struct kinfo_proc *kp, int preferthread)
kp->ki_numthreads = p->p_numthreads;
kp->ki_pcb = td->td_pcb;
kp->ki_kstack = (void *)td->td_kstack;
- kp->ki_pctcpu = sched_pctcpu(td);
- kp->ki_estcpu = td->td_estcpu;
kp->ki_slptime = (ticks - td->td_slptick) / hz;
kp->ki_pri.pri_class = td->td_pri_class;
kp->ki_pri.pri_user = td->td_user_pri;
- if (preferthread)
+ if (preferthread) {
kp->ki_runtime = cputick2usec(td->td_runtime);
+ kp->ki_pctcpu = sched_pctcpu(td);
+ kp->ki_estcpu = td->td_estcpu;
+ }
/* We can't get this anymore but ps etc never used it anyway. */
kp->ki_rqindex = 0;
@@ -895,8 +921,9 @@ fill_kinfo_proc(struct proc *p, struct kinfo_proc *kp)
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, 0);
+ MPASS (FIRST_THREAD_IN_PROC(p) != NULL);
+ fill_kinfo_thread(FIRST_THREAD_IN_PROC(p), kp, 0);
+ fill_kinfo_aggregate(p, kp);
PROC_SUNLOCK(p);
}
@@ -962,28 +989,20 @@ sysctl_out_proc(struct proc *p, struct sysctl_req *req, int flags)
PROC_LOCK_ASSERT(p, MA_OWNED);
- fill_kinfo_proc_only(p, &kinfo_proc);
- 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, 0);
- PROC_SUNLOCK(p);
+ fill_kinfo_proc(p, &kinfo_proc);
+ if (flags & KERN_PROC_NOTHREADS)
error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
- sizeof(kinfo_proc));
- } else {
+ sizeof(kinfo_proc));
+ else {
PROC_SLOCK(p);
- if (FIRST_THREAD_IN_PROC(p) != NULL)
- FOREACH_THREAD_IN_PROC(p, td) {
- fill_kinfo_thread(td, &kinfo_proc, 1);
- error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
- sizeof(kinfo_proc));
- if (error)
- break;
- }
- else
+ MPASS(FIRST_THREAD_IN_PROC(p) != NULL);
+ FOREACH_THREAD_IN_PROC(p, td) {
+ fill_kinfo_thread(td, &kinfo_proc, 1);
error = SYSCTL_OUT(req, (caddr_t)&kinfo_proc,
- sizeof(kinfo_proc));
+ sizeof(kinfo_proc));
+ if (error)
+ break;
+ }
PROC_SUNLOCK(p);
}
PROC_UNLOCK(p);