Add ${top_time} sorting processes by CPU time
authorAlexander Graf <agraf@znc.in>
Sat, 7 Feb 2009 14:01:50 +0000 (15:01 +0100)
committerAlexander Graf <agraf@znc.in>
Sat, 7 Feb 2009 14:01:50 +0000 (15:01 +0100)
doc/variables.xml
src/conky.c
src/conky.h
src/linux.c
src/text_object.h
src/top.c
src/top.h

index d82456b..2c523fa 100644 (file)
 
        <varlistentry>
                <term>
+                       <command><option>top_time</option></command>
+                       <option>type, num</option>
+               </term>
+               <listitem>
+                       Same as top, except sorted by total CPU time instead of current CPU usage
+                       <para></para></listitem>
+       </varlistentry>
+
+       <varlistentry>
+               <term>
                        <command><option>totalup</option></command>
                        <option>net</option>
                </term>
index 4a496d5..0cd3164 100644 (file)
@@ -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");
index 447ab6e..679d5ee 100644 (file)
@@ -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;
index 9e5f6a2..f3a8ef9 100644 (file)
@@ -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();
 }
 
index 6dae129..687647d 100644 (file)
@@ -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,
index 9528818..fae248b 100644 (file)
--- 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);
 }
index 06eddef..6f41fe3 100644 (file)
--- 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_ */