summaryrefslogtreecommitdiff
path: root/accel-pppd/radius/stat_accm.c
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2011-01-27 08:27:39 +0300
committerDmitry Kozlov <xeb@mail.ru>2011-01-27 08:27:39 +0300
commit673bea74d2beb8d4260355f928499230c7ff9b17 (patch)
tree4b5474b9623f0b6f5a8dbdde48f1dc906fdd322e /accel-pppd/radius/stat_accm.c
parent7f8d3e240fe9544b22846ea05b09515922d1de57 (diff)
downloadaccel-ppp-xebd-673bea74d2beb8d4260355f928499230c7ff9b17.tar.gz
accel-ppp-xebd-673bea74d2beb8d4260355f928499230c7ff9b17.zip
radius: extended statistics calculation
Diffstat (limited to 'accel-pppd/radius/stat_accm.c')
-rw-r--r--accel-pppd/radius/stat_accm.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/accel-pppd/radius/stat_accm.c b/accel-pppd/radius/stat_accm.c
new file mode 100644
index 0000000..9367ceb
--- /dev/null
+++ b/accel-pppd/radius/stat_accm.c
@@ -0,0 +1,96 @@
+#include <string.h>
+
+#include "radius_p.h"
+#include "mempool.h"
+#include "memdebug.h"
+
+struct item_t
+{
+ struct list_head entry;
+ unsigned int val;
+ time_t ts;
+};
+
+struct stat_accm_t
+{
+ pthread_mutex_t lock;
+ struct list_head items;
+ unsigned int items_cnt;
+ unsigned int time;
+ unsigned long total;
+};
+
+static mempool_t item_pool;
+
+struct stat_accm_t *stat_accm_create(unsigned int time)
+{
+ struct stat_accm_t *s = _malloc(sizeof(*s));
+
+ memset(s, 0, sizeof(*s));
+ pthread_mutex_init(&s->lock, NULL);
+ INIT_LIST_HEAD(&s->items);
+ s->time = time;
+
+ return s;
+}
+
+static void stat_accm_clean(struct stat_accm_t *s)
+{
+ struct item_t *it;
+ time_t ts = time(NULL);
+
+ while (!list_empty(&s->items)) {
+ it = list_entry(s->items.next, typeof(*it), entry);
+ if (ts - it->ts > s->time) {
+ list_del(&it->entry);
+ --s->items_cnt;
+ s->total -= it->val;
+ mempool_free(it);
+ } else
+ break;
+ }
+}
+
+void stat_accm_add(struct stat_accm_t *s, unsigned int val)
+{
+ struct item_t *it;
+
+ pthread_mutex_lock(&s->lock);
+
+ stat_accm_clean(s);
+
+ it = mempool_alloc(item_pool);
+ it->ts = time(NULL);
+ it->val = val;
+ list_add_tail(&it->entry, &s->items);
+ ++s->items_cnt;
+ s->total += val;
+
+ pthread_mutex_unlock(&s->lock);
+}
+
+unsigned long stat_accm_get_cnt(struct stat_accm_t *s)
+{
+ pthread_mutex_lock(&s->lock);
+ stat_accm_clean(s);
+ pthread_mutex_unlock(&s->lock);
+
+ return s->items_cnt;
+}
+
+unsigned long stat_accm_get_avg(struct stat_accm_t *s)
+{
+ unsigned long val;
+ pthread_mutex_lock(&s->lock);
+ stat_accm_clean(s);
+ val = s->items_cnt ? s->total/s->items_cnt : 0;
+ pthread_mutex_unlock(&s->lock);
+
+ return val;
+}
+
+static void __init init(void)
+{
+ item_pool = mempool_create(sizeof(struct item_t));
+}
+