|
|
@ -36,7 +36,10 @@ char *history[CMDLINE_HISTORY_MAX_QUANTITY]; |
|
|
|
int cmdline_amount = 0; |
|
|
|
|
|
|
|
struct proc *proc = NULL, *prev_proc = NULL; |
|
|
|
int order = ORDER_CPU; |
|
|
|
int blockedverbose = 0; |
|
|
|
int nr_total = 0; |
|
|
|
int slot = 1; |
|
|
|
unsigned int nr_procs, nr_tasks; |
|
|
|
|
|
|
|
int main() |
|
|
@ -462,7 +465,7 @@ void parse_dir() |
|
|
|
DIR *p_dir; |
|
|
|
struct dirent *p_ent; |
|
|
|
pid_t pid; |
|
|
|
char *end; |
|
|
|
char *end; //end是指向第一个不可转换的字符位置的指针
|
|
|
|
|
|
|
|
if ((p_dir = opendir("/proc")) == NULL) |
|
|
|
{ |
|
|
@ -472,12 +475,10 @@ void parse_dir() |
|
|
|
|
|
|
|
for (p_ent = readdir(p_dir); p_ent != NULL; p_ent = readdir(p_dir)) |
|
|
|
{ |
|
|
|
pid = strtol(p_ent->d_name, &end, 10); |
|
|
|
pid = strtol(p_ent->d_name, &end, 10); //long strtol(char *str, char **endptr, int base)将串转换为长整数,base是基数,表示要转换的是几进制的数
|
|
|
|
|
|
|
|
if (!end[0] && pid != 0) |
|
|
|
{ |
|
|
|
parse_file(pid); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
closedir(p_dir); |
|
|
@ -486,14 +487,15 @@ void parse_dir() |
|
|
|
void parse_file(pid_t pid) |
|
|
|
{ |
|
|
|
char path[PATH_MAX], name[256], type, state; |
|
|
|
int version, endpt, effuid; |
|
|
|
unsigned long cycles_hi, cycles_lo; |
|
|
|
int version, endpt, effuid; //版本,端点,有效用户ID
|
|
|
|
unsigned long cycles_hi, cycles_lo; //高周期,低周期
|
|
|
|
FILE *fp; |
|
|
|
struct proc *p; |
|
|
|
int slot; |
|
|
|
//int slot; //插槽?
|
|
|
|
int i; |
|
|
|
//printf("parse_file\n");
|
|
|
|
|
|
|
|
sprintf(path, "%d/psinfo", pid); |
|
|
|
sprintf(path, "/proc/%d/psinfo", pid); |
|
|
|
|
|
|
|
if ((fp = fopen(path, "r")) == NULL) |
|
|
|
return; |
|
|
@ -505,7 +507,7 @@ void parse_file(pid_t pid) |
|
|
|
} |
|
|
|
|
|
|
|
if (version != PSINFO_VERSION) |
|
|
|
{ |
|
|
|
{ //0
|
|
|
|
fputs("procfs version mismatch!\n", stderr); |
|
|
|
exit(1); |
|
|
|
} |
|
|
@ -516,11 +518,12 @@ void parse_file(pid_t pid) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
slot = SLOT_NR(endpt); |
|
|
|
slot++; |
|
|
|
//slot = SLOT_NR(endpt);
|
|
|
|
|
|
|
|
if (slot < 0 || slot >= nr_total) |
|
|
|
{ |
|
|
|
//fprintf(stderr, "top: unreasonable endpoint number %d\n", endpt);
|
|
|
|
fprintf(stderr, "top: unreasonable endpoint number %d\n", endpt); |
|
|
|
fclose(fp); |
|
|
|
return; |
|
|
|
} |
|
|
@ -528,18 +531,16 @@ void parse_file(pid_t pid) |
|
|
|
p = &proc[slot]; |
|
|
|
|
|
|
|
if (type == TYPE_TASK) |
|
|
|
{ |
|
|
|
p->p_flags |= IS_TASK; |
|
|
|
} |
|
|
|
else if (type == TYPE_SYSTEM) |
|
|
|
{ |
|
|
|
p->p_flags |= IS_SYSTEM; |
|
|
|
} |
|
|
|
|
|
|
|
p->p_endpoint = endpt; |
|
|
|
p->p_pid = pid; |
|
|
|
|
|
|
|
if (fscanf(fp, " %255s %c %d %d %lu %*u %lu %lu", name, &state, &p->p_blocked, &p->p_priority, &p->p_user_time, &cycles_hi, &cycles_lo) != 7) |
|
|
|
if (fscanf(fp, " %255s %c %d %d %lu %*u %lu %lu", |
|
|
|
name, &state, &p->p_blocked, &p->p_priority, |
|
|
|
&p->p_user_time, &cycles_hi, &cycles_lo) != 7) |
|
|
|
{ |
|
|
|
|
|
|
|
fclose(fp); |
|
|
@ -550,16 +551,15 @@ void parse_file(pid_t pid) |
|
|
|
p->p_name[sizeof(p->p_name) - 1] = 0; |
|
|
|
|
|
|
|
if (state != STATE_RUN) |
|
|
|
{ |
|
|
|
p->p_flags |= BLOCKED; |
|
|
|
} |
|
|
|
p->p_cpucycles[0] = make64(cycles_lo, cycles_hi); |
|
|
|
p->p_memory = 0L; |
|
|
|
|
|
|
|
if (!(p->p_flags & IS_TASK)) |
|
|
|
{ |
|
|
|
int j; |
|
|
|
if ((j = fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u", &p->p_memory, &effuid, &p->p_nice)) != 3) |
|
|
|
if ((j = fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u", |
|
|
|
&p->p_memory, &effuid, &p->p_nice)) != 3) |
|
|
|
{ |
|
|
|
|
|
|
|
fclose(fp); |
|
|
@ -569,13 +569,12 @@ void parse_file(pid_t pid) |
|
|
|
p->p_effuid = effuid; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
p->p_effuid = 0; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 1; i < CPUTIMENAMES; i++) |
|
|
|
{ |
|
|
|
if (fscanf(fp, " %lu %lu", &cycles_hi, &cycles_lo) == 2) |
|
|
|
if (fscanf(fp, " %lu %lu", |
|
|
|
&cycles_hi, &cycles_lo) == 2) |
|
|
|
{ |
|
|
|
p->p_cpucycles[i] = make64(cycles_lo, cycles_hi); |
|
|
|
} |
|
|
@ -622,11 +621,14 @@ void getkinfo() |
|
|
|
void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode) |
|
|
|
{ |
|
|
|
int p, nprocs; |
|
|
|
//u64_t idleticks = 0;
|
|
|
|
//u64_t kernelticks = 0;
|
|
|
|
u64_t systemticks = 0; |
|
|
|
u64_t userticks = 0; |
|
|
|
u64_t total_ticks = 0; |
|
|
|
int blockedseen = 0; |
|
|
|
static struct tp *tick_procs = NULL; |
|
|
|
static struct tp *tick_procs = NULL; //tp结构体的数组tick_procs,对所有的进程和任务(即上面读出来的nr_total)计算ticks
|
|
|
|
|
|
|
|
if (tick_procs == NULL) |
|
|
|
{ |
|
|
|
tick_procs = malloc(nr_total * sizeof(tick_procs[0])); |
|
|
@ -642,58 +644,37 @@ void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode) |
|
|
|
{ |
|
|
|
u64_t uticks; |
|
|
|
if (!(proc2[p].p_flags & USED)) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
tick_procs[nprocs].p = proc2 + p; |
|
|
|
tick_procs[nprocs].ticks = cputicks(&proc1[p], &proc2[p], cputimemode); |
|
|
|
uticks = cputicks(&proc1[p], &proc2[p], 1); |
|
|
|
total_ticks = total_ticks + uticks; |
|
|
|
//printf("total_ticks:%llu\n",total_ticks);
|
|
|
|
/*if(p-NR_TASKS == IDLE) {
|
|
|
|
idleticks = uticks; |
|
|
|
continue; |
|
|
|
} |
|
|
|
if(p-NR_TASKS == KERNEL) { |
|
|
|
kernelticks = uticks; |
|
|
|
} |
|
|
|
*/ |
|
|
|
if (!(proc2[p].p_flags & IS_TASK)) |
|
|
|
{ |
|
|
|
if (proc2[p].p_flags & IS_SYSTEM) |
|
|
|
{ |
|
|
|
systemticks = systemticks + tick_procs[nprocs].ticks; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
userticks = userticks + tick_procs[nprocs].ticks; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
nprocs++; |
|
|
|
} |
|
|
|
|
|
|
|
if (total_ticks == 0) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
printf("CPU states: %6.2f%% user, ", 100.0 * userticks / total_ticks); |
|
|
|
printf("%6.2f%% system", 100.0 * systemticks / total_ticks); |
|
|
|
printf("%6.2f%% in total\n", 100.0 * (systemticks + userticks) / total_ticks); |
|
|
|
} |
|
|
|
|
|
|
|
u64_t cputicks(struct proc *p1, struct proc *p2, int timemode) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
u64_t t = 0; |
|
|
|
for (i = 0; i < CPUTIMENAMES; i++) |
|
|
|
{ |
|
|
|
if (!CPUTIME(timemode, i)) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (p1->p_endpoint == p2->p_endpoint) |
|
|
|
{ |
|
|
|
{ |
|
|
|
t = t + p2->p_cpucycles[i] - p1->p_cpucycles[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
t = t + p2->p_cpucycles[i]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return t; |
|
|
|
//printf("%6.2f%% kernel, ", 100.0 * kernelticks/ total_ticks);
|
|
|
|
//printf("%6.2f%% idle", 100.0 * idleticks / total_ticks);
|
|
|
|
} |