]> git.webhop.me Git - lcd4linux.git/commitdiff
[lcd4linux @ 2004-01-18 09:01:45 by reinelt]
authorreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sun, 18 Jan 2004 09:01:45 +0000 (09:01 +0000)
committerreinelt <reinelt@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Sun, 18 Jan 2004 09:01:45 +0000 (09:01 +0000)
/proc/stat parsing finished

git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@319 3ae390bd-cb1e-0410-b409-cd5a39f66f1f

hash.c
hash.h
lcd4linux.conf.sample
plugin_proc_stat.c
timer.c

diff --git a/hash.c b/hash.c
index 56a633065ceebd2f2a89c4eedc6cf01bed155675..235a9bc19996629abcd5870430bf5e52eaad6854 100644 (file)
--- a/hash.c
+++ b/hash.c
@@ -1,4 +1,4 @@
-/* $Id: hash.c,v 1.4 2004/01/18 06:54:08 reinelt Exp $
+/* $Id: hash.c,v 1.5 2004/01/18 09:01:45 reinelt Exp $
  *
  * hashes (associative arrays)
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: hash.c,v $
+ * Revision 1.5  2004/01/18 09:01:45  reinelt
+ * /proc/stat parsing finished
+ *
  * Revision 1.4  2004/01/18 06:54:08  reinelt
  * bug in expr.c fixed (thanks to Xavier)
  * some progress with /proc/stat parsing
@@ -60,6 +63,9 @@
 #include "hash.h"
 
 
+#define FILTER_SLOTS 64
+
+
 // bsearch compare function for hash entries
 static int hash_lookup_f (const void *a, const void *b)
 {
@@ -80,21 +86,21 @@ static int hash_sort_f (const void *a, const void *b)
 }
 
 
-
-// insert a key/val pair into the hash table
+// search an entry in the hash table:
 // If the table is flagged "sorted", the entry is looked
 // up using the bsearch function. If the table is 
-// unsorted, it will be searched in a linear way if the entry 
-// does already exist.
-// If the entry does already exist, it will be overwritten,
-// and the table stays sorted (if it has been before).
-// Otherwise, the entry is appended at the end, and 
-// the table will be flagged 'unsorted' afterwards
+// unsorted, it will be searched in a linear way
 
-void hash_set (HASH *Hash, char *key, char *val)
+static HASH_ITEM* hash_lookup (HASH *Hash, char *key, int sortit)
 {
   HASH_ITEM *Item=NULL;
   
+  // maybe sort the array
+  if (sortit && !Hash->sorted) {
+    qsort(Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_sort_f);
+    Hash->sorted=1;
+  }
+  
   // lookup using bsearch
   if (Hash->sorted) {
     Item=bsearch(key, Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_lookup_f);
@@ -110,37 +116,127 @@ void hash_set (HASH *Hash, char *key, char *val)
       }
     }
   }
+  
+  return Item;
+  
+}
+
+
+// insert a key/val pair into the hash table
+// If the entry does already exist, it will be overwritten,
+// and the table stays sorted (if it has been before).
+// Otherwise, the entry is appended at the end, and 
+// the table will be flagged 'unsorted' afterwards
+
+static HASH_ITEM* hash_set_string (HASH *Hash, char *key, char *val)
+{
+  HASH_ITEM *Item;
+  
+  Item=hash_lookup (Hash, key, 0);
 
   // entry already exists?
   if (Item!=NULL) {
     if (Item->val) free (Item->val);
-    Item->val=strdup(val);
-    return;
+    Item->val = strdup(val);
+    return Item;
   }
 
   // add entry
   Hash->sorted=0;
   Hash->nItems++;
   Hash->Items=realloc(Hash->Items,Hash->nItems*sizeof(HASH_ITEM));
-  Hash->Items[Hash->nItems-1].key=strdup(key);
-  Hash->Items[Hash->nItems-1].val=strdup(val);
+
+  Item=&(Hash->Items[Hash->nItems-1]);
+  
+  Item->key   = strdup(key);
+  Item->val   = strdup(val);
+  Item->Slot  = NULL;
+  
+  return Item;
 }
 
 
-char *hash_get (HASH *Hash, char *key)
+// insert a string into the hash table
+void hash_set (HASH *Hash, char *key, char *val)
+{
+  hash_set_string (Hash, key, val);
+}
+
+
+// insert a string into the hash table
+// convert it into a number, and store it in the
+// filter table, too
+void hash_set_filter (HASH *Hash, char *key, char *val)
 {
+  double number=atof(val);
   HASH_ITEM *Item;
   
-  if (!Hash->sorted) {
-    qsort(Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_sort_f);
-    Hash->sorted=1;
+  Item=hash_set_string (Hash, key, val);
+  
+  // allocate filter table
+  if (Item->Slot==NULL) {
+    Item->Slot  = malloc(FILTER_SLOTS*sizeof(HASH_SLOT));
+    memset(Item->Slot, 0, FILTER_SLOTS*sizeof(HASH_SLOT));
   }
   
-  Item=bsearch(key, Hash->Items, Hash->nItems, sizeof(HASH_ITEM), hash_lookup_f);
+  // shift filter table
+  memmove (Item->Slot+1, Item->Slot, (FILTER_SLOTS-1)*sizeof(HASH_SLOT));
+
+  // set first entry
+  gettimeofday(&(Item->Slot[0].time), NULL);
+  Item->Slot[0].val=number;
+}
 
+
+// get a string from the hash table
+char *hash_get (HASH *Hash, char *key)
+{
+  HASH_ITEM *Item=hash_lookup(Hash, key, 1);
   return Item?Item->val:NULL;
 }
 
+// get a delta value from the filter table
+double hash_get_filter (HASH *Hash, char *key, int delay)
+{
+  HASH_ITEM *Item;
+  struct timeval now, end;
+  int i;
+  double dv, dt;
+  
+  // lookup item
+  Item=hash_lookup(Hash, key, 1);
+  if (Item==NULL) return 0.0;
+  if (Item->Slot==NULL) return 0.0;
+  
+  // prepare timing values
+  now=Item->Slot[0].time;
+  end.tv_sec  = now.tv_sec;
+  end.tv_usec = now.tv_usec-1000*delay;
+  if (end.tv_usec<0) {
+    end.tv_sec--;
+    end.tv_usec += 1000000;
+  }
+  
+  // search filter slot
+  for (i=1; i<FILTER_SLOTS; i++) {
+    if (Item->Slot[i].time.tv_sec==0) break;
+    if (timercmp(&Item->Slot[i].time, &end, <)) break;
+  }
+
+  // empty slot => use the one before
+  if (Item->Slot[i].time.tv_sec==0) i--;
+  
+  // not enough slots available...
+  if (i==0) return 0.0;
+
+  // delta value, delta time
+  dv = Item->Slot[0].val - Item->Slot[i].val; 
+  dt = (now.tv_sec - Item->Slot[i].time.tv_sec) + (now.tv_usec - Item->Slot[i].time.tv_usec)/1000000.0; 
+
+  if (dt > 0.0 && dv >= 0.0) return dv/dt;
+  return 0.0;
+}
+
 
 void hash_destroy (HASH *Hash)
 {
@@ -150,8 +246,9 @@ void hash_destroy (HASH *Hash)
     
     // free all entries
     for (i=0;i<Hash->nItems; i++) {
-      if (Hash->Items[i].key) free (Hash->Items[i].key);
-      if (Hash->Items[i].val) free (Hash->Items[i].val);
+      if (Hash->Items[i].key)  free (Hash->Items[i].key);
+      if (Hash->Items[i].val)  free (Hash->Items[i].val);
+      if (Hash->Items[i].Slot) free (Hash->Items[i].Slot);
     }
     
     // free hash table
diff --git a/hash.h b/hash.h
index 7ab163489095597b349bd458e9d09e28790daeb5..f29ccdb937613b91bf403b7c2fe0bcb7930a9d88 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -1,4 +1,4 @@
-/* $Id: hash.h,v 1.4 2004/01/16 11:12:26 reinelt Exp $
+/* $Id: hash.h,v 1.5 2004/01/18 09:01:45 reinelt Exp $
  *
  * hashes (associative arrays)
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: hash.h,v $
+ * Revision 1.5  2004/01/18 09:01:45  reinelt
+ * /proc/stat parsing finished
+ *
  * Revision 1.4  2004/01/16 11:12:26  reinelt
  * some bugs in plugin_xmms fixed, parsing moved to own function
  * plugin_proc_stat nearly finished
 #ifndef _HASH_H_
 #define _HASH_H_
 
+
+// struct timeval
+#include <sys/time.h>
+
+
 typedef struct {
-  char *key;
-  char *val;
+  struct timeval time;
+  double val;
+} HASH_SLOT;
+
+
+typedef struct {
+  char      *key;
+  char      *val;
+  HASH_SLOT *Slot;
 } HASH_ITEM;
 
 
@@ -59,19 +74,10 @@ typedef struct {
 } HASH;
 
 
-typedef struct {
-  // struct timeval time;
-  double val;
-} FILTER_SLOT;
-
-typedef struct {
-  char        *key;
-  int         nSlots;
-  FILTER_SLOT *Slots;
-} FILTER_ITEM;
-
-void  hash_set     (HASH *Hash, char *key, char *val);
-char *hash_get     (HASH *Hash, char *key);
-void  hash_destroy (HASH *Hash);
+void   hash_set        (HASH *Hash, char *key, char *val);
+void   hash_set_filter (HASH *Hash, char *key, char *val);
+char  *hash_get        (HASH *Hash, char *key);
+double hash_get_filter (HASH *Hash, char *key, int delay);
+void   hash_destroy    (HASH *Hash);
 
 #endif
index 7d48af38783918f150c10bd17e497428819f38ca..40822105aed69c356c0c233f168b6742ad824569 100644 (file)
@@ -35,6 +35,17 @@ Widget RAM {
     update tick
 }
 
+Widget Busy {
+    class 'Text'
+    expression cpu('busy', 500)
+    prefix 'Busy '     
+    postfix '%'        
+    width 10   
+    precision 1
+    align 'R'  
+    update tick        
+}      
+
 Widget Load {
     class 'Text'
     expression loadavg(1)
@@ -56,6 +67,7 @@ Layout Default {
        Col10 'RAM'
     }
     Row3 {
+       Col1 'Busy'
     }
     Row4 {
        Col1 'Load'
index 5c9f65eafb2b4704dbbfe99c581f4e1ddfb7ee4a..385799526011106d1dae7067037a50d0ef053daf 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: plugin_proc_stat.c,v 1.4 2004/01/18 06:54:08 reinelt Exp $
+/* $Id: plugin_proc_stat.c,v 1.5 2004/01/18 09:01:45 reinelt Exp $
  *
  * plugin for /proc/stat parsing
  *
@@ -23,6 +23,9 @@
  *
  *
  * $Log: plugin_proc_stat.c,v $
+ * Revision 1.5  2004/01/18 09:01:45  reinelt
+ * /proc/stat parsing finished
+ *
  * Revision 1.4  2004/01/18 06:54:08  reinelt
  * bug in expr.c fixed (thanks to Xavier)
  * some progress with /proc/stat parsing
@@ -67,6 +70,7 @@
 
 static HASH Stat = { 0, 0, NULL };
 
+
 static int renew(int msec)
 {
   static struct timeval end = {0, 0};
@@ -89,13 +93,10 @@ static int renew(int msec)
 
 static void hash_set1 (char *key1, char *val) 
 {
-  double number;
-  
-  number=atof(val);
-  
-  hash_set (&Stat, key1, val);
+  hash_set_filter (&Stat, key1, val);
 }
 
+
 static void hash_set2 (char *key1, char *key2, char *val) 
 {
   char key[32];
@@ -104,6 +105,7 @@ static void hash_set2 (char *key1, char *key2, char *val)
   hash_set1 (key, val);
 }
 
+
 static void hash_set3 (char *key1, char *key2, char *key3, char *val) 
 {
   char key[32];
@@ -120,8 +122,7 @@ static int parse_proc_stat (void)
   // update every 10 msec
   if (!renew(10)) return 0;
   
-  // stream=fopen("/proc/stat", "r");
-  stream=fopen("proc_stat", "r");
+  stream=fopen("/proc/stat", "r");
   if (stream==NULL) {
     error ("fopen(/proc/stat) failed: %s", strerror(errno));
     return -1;
@@ -191,26 +192,71 @@ static int parse_proc_stat (void)
   return 0;
 }
 
-static void my_proc_stat (RESULT *result, RESULT *arg1)
+
+static void my_proc_stat (RESULT *result, int argc, RESULT *argv[])
 {
-  char *key, *val;
-  
+  char  *string;
+  double number;
+
   if (parse_proc_stat()<0) {
     SetResult(&result, R_STRING, ""); 
     return;
   }
 
-  key=R2S(arg1);
-  val=hash_get(&Stat, key);
-  if (val==NULL) val="";
+  switch (argc) {
+  case 1:
+    string=hash_get(&Stat, R2S(argv[0]));
+    if (string==NULL) string="";
+    SetResult(&result, R_STRING, string); 
+    break;
+  case 2:
+    number=hash_get_filter(&Stat, R2S(argv[0]), R2N(argv[1]));
+    SetResult(&result, R_NUMBER, &number); 
+    break;
+  default:
+    error ("proc_stat(): wrong number of parameters");
+    SetResult(&result, R_STRING, ""); 
+  }
+}
+
+
+static void my_cpu (RESULT *result, RESULT *arg1, RESULT *arg2)
+{
+  char *key;
+  int delay;
+  double value;
+  double cpu_user, cpu_nice, cpu_system, cpu_idle, cpu_total;
+  
+  if (parse_proc_stat()<0) {
+    SetResult(&result, R_STRING, ""); 
+    return;
+  }
+  
+  key   = R2S(arg1);
+  delay = R2N(arg2);
+  
+  cpu_user   = hash_get_filter(&Stat, "cpu.user",   delay);
+  cpu_nice   = hash_get_filter(&Stat, "cpu.nice",   delay);
+  cpu_system = hash_get_filter(&Stat, "cpu.system", delay);
+  cpu_idle   = hash_get_filter(&Stat, "cpu.idle",   delay);
 
-  SetResult(&result, R_STRING, val); 
+  cpu_total  = cpu_user+cpu_nice+cpu_system+cpu_idle;
+  
+  if      (strcasecmp(key, "user"  )==0) value=cpu_user;
+  else if (strcasecmp(key, "nice"  )==0) value=cpu_nice;
+  else if (strcasecmp(key, "system")==0) value=cpu_system;
+  else if (strcasecmp(key, "idle"  )==0) value=cpu_idle;
+  else if (strcasecmp(key, "busy"  )==0) value=cpu_total-cpu_idle;
+  
+  value = 100*value/cpu_total;
+  
+  SetResult(&result, R_NUMBER, &value); 
 }
 
 
 int plugin_init_proc_stat (void)
 {
-  AddFunction ("stat", 1, my_proc_stat);
+  AddFunction ("proc_stat", -1, my_proc_stat);
+  AddFunction ("cpu", 2, my_cpu);
   return 0;
 }
-
diff --git a/timer.c b/timer.c
index f85998d99e67e00a431576e0203220ebc39fc6fd..86b733e42260ff8c1b4c51760a8f217937e31228 100644 (file)
--- a/timer.c
+++ b/timer.c
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.1 2004/01/13 08:18:20 reinelt Exp $
+/* $Id: timer.c,v 1.2 2004/01/18 09:01:45 reinelt Exp $
  *
  * generic timer handling
  *
@@ -21,6 +21,9 @@
  *
  *
  * $Log: timer.c,v $
+ * Revision 1.2  2004/01/18 09:01:45  reinelt
+ * /proc/stat parsing finished
+ *
  * Revision 1.1  2004/01/13 08:18:20  reinelt
  * timer queues added
  * liblcd4linux deactivated turing transformation to new layout
@@ -142,11 +145,6 @@ int timer_process (struct timespec *delay)
     }
   }
 
-  if (flag) {
-    // Fixme: if at least one timer has been processed, do a flush()
-    
-  }
-
   // find next timer
   flag=1;
   min=-1;