From acb60628f53ba1fc29d1a554683acdb03f961c6f Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 2 Jun 2010 22:20:40 +0200 Subject: Implements command that shows memory usage. --- lib/event.c | 1 + lib/mempool.c | 22 +++++++++++++++++++++- lib/resource.c | 38 ++++++++++++++++++++++++++++++++++++-- lib/resource.h | 5 +++++ lib/slab.c | 38 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 99 insertions(+), 5 deletions(-) (limited to 'lib') 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) { -- cgit v1.2.3