kernel: more sensible idle tracking
This commit is contained in:
parent
780aa1b534
commit
bafc85f675
84
apps/top.c
84
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);
|
||||
|
||||
|
|
|
@ -172,8 +172,6 @@ struct ProcessorLocal {
|
|||
int cpu_id;
|
||||
union PML * current_pml;
|
||||
|
||||
int idle_time;
|
||||
|
||||
struct regs * interrupt_registers;
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in New Issue