aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hash.c139
-rw-r--r--hash.h40
-rw-r--r--lcd4linux.conf.sample12
-rw-r--r--plugin_proc_stat.c80
-rw-r--r--timer.c10
5 files changed, 220 insertions, 61 deletions
diff --git a/hash.c b/hash.c
index 56a6330..235a9bc 100644
--- 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 7ab1634..f29ccdb 100644
--- 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
@@ -46,9 +49,21 @@
#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
diff --git a/lcd4linux.conf.sample b/lcd4linux.conf.sample
index 7d48af3..4082210 100644
--- a/lcd4linux.conf.sample
+++ b/lcd4linux.conf.sample
@@ -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'
diff --git a/plugin_proc_stat.c b/plugin_proc_stat.c
index 5c9f65e..3857995 100644
--- a/plugin_proc_stat.c
+++ b/plugin_proc_stat.c
@@ -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 f85998d..86b733e 100644
--- 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;