From 9c679bf33f0241cd857eb86dc9b5f748c9017dcd Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Sat, 7 Feb 2009 15:01:50 +0100 Subject: [PATCH] Add ${top_time} sorting processes by CPU time --- doc/variables.xml | 10 ++++++ src/conky.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++- src/conky.h | 3 +- src/linux.c | 2 +- src/text_object.h | 1 + src/top.c | 18 ++++++++-- src/top.h | 2 +- 7 files changed, 117 insertions(+), 6 deletions(-) diff --git a/doc/variables.xml b/doc/variables.xml index d82456b3..2c523faf 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -2103,6 +2103,16 @@ + + + + + + + Same as top, except sorted by total CPU time instead of current CPU usage + + + diff --git a/src/conky.c b/src/conky.c index 4a496d52..0cd3164b 100644 --- a/src/conky.c +++ b/src/conky.c @@ -125,7 +125,7 @@ enum { LEFT_SPACER, RIGHT_SPACER } use_spacer; -int top_cpu, top_mem; +int top_cpu, top_mem, top_time; #define TO_X 1 #define TO_STDOUT 2 static int output_methods; @@ -2310,6 +2310,46 @@ static struct text_object *construct_text_object(const char *s, ERR("invalid args given for top"); return NULL; } + END OBJ(top_time, INFO_TOP) + char buf[64]; + int n; + + if (!arg) { + ERR("top_time needs arguments"); + obj->type = OBJ_text; + obj->data.s = strndup("${top_time}", text_buffer_size); + return NULL; + } + if (sscanf(arg, "%63s %i", buf, &n) == 2) { + if (strcmp(buf, "name") == EQUAL) { + obj->data.top.type = TOP_NAME; + } else if (strcmp(buf, "cpu") == EQUAL) { + obj->data.top.type = TOP_CPU; + } else if (strcmp(buf, "pid") == EQUAL) { + obj->data.top.type = TOP_PID; + } else if (strcmp(buf, "mem") == EQUAL) { + obj->data.top.type = TOP_MEM; + } else if (strcmp(buf, "time") == EQUAL) { + obj->data.top.type = TOP_TIME; + } else if (strcmp(buf, "mem_res") == EQUAL) { + obj->data.top.type = TOP_MEM_RES; + } else if (strcmp(buf, "mem_vsize") == EQUAL) { + obj->data.top.type = TOP_MEM_VSIZE; + } else { + ERR("invalid arg for top"); + return NULL; + } + if (n < 1 || n > 10) { + CRIT_ERR("invalid arg for top"); + return NULL; + } else { + obj->data.top.num = n - 1; + top_time = 1; + } + } else { + ERR("invalid args given for top"); + return NULL; + } END OBJ(addr, INFO_NET) if (arg) { obj->data.net = get_net_stat(arg); @@ -5223,6 +5263,50 @@ static void generate_text_internal(char *p, int p_max_size, ERR("Top index < 0 or > 10: %d\n", obj->data.top.num); } } + OBJ(top_time) { + if (obj->data.top.num >= 0 && obj->data.top.num < 10) { + char *timeval; + + switch (obj->data.top.type) { + case TOP_NAME: + snprintf(p, 16, "%-15s", + cur->time[obj->data.top.num]->name); + break; + case TOP_CPU: + snprintf(p, 7, "%6.2f", + cur->time[obj->data.top.num]->amount); + break; + case TOP_PID: + snprintf(p, 6, "%5i", + cur->time[obj->data.top.num]->pid); + break; + case TOP_MEM: + snprintf(p, 7, "%6.2f", + cur->time[obj->data.top.num]->totalmem); + break; + case TOP_TIME: + timeval = format_time( + cur->time[obj->data.top.num]->total_cpu_time, + 9); + snprintf(p, 10, "%9s", timeval); + free(timeval); + break; + case TOP_MEM_RES: + human_readable(cur->cpu[obj->data.top.num]->rss, + p, 255); + break; + case TOP_MEM_VSIZE: + human_readable(cur->cpu[obj->data.top.num]->vsize, + p, 255); + break; + default: + ERR("Unhandled top data type: %d\n", + obj->data.top.type); + } + } else { + ERR("Top index < 0 or > 10: %d\n", obj->data.top.num); + } + } OBJ(tail) { if (current_update_time - obj->data.tail.last_update < obj->data.tail.interval) { @@ -7101,6 +7185,7 @@ static void set_default_configurations(void) cpu_separate = 0; short_units = 0; top_mem = 0; + top_time = 0; #ifdef MPD mpd_set_host("localhost"); mpd_set_port("6600"); diff --git a/src/conky.h b/src/conky.h index 447ab6e2..679d5ee8 100644 --- a/src/conky.h +++ b/src/conky.h @@ -250,6 +250,7 @@ struct information { struct dns_data nameserver_info; struct process *cpu[10]; struct process *memu[10]; + struct process *time[10]; struct process *first_process; unsigned long looped; struct entropy_s entropy; @@ -278,7 +279,7 @@ enum { #define KFLAG_ISSET(a) info.kflags & a /* defined in conky.c, needed by top.c */ -extern int top_cpu, top_mem; +extern int top_cpu, top_mem, top_time; /* defined in conky.c, needed by top.c */ extern int cpu_separate; diff --git a/src/linux.c b/src/linux.c index 9e5f6a2c..f3a8ef9b 100644 --- a/src/linux.c +++ b/src/linux.c @@ -2086,7 +2086,7 @@ void get_powerbook_batt_info(char *buffer, size_t n, int i) void update_top(void) { show_nice_processes = 1; - process_find_top(info.cpu, info.memu); + process_find_top(info.cpu, info.memu, info.time); info.first_process = get_first_process(); } diff --git a/src/text_object.h b/src/text_object.h index 6dae1293..687647d3 100644 --- a/src/text_object.h +++ b/src/text_object.h @@ -160,6 +160,7 @@ enum text_object_type { OBJ_if_running, OBJ_top, OBJ_top_mem, + OBJ_top_time, OBJ_tail, OBJ_head, OBJ_lines, diff --git a/src/top.c b/src/top.c index 95288188..fae248b1 100644 --- a/src/top.c +++ b/src/top.c @@ -440,6 +440,12 @@ int compare_mem(struct process *a, struct process *b) } } +/* CPU time comparision function for insert_sp_element */ +int compare_time(struct process *a, struct process *b) +{ + return b->total_cpu_time - a->total_cpu_time; +} + /* insert this process into the list in a sorted fashion, * or destroy it if it doesn't fit on the list */ int insert_sp_element(struct sorted_process *sp_cur, @@ -517,14 +523,16 @@ void sp_acopy(struct sorted_process *sp_head, struct process **ar, int max_size) * Results are stored in the cpu,mem arrays in decreasing order[0-9]. * * ****************************************************************** */ -void process_find_top(struct process **cpu, struct process **mem) +void process_find_top(struct process **cpu, struct process **mem, + struct process **time) { struct sorted_process *spc_head = NULL, *spc_tail = NULL, *spc_cur = NULL; struct sorted_process *spm_head = NULL, *spm_tail = NULL, *spm_cur = NULL; + struct sorted_process *spt_head = NULL, *spt_tail = NULL, *spt_cur = NULL; struct process *cur_proc = NULL; unsigned long long total = 0; - if (!top_cpu && !top_mem) { + if (!top_cpu && !top_mem && !top_time) { return; } @@ -546,8 +554,14 @@ void process_find_top(struct process **cpu, struct process **mem) insert_sp_element(spm_cur, &spm_head, &spm_tail, MAX_SP, &compare_mem); } + if (top_time) { + spt_cur = malloc_sp(cur_proc); + insert_sp_element(spt_cur, &spt_head, &spt_tail, MAX_SP, + &compare_time); + } cur_proc = cur_proc->next; } sp_acopy(spc_head, cpu, MAX_SP); sp_acopy(spm_head, mem, MAX_SP); + sp_acopy(spt_head, time, MAX_SP); } diff --git a/src/top.h b/src/top.h index 06eddef7..6f41fe31 100644 --- a/src/top.h +++ b/src/top.h @@ -116,6 +116,6 @@ struct sorted_process { }; /* Pointer to head of process list */ -void process_find_top(struct process **, struct process **); +void process_find_top(struct process **, struct process **, struct process **); #endif /* _top_h_ */