summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>2000-05-09 00:33:38 +0200
committerMartin Mares <mj@ucw.cz>2000-05-09 00:33:38 +0200
commitc976342828d5de3d16b59d623f4f7fb03f52acc9 (patch)
tree4c36b20465c2d7d65e248c14e718e778a5efef60 /lib
parent0521e4f68490d5ef5cc6ba6b2b4e4edf7cf6aa1a (diff)
downloadbird-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.
Diffstat (limited to 'lib')
-rw-r--r--lib/mempool.c30
-rw-r--r--lib/resource.c39
-rw-r--r--lib/resource.h2
-rw-r--r--lib/slab.c19
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 *);
diff --git a/lib/slab.c b/lib/slab.c
index e2e741c..0a3455f 100644
--- a/lib/slab.c
+++ b/lib/slab.c
@@ -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