diff options
author | Martin Mares <mj@ucw.cz> | 2000-05-09 00:33:38 +0200 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 2000-05-09 00:33:38 +0200 |
commit | c976342828d5de3d16b59d623f4f7fb03f52acc9 (patch) | |
tree | 4c36b20465c2d7d65e248c14e718e778a5efef60 | |
parent | 0521e4f68490d5ef5cc6ba6b2b4e4edf7cf6aa1a (diff) | |
download | bird-c976342828d5de3d16b59d623f4f7fb03f52acc9.tar bird-c976342828d5de3d16b59d623f4f7fb03f52acc9.zip |
Implemented debugging function rlookup() which you can call from gdb
to see what resource does the address given as a parameter belong to.
-rw-r--r-- | lib/mempool.c | 30 | ||||
-rw-r--r-- | lib/resource.c | 39 | ||||
-rw-r--r-- | lib/resource.h | 2 | ||||
-rw-r--r-- | lib/slab.c | 19 |
4 files changed, 83 insertions, 7 deletions
diff --git a/lib/mempool.c b/lib/mempool.c index c9c1dd6..f21b305 100644 --- a/lib/mempool.c +++ b/lib/mempool.c @@ -14,6 +14,7 @@ struct lp_chunk { struct lp_chunk *next; + unsigned int size; byte data[0]; }; @@ -25,14 +26,16 @@ struct linpool { unsigned chunk_size, threshold, total, total_large; }; -void lp_free(resource *); -void lp_dump(resource *); +static void lp_free(resource *); +static void lp_dump(resource *); +static resource *lp_lookup(resource *, unsigned long); static struct resclass lp_class = { "LinPool", sizeof(struct linpool), lp_free, - lp_dump + lp_dump, + lp_lookup }; linpool @@ -70,6 +73,7 @@ lp_alloc(linpool *m, unsigned size) m->total_large += size; c->next = m->first_large; m->first_large = c->next; + c->size = size; } else { @@ -87,6 +91,7 @@ lp_alloc(linpool *m, unsigned size) *m->plast = c; m->plast = &c->next; c->next = NULL; + c->size = m->chunk_size; } m->ptr = c->data + size; m->end = c->data + m->chunk_size; @@ -134,7 +139,7 @@ lp_flush(linpool *m) m->total_large = 0; } -void +static void lp_free(resource *r) { linpool *m = (linpool *) r; @@ -152,7 +157,7 @@ lp_free(resource *r) } } -void +static void lp_dump(resource *r) { linpool *m = (linpool *) r; @@ -171,3 +176,18 @@ lp_dump(resource *r) m->total, m->total_large); } + +static resource * +lp_lookup(resource *r, unsigned long a) +{ + linpool *m = (linpool *) r; + struct lp_chunk *c; + + for(c=m->first; c; c=c->next) + if ((unsigned long) c->data <= a && (unsigned long) c->data + c->size > a) + return r; + for(c=m->first_large; c; c=c->next) + if ((unsigned long) c->data <= a && (unsigned long) c->data + c->size > a) + return r; + return NULL; +} diff --git a/lib/resource.c b/lib/resource.c index e67c05a..3cfd065 100644 --- a/lib/resource.c +++ b/lib/resource.c @@ -21,12 +21,14 @@ struct pool { static void pool_dump(resource *); static void pool_free(resource *); +static resource *pool_lookup(resource *, unsigned long); static struct resclass pool_class = { "Pool", sizeof(pool), pool_free, - pool_dump + pool_dump, + pool_lookup }; pool root_pool; @@ -70,6 +72,18 @@ pool_dump(resource *P) indent -= 3; } +static resource * +pool_lookup(resource *P, unsigned long a) +{ + pool *p = (pool *) P; + resource *r, *q; + + WALK_LIST(r, p->inside) + if (r->class->lookup && (q = r->class->lookup(r, a))) + return q; + return NULL; +} + void rfree(void *res) { @@ -112,6 +126,18 @@ ralloc(pool *p, struct resclass *c) } void +rlookup(unsigned long a) +{ + resource *r; + + debug("Looking up %08lx\n", a); + if (r = pool_lookup(&root_pool.r, a)) + rdump(r); + else + debug("Not found.\n"); +} + +void resource_init(void) { root_pool.r.class = &pool_class; @@ -140,11 +166,22 @@ static void mbl_debug(resource *r) debug("(size=%d)\n", m->size); } +static resource * +mbl_lookup(resource *r, unsigned long a) +{ + struct mblock *m = (struct mblock *) r; + + if ((unsigned long) m->data <= a && (unsigned long) m->data + m->size > a) + return r; + return NULL; +} + static struct resclass mb_class = { "Memory", 0, mbl_free, mbl_debug, + mbl_lookup }; void * diff --git a/lib/resource.h b/lib/resource.h index 1491fde..ab53048 100644 --- a/lib/resource.h +++ b/lib/resource.h @@ -25,6 +25,7 @@ struct resclass { unsigned size; /* Standard size of single resource */ void (*free)(resource *); /* Freeing function */ void (*dump)(resource *); /* Dump to debug output */ + resource *(*lookup)(resource *, unsigned long); /* Look up address (only for debugging) */ }; /* Generic resource manipulation */ @@ -35,6 +36,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 */ +void rlookup(unsigned long); /* Look up address (only for debugging) */ void *ralloc(pool *, struct resclass *); @@ -18,6 +18,7 @@ static void slab_free(resource *r); static void slab_dump(resource *r); +static resource *slab_lookup(resource *r, unsigned long addr); #ifdef FAKE_SLAB @@ -111,7 +112,8 @@ static struct resclass sl_class = { "Slab", sizeof(struct slab), slab_free, - slab_dump + slab_dump, + slab_lookup }; struct sl_head { @@ -269,4 +271,19 @@ 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 resource * +slab_lookup(resource *r, unsigned long a) +{ + slab *s = (slab *) r; + struct sl_head *h; + + WALK_LIST(h, s->partial_heads) + if ((unsigned long) h < a && (unsigned long) h + SLAB_SIZE < a) + return r; + WALK_LIST(h, s->full_heads) + if ((unsigned long) h < a && (unsigned long) h + SLAB_SIZE < a) + return r; + return NULL; +} + #endif |