summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-06-02 22:20:40 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2010-06-02 22:20:40 +0200
commitacb60628f53ba1fc29d1a554683acdb03f961c6f (patch)
treebe767e6d7995dee6708b7530b7dabe74d23b491e /lib
parent4461b8979143bd13024663622c419646a1db0c85 (diff)
downloadbird-acb60628f53ba1fc29d1a554683acdb03f961c6f.tar
bird-acb60628f53ba1fc29d1a554683acdb03f961c6f.zip
Implements command that shows memory usage.
Diffstat (limited to 'lib')
-rw-r--r--lib/event.c1
-rw-r--r--lib/mempool.c22
-rw-r--r--lib/resource.c38
-rw-r--r--lib/resource.h5
-rw-r--r--lib/slab.c38
5 files changed, 99 insertions, 5 deletions
diff --git a/lib/event.c b/lib/event.c
index ce5e81c..916cf55 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -50,6 +50,7 @@ static struct resclass ev_class = {
sizeof(event),
(void (*)(resource *)) ev_postpone,
ev_dump,
+ NULL,
NULL
};
diff --git a/lib/mempool.c b/lib/mempool.c
index 0cb06b5..65072f9 100644
--- a/lib/mempool.c
+++ b/lib/mempool.c
@@ -43,13 +43,15 @@ struct linpool {
static void lp_free(resource *);
static void lp_dump(resource *);
static resource *lp_lookup(resource *, unsigned long);
+static size_t lp_memsize(resource *r);
static struct resclass lp_class = {
"LinPool",
sizeof(struct linpool),
lp_free,
lp_dump,
- lp_lookup
+ lp_lookup,
+ lp_memsize
};
/**
@@ -235,6 +237,24 @@ lp_dump(resource *r)
m->total_large);
}
+static size_t
+lp_memsize(resource *r)
+{
+ linpool *m = (linpool *) r;
+ struct lp_chunk *c;
+ int cnt = 0;
+
+ for(c=m->first; c; c=c->next)
+ cnt++;
+ for(c=m->first_large; c; c=c->next)
+ cnt++;
+
+ return ALLOC_OVERHEAD + sizeof(struct linpool) +
+ cnt * (ALLOC_OVERHEAD + sizeof(sizeof(struct lp_chunk))) +
+ m->total + m->total_large;
+}
+
+
static resource *
lp_lookup(resource *r, unsigned long a)
{
diff --git a/lib/resource.c b/lib/resource.c
index 5ba23f1..24164ec 100644
--- a/lib/resource.c
+++ b/lib/resource.c
@@ -37,13 +37,15 @@ struct pool {
static void pool_dump(resource *);
static void pool_free(resource *);
static resource *pool_lookup(resource *, unsigned long);
+static size_t pool_memsize(resource *P);
static struct resclass pool_class = {
"Pool",
sizeof(pool),
pool_free,
pool_dump,
- pool_lookup
+ pool_lookup,
+ pool_memsize
};
pool root_pool;
@@ -95,6 +97,19 @@ pool_dump(resource *P)
indent -= 3;
}
+static size_t
+pool_memsize(resource *P)
+{
+ pool *p = (pool *) P;
+ resource *r;
+ size_t sum = sizeof(pool) + ALLOC_OVERHEAD;
+
+ WALK_LIST(r, p->inside)
+ sum += rmemsize(r);
+
+ return sum;
+}
+
static resource *
pool_lookup(resource *P, unsigned long a)
{
@@ -177,6 +192,17 @@ rdump(void *res)
debug("NULL\n");
}
+size_t
+rmemsize(void *res)
+{
+ resource *r = res;
+ if (!r)
+ return 0;
+ if (!r->class->memsize)
+ return r->class->size + ALLOC_OVERHEAD;
+ return r->class->memsize(r);
+}
+
/**
* ralloc - create a resource
* @p: pool to create the resource in
@@ -277,12 +303,20 @@ mbl_lookup(resource *r, unsigned long a)
return NULL;
}
+static size_t
+mbl_memsize(resource *r)
+{
+ struct mblock *m = (struct mblock *) r;
+ return ALLOC_OVERHEAD + sizeof(struct mblock) + m->size;
+}
+
static struct resclass mb_class = {
"Memory",
0,
mbl_free,
mbl_debug,
- mbl_lookup
+ mbl_lookup,
+ mbl_memsize
};
/**
diff --git a/lib/resource.h b/lib/resource.h
index 8dd441f..5cb5e27 100644
--- a/lib/resource.h
+++ b/lib/resource.h
@@ -26,8 +26,12 @@ struct resclass {
void (*free)(resource *); /* Freeing function */
void (*dump)(resource *); /* Dump to debug output */
resource *(*lookup)(resource *, unsigned long); /* Look up address (only for debugging) */
+ size_t (*memsize)(resource *); /* Return size of memory used by the resource, may be NULL */
};
+/* Estimate of system allocator overhead per item, for memory consumtion stats */
+#define ALLOC_OVERHEAD 8
+
/* Generic resource manipulation */
typedef struct pool pool;
@@ -36,6 +40,7 @@ void resource_init(void);
pool *rp_new(pool *, char *); /* Create new pool */
void rfree(void *); /* Free single resource */
void rdump(void *); /* Dump to debug output */
+size_t rmemsize(void *res); /* Return size of memory used by the resource */
void rlookup(unsigned long); /* Look up address (only for debugging) */
void rmove(void *, pool *); /* Move to a different pool */
diff --git a/lib/slab.c b/lib/slab.c
index 8cce52f..af6b50b 100644
--- a/lib/slab.c
+++ b/lib/slab.c
@@ -41,6 +41,7 @@
static void slab_free(resource *r);
static void slab_dump(resource *r);
static resource *slab_lookup(resource *r, unsigned long addr);
+static size_t slab_memsize(resource *r);
#ifdef FAKE_SLAB
@@ -58,7 +59,8 @@ static struct resclass sl_class = {
"FakeSlab",
sizeof(struct slab),
slab_free,
- slab_dump
+ slab_dump,
+ slab_memsize
};
struct sl_obj {
@@ -116,6 +118,20 @@ slab_dump(resource *r)
debug("(%d objects per %d bytes)\n", cnt, s->size);
}
+static size_t
+slab_memsize(resource *r)
+{
+ slab *s = (slab *) r;
+ int cnt = 0;
+ struct sl_obj *o;
+
+ WALK_LIST(o, s->objs)
+ cnt++;
+
+ return ALLOC_OVERHEAD + sizeof(struct slab) + cnt * (ALLOC_OVERHEAD + s->size);
+}
+
+
#else
/*
@@ -136,7 +152,8 @@ static struct resclass sl_class = {
sizeof(struct slab),
slab_free,
slab_dump,
- slab_lookup
+ slab_lookup,
+ slab_memsize
};
struct sl_head {
@@ -324,6 +341,23 @@ slab_dump(resource *r)
debug("(%de+%dp+%df blocks per %d objs per %d bytes)\n", ec, pc, fc, s->objs_per_slab, s->obj_size);
}
+static size_t
+slab_memsize(resource *r)
+{
+ slab *s = (slab *) r;
+ int heads = 0;
+ struct sl_head *h;
+
+ WALK_LIST(h, s->empty_heads)
+ heads++;
+ WALK_LIST(h, s->partial_heads)
+ heads++;
+ WALK_LIST(h, s->full_heads)
+ heads++;
+
+ return ALLOC_OVERHEAD + sizeof(struct slab) + heads * (ALLOC_OVERHEAD + SLAB_SIZE);
+}
+
static resource *
slab_lookup(resource *r, unsigned long a)
{