diff --git a/apps/top.c b/apps/top.c index 45bbbee6..c6fb2a62 100644 --- a/apps/top.c +++ b/apps/top.c @@ -35,7 +35,27 @@ static int show_cpu = 0; static int collect_commandline = 0; static int cpu_count = 1; -static int widths[] = {3,3,4,3,3,4,4}; +enum header_columns { + COLUMN_PID, + COLUMN_TID, + COLUMN_USER, + COLUMN_VSZ, + COLUMN_SHM, + COLUMN_MEM, + COLUMN_CPUA, + COLUMN_CPU +}; + +static int widths[] = { + [COLUMN_PID] = 3, + [COLUMN_TID] = 3, + [COLUMN_USER] = 4, + [COLUMN_VSZ] = 3, + [COLUMN_SHM] = 3, + [COLUMN_MEM] = 4, + [COLUMN_CPUA] = 4, + [COLUMN_CPU] = 4, +}; struct process { int uid; @@ -45,6 +65,7 @@ struct process { int vsz; int shm; int cpu; + int cpua; char * process; char * command_line; }; @@ -72,7 +93,7 @@ struct process * process_entry(struct dirent *dent) { FILE * f; char line[LINE_LEN]; - int pid = 0, uid = 0, tgid = 0, mem = 0, shm = 0, vsz = 0, cpu = 0; + int pid = 0, uid = 0, tgid = 0, mem = 0, shm = 0, vsz = 0, cpu = 0, cpua = 0; char name[100]; sprintf(tmp, "/proc/%s/status", dent->d_name); @@ -108,10 +129,11 @@ struct process * process_entry(struct dirent *dent) { mem = atoi(tab); } else if (strstr(line, "CpuPermille:") == line) { cpu = strtoul(tab, &tab, 10); - cpu += strtoul(tab, &tab, 10); - cpu += strtoul(tab, &tab, 10); - cpu += strtoul(tab, &tab, 10); - cpu /= 4; + cpua = cpua; + cpua += strtoul(tab, &tab, 10); + cpua += strtoul(tab, &tab, 10); + cpua += strtoul(tab, &tab, 10); + cpua /= 4; } } @@ -128,6 +150,7 @@ struct process * process_entry(struct dirent *dent) { struct process * parent = process_from_pid(tgid); if (parent) { parent->cpu += cpu; + parent->cpua += cpua; } return NULL; } @@ -141,6 +164,7 @@ struct process * process_entry(struct dirent *dent) { out->shm = shm; out->vsz = vsz; out->cpu = cpu; + out->cpua = cpua; out->process = strdup(name); out->command_line = NULL; @@ -149,12 +173,16 @@ struct process * process_entry(struct dirent *dent) { char garbage[1024]; int len; - if ((len = sprintf(garbage, "%d", out->pid)) > widths[0]) widths[0] = len; - if ((len = sprintf(garbage, "%d", out->tid)) > widths[1]) widths[1] = len; - if ((len = sprintf(garbage, "%d", out->vsz)) > widths[3]) widths[3] = len; - if ((len = sprintf(garbage, "%d", out->shm)) > widths[4]) widths[4] = len; - if ((len = sprintf(garbage, "%d.%01d", out->mem / 10, out->mem % 10)) > widths[5]) widths[5] = len; - if ((len = sprintf(garbage, "%d.%01d", out->cpu / 10, out->cpu % 10)) > widths[6]) widths[6] = len; +#define DEC(col, member) if ((len = sprintf(garbage, "%d", out-> member)) > widths[col]) widths[col] = len; +#define PCT(col, member) if ((len = sprintf(garbage, "%d.%01d", out-> member / 10, out-> member % 10)) > widths[col]) widths[col] = len; + + DEC(COLUMN_PID, pid); + DEC(COLUMN_TID, tid); + DEC(COLUMN_VSZ, vsz); + DEC(COLUMN_SHM, shm); + PCT(COLUMN_MEM, mem); + PCT(COLUMN_CPU, cpu); + PCT(COLUMN_CPUA, cpua); struct passwd * p = getpwuid(out->uid); if (p) { @@ -189,21 +217,19 @@ struct process * process_entry(struct dirent *dent) { void print_header(void) { printf("\033[7m"); - if (show_username) { - printf("%-*s ", widths[2], "USER"); - } - printf("%*s ", widths[0], "PID"); - if (show_threads) { - printf("%*s ", widths[1], "TID"); - } - if (show_cpu) { - printf("%*s ", widths[6], "%CPU"); - } - if (show_mem) { - printf("%*s ", widths[5], "%MEM"); - printf("%*s ", widths[3], "VSZ"); - printf("%*s ", widths[4], "SHM"); - } +#define HEADER(col, title) printf("%*s ", widths[col], title) + + HEADER(COLUMN_USER, "USER"); + HEADER(COLUMN_PID, "PID"); + if (show_threads) HEADER(COLUMN_TID, "TID"); + + HEADER(COLUMN_CPU, "%CPU"); + HEADER(COLUMN_CPUA, "ACPU"); + + HEADER(COLUMN_MEM, "%MEM"); + HEADER(COLUMN_VSZ, "VSZ"); + HEADER(COLUMN_SHM, "SHM"); + printf("CMD\033[K\033[0m\n"); } @@ -228,6 +254,8 @@ void print_entry(struct process * out, int width) { sprintf(tmp, "%*d.%01d", widths[6]-2, out->cpu / 10, out->cpu % 10); used += printf("%*s ", widths[6], tmp); printf("\033[0m"); + sprintf(tmp, "%*d.%01d", widths[6]-2, out->cpua / 10, out->cpua % 10); + used += printf("%*s ", widths[6], tmp); } if (show_mem) { char tmp[10]; @@ -305,7 +333,7 @@ static void print_meter(const char * title, const char * label, int width, int f } static void get_cpu_info(int cpus[]) { - FILE * f = fopen("/proc/smp","r"); + FILE * f = fopen("/proc/idle","r"); char buf[4096]; fread(buf, 4096, 1, f); diff --git a/base/usr/include/kernel/process.h b/base/usr/include/kernel/process.h index 0e4c4009..e6eee366 100644 --- a/base/usr/include/kernel/process.h +++ b/base/usr/include/kernel/process.h @@ -172,8 +172,6 @@ struct ProcessorLocal { int cpu_id; union PML * current_pml; - int idle_time; - struct regs * interrupt_registers; #ifdef __x86_64__ diff --git a/kernel/sys/process.c b/kernel/sys/process.c index 37b5b423..e25e7520 100644 --- a/kernel/sys/process.c +++ b/kernel/sys/process.c @@ -1340,25 +1340,24 @@ process_t * spawn_worker_thread(void (*entrypoint)(void * argp), const char * na return proc; } +static void update_one_process(uint64_t clock_ticks, uint64_t perf_scale, process_t * proc) { + proc->usage[3] = proc->usage[2]; + proc->usage[2] = proc->usage[1]; + proc->usage[1] = proc->usage[0]; + proc->usage[0] = (1000 * (proc->time_total - proc->time_prev)) / (clock_ticks * perf_scale); + proc->time_prev = proc->time_total; +} + void update_process_usage(uint64_t clock_ticks, uint64_t perf_scale) { spin_lock(tree_lock); foreach(lnode, process_list) { process_t * proc = lnode->value; - proc->usage[3] = proc->usage[2]; - proc->usage[2] = proc->usage[1]; - proc->usage[1] = proc->usage[0]; - proc->usage[0] = (1000 * (proc->time_total - proc->time_prev)) / (clock_ticks * perf_scale); - proc->time_prev = proc->time_total; + update_one_process(clock_ticks, perf_scale, proc); } spin_unlock(tree_lock); /* Now use idle tasks to calculator processor activity? */ for (int i = 0; i < processor_count; ++i) { process_t * proc = processor_local_data[i].kernel_idle_task; - proc->usage[3] = proc->usage[2]; - proc->usage[2] = proc->usage[1]; - proc->usage[1] = proc->usage[0]; - proc->usage[0] = (1000 * (proc->time_total - proc->time_prev)) / (clock_ticks * perf_scale); - proc->time_prev = proc->time_total; - processor_local_data[i].idle_time = (proc->usage[0] + proc->usage[1] + proc->usage[2] + proc->usage[3]) / 4; + update_one_process(clock_ticks, perf_scale, proc); } } diff --git a/kernel/vfs/procfs.c b/kernel/vfs/procfs.c index c01b3326..d5b71bc5 100644 --- a/kernel/vfs/procfs.c +++ b/kernel/vfs/procfs.c @@ -648,15 +648,17 @@ static ssize_t pci_func(fs_node_t *node, off_t offset, size_t size, uint8_t *buf } #endif -static ssize_t smp_func(fs_node_t *node, off_t offset, size_t size, uint8_t *buffer) { +static ssize_t idle_func(fs_node_t *node, off_t offset, size_t size, uint8_t *buffer) { char * buf = malloc(4096); unsigned int soffset = 0; for (int i = 0; i < processor_count; ++i) { - soffset += snprintf(&buf[soffset], 100, "%d: %d %d\n", + soffset += snprintf(&buf[soffset], 100, "%d: %4d %4d %d %4d\n", i, - processor_local_data[i].current_process->id, - processor_local_data[i].idle_time + processor_local_data[i].kernel_idle_task->usage[0], + processor_local_data[i].kernel_idle_task->usage[1], + processor_local_data[i].kernel_idle_task->usage[2], + processor_local_data[i].kernel_idle_task->usage[3] ); } @@ -683,7 +685,7 @@ static struct procfs_entry std_entries[] = { {-8, "modules", modules_func}, {-9, "filesystems", filesystems_func}, {-10,"loader", loader_func}, - {-11,"smp", smp_func}, + {-11,"idle", idle_func}, #ifdef __x86_64__ {-12,"irq", irq_func}, {-13,"pat", pat_func},