top - able to account kernel cpu time to process
This commit is contained in:
parent
ab73ac3b6f
commit
dce5e09683
1 changed files with 85 additions and 19 deletions
|
@ -20,6 +20,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <sys/ioc_tty.h>
|
#include <sys/ioc_tty.h>
|
||||||
#include <sys/times.h>
|
#include <sys/times.h>
|
||||||
|
@ -36,8 +37,17 @@
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <minix/procfs.h>
|
#include <minix/procfs.h>
|
||||||
|
|
||||||
|
#define TIMECYCLEKEY 't'
|
||||||
|
|
||||||
u32_t system_hz;
|
u32_t system_hz;
|
||||||
|
|
||||||
|
/* name of cpu cycle types, in the order they appear in /psinfo. */
|
||||||
|
char *cputimenames[] = { "user", "ipc", "kernelcall" };
|
||||||
|
|
||||||
|
#define CPUTIMENAMES (sizeof(cputimenames)/sizeof(cputimenames[0]))
|
||||||
|
|
||||||
|
#define CPUTIME(m, i) (m & (1L << (i)))
|
||||||
|
|
||||||
unsigned int nr_procs, nr_tasks;
|
unsigned int nr_procs, nr_tasks;
|
||||||
int nr_total;
|
int nr_total;
|
||||||
|
|
||||||
|
@ -59,7 +69,7 @@ struct proc {
|
||||||
int p_flags;
|
int p_flags;
|
||||||
endpoint_t p_endpoint;
|
endpoint_t p_endpoint;
|
||||||
pid_t p_pid;
|
pid_t p_pid;
|
||||||
u64_t p_cycles;
|
u64_t p_cpucycles[CPUTIMENAMES];
|
||||||
int p_priority;
|
int p_priority;
|
||||||
endpoint_t p_blocked;
|
endpoint_t p_blocked;
|
||||||
time_t p_user_time;
|
time_t p_user_time;
|
||||||
|
@ -78,6 +88,7 @@ void parse_file(pid_t pid)
|
||||||
unsigned long cycles_hi, cycles_lo;
|
unsigned long cycles_hi, cycles_lo;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
int i;
|
||||||
|
|
||||||
sprintf(path, "%d/psinfo", pid);
|
sprintf(path, "%d/psinfo", pid);
|
||||||
|
|
||||||
|
@ -122,12 +133,13 @@ void parse_file(pid_t pid)
|
||||||
|
|
||||||
if (state != STATE_RUN)
|
if (state != STATE_RUN)
|
||||||
p->p_flags |= BLOCKED;
|
p->p_flags |= BLOCKED;
|
||||||
p->p_cycles = make64(cycles_lo, cycles_hi);
|
p->p_cpucycles[0] = make64(cycles_lo, cycles_hi);
|
||||||
p->p_memory = 0L;
|
p->p_memory = 0L;
|
||||||
|
|
||||||
if (!(p->p_flags & IS_TASK)) {
|
if (!(p->p_flags & IS_TASK)) {
|
||||||
if (fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d",
|
int i;
|
||||||
&p->p_memory, &effuid, &p->p_nice) != 3) {
|
if ((i=fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u",
|
||||||
|
&p->p_memory, &effuid, &p->p_nice)) != 3) {
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return;
|
return;
|
||||||
|
@ -136,6 +148,15 @@ void parse_file(pid_t pid)
|
||||||
p->p_effuid = effuid;
|
p->p_effuid = effuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i = 1; i < CPUTIMENAMES; i++) {
|
||||||
|
if(fscanf(fp, " %lu %lu",
|
||||||
|
&cycles_hi, &cycles_lo) == 2) {
|
||||||
|
p->p_cpucycles[i] = make64(cycles_lo, cycles_hi);
|
||||||
|
} else {
|
||||||
|
p->p_cpucycles[i] = make64(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p->p_flags |= USED;
|
p->p_flags |= USED;
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -302,6 +323,8 @@ struct tp *lookup(endpoint_t who, struct tp *tptab, int np)
|
||||||
*/
|
*/
|
||||||
#define SCALE (1 << 12)
|
#define SCALE (1 << 12)
|
||||||
|
|
||||||
|
double ktotal = 0;
|
||||||
|
|
||||||
void print_proc(struct tp *tp, u32_t tcyc)
|
void print_proc(struct tp *tp, u32_t tcyc)
|
||||||
{
|
{
|
||||||
int euid = 0;
|
int euid = 0;
|
||||||
|
@ -339,8 +362,45 @@ void print_proc(struct tp *tp, u32_t tcyc)
|
||||||
printf("%6.2f%% %s", 100.0*pcyc/tcyc, name);
|
printf("%6.2f%% %s", 100.0*pcyc/tcyc, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *cputimemodename(int cputimemode)
|
||||||
|
{
|
||||||
|
static char name[100];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
name[0] = '\0';
|
||||||
|
|
||||||
|
for(i = 0; i < CPUTIMENAMES; i++) {
|
||||||
|
if(CPUTIME(cputimemode, i)) {
|
||||||
|
assert(strlen(name) +
|
||||||
|
strlen(cputimenames[i]) < sizeof(name));
|
||||||
|
strcat(name, cputimenames[i]);
|
||||||
|
strcat(name, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64_t cputicks(struct proc *p1, struct proc *p2, int timemode)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u64_t t = make64(0, 0);
|
||||||
|
for(i = 0; i < CPUTIMENAMES; i++) {
|
||||||
|
if(!CPUTIME(timemode, i))
|
||||||
|
continue;
|
||||||
|
if(p1->p_endpoint == p2->p_endpoint) {
|
||||||
|
t = add64(t, sub64(p2->p_cpucycles[i],
|
||||||
|
p1->p_cpucycles[i]));
|
||||||
|
} else {
|
||||||
|
t = add64(t, p2->p_cpucycles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
void print_procs(int maxlines,
|
void print_procs(int maxlines,
|
||||||
struct proc *proc1, struct proc *proc2)
|
struct proc *proc1, struct proc *proc2, int cputimemode)
|
||||||
{
|
{
|
||||||
int p, nprocs;
|
int p, nprocs;
|
||||||
u64_t idleticks = cvu64(0);
|
u64_t idleticks = cvu64(0);
|
||||||
|
@ -363,24 +423,19 @@ void print_procs(int maxlines,
|
||||||
}
|
}
|
||||||
|
|
||||||
for(p = nprocs = 0; p < nr_total; p++) {
|
for(p = nprocs = 0; p < nr_total; p++) {
|
||||||
|
u64_t uticks;
|
||||||
if(!(proc2[p].p_flags & USED))
|
if(!(proc2[p].p_flags & USED))
|
||||||
continue;
|
continue;
|
||||||
tick_procs[nprocs].p = proc2 + p;
|
tick_procs[nprocs].p = proc2 + p;
|
||||||
if(proc1[p].p_endpoint == proc2[p].p_endpoint) {
|
tick_procs[nprocs].ticks = cputicks(&proc1[p], &proc2[p], cputimemode);
|
||||||
tick_procs[nprocs].ticks =
|
uticks = cputicks(&proc1[p], &proc2[p], 1);
|
||||||
sub64(proc2[p].p_cycles, proc1[p].p_cycles);
|
total_ticks = add64(total_ticks, uticks);
|
||||||
} else {
|
|
||||||
tick_procs[nprocs].ticks =
|
|
||||||
proc2[p].p_cycles;
|
|
||||||
}
|
|
||||||
total_ticks = add64(total_ticks, tick_procs[nprocs].ticks);
|
|
||||||
if(p-NR_TASKS == IDLE) {
|
if(p-NR_TASKS == IDLE) {
|
||||||
idleticks = tick_procs[nprocs].ticks;
|
idleticks = uticks;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(p-NR_TASKS == KERNEL) {
|
if(p-NR_TASKS == KERNEL) {
|
||||||
kernelticks = tick_procs[nprocs].ticks;
|
kernelticks = uticks;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!(proc2[p].p_flags & IS_TASK)) {
|
if(!(proc2[p].p_flags & IS_TASK)) {
|
||||||
|
@ -416,6 +471,11 @@ void print_procs(int maxlines,
|
||||||
|
|
||||||
#define NEWLINE do { printf("\n"); if(--maxlines <= 0) { return; } } while(0)
|
#define NEWLINE do { printf("\n"); if(--maxlines <= 0) { return; } } while(0)
|
||||||
NEWLINE;
|
NEWLINE;
|
||||||
|
|
||||||
|
printf("CPU time displayed (press '%c' to cycle): %s",
|
||||||
|
TIMECYCLEKEY, cputimemodename(cputimemode));
|
||||||
|
NEWLINE;
|
||||||
|
|
||||||
NEWLINE;
|
NEWLINE;
|
||||||
|
|
||||||
printf(" PID USERNAME PRI NICE SIZE STATE TIME CPU COMMAND");
|
printf(" PID USERNAME PRI NICE SIZE STATE TIME CPU COMMAND");
|
||||||
|
@ -471,7 +531,7 @@ void print_procs(int maxlines,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showtop(int r)
|
void showtop(int cputimemode, int r)
|
||||||
{
|
{
|
||||||
#define NLOADS 3
|
#define NLOADS 3
|
||||||
double loads[NLOADS];
|
double loads[NLOADS];
|
||||||
|
@ -502,7 +562,7 @@ void showtop(int r)
|
||||||
|
|
||||||
if(winsize.ws_row > 0) r = winsize.ws_row;
|
if(winsize.ws_row > 0) r = winsize.ws_row;
|
||||||
|
|
||||||
print_procs(r - lines - 2, prev_proc, proc);
|
print_procs(r - lines - 2, prev_proc, proc, cputimemode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(int *rows)
|
void init(int *rows)
|
||||||
|
@ -561,6 +621,7 @@ void getkinfo(void)
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int r, c, s = 0;
|
int r, c, s = 0;
|
||||||
|
int cputimemode = 1; /* bitmap. */
|
||||||
|
|
||||||
if (chdir(_PATH_PROC) != 0) {
|
if (chdir(_PATH_PROC) != 0) {
|
||||||
perror("chdir to " _PATH_PROC);
|
perror("chdir to " _PATH_PROC);
|
||||||
|
@ -601,7 +662,7 @@ int main(int argc, char *argv[])
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int ns;
|
int ns;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
showtop(r);
|
showtop(cputimemode, r);
|
||||||
tv.tv_sec = s;
|
tv.tv_sec = s;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
@ -621,6 +682,11 @@ int main(int argc, char *argv[])
|
||||||
putchar('\r');
|
putchar('\r');
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
case TIMECYCLEKEY:
|
||||||
|
cputimemode++;
|
||||||
|
if(cputimemode >= (1L << CPUTIMENAMES))
|
||||||
|
cputimemode = 1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue