bird/lib/resource.c

212 lines
3 KiB
C
Raw Normal View History

/*
* BIRD Resource Manager
*
* (c) 1998 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdio.h>
#include <stdlib.h>
#include "nest/bird.h"
#include "lib/resource.h"
#include "lib/string.h"
struct pool {
resource r;
list inside;
1998-05-27 05:37:37 +08:00
char *name;
};
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_lookup
};
pool root_pool;
static int indent;
pool *
1998-05-27 05:37:37 +08:00
rp_new(pool *p, char *name)
{
pool *z = ralloc(p, &pool_class);
z->name = name;
init_list(&z->inside);
return z;
}
static void
pool_free(resource *P)
{
pool *p = (pool *) P;
resource *r, *rr;
r = HEAD(p->inside);
while (rr = (resource *) r->n.next)
{
r->class->free(r);
xfree(r);
r = rr;
}
}
static void
pool_dump(resource *P)
{
pool *p = (pool *) P;
resource *r;
debug("%s\n", p->name);
indent += 3;
WALK_LIST(r, p->inside)
rdump(r);
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)
{
resource *r = res;
if (r)
{
if (r->n.next)
rem_node(&r->n);
r->class->free(r);
xfree(r);
}
}
void
rdump(void *res)
{
char x[16];
resource *r = res;
2000-04-01 07:33:03 +08:00
bsprintf(x, "%%%ds%%08x ", indent);
debug(x, "", (int) r);
if (r)
{
debug("%s ", r->class->name);
r->class->dump(r);
}
else
debug("NULL\n");
}
void *
ralloc(pool *p, struct resclass *c)
{
resource *r = xmalloc(c->size);
r->class = c;
add_tail(&p->inside, &r->n);
return r;
}
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;
1998-05-27 05:37:37 +08:00
root_pool.name = "Root";
init_list(&root_pool.inside);
}
/*
* Memory blocks.
*/
struct mblock {
resource r;
unsigned size;
byte data[0];
};
static void mbl_free(resource *r)
{
}
static void mbl_debug(resource *r)
{
struct mblock *m = (struct mblock *) 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 *
mb_alloc(pool *p, unsigned size)
{
struct mblock *b = xmalloc(sizeof(struct mblock) + size);
b->r.class = &mb_class;
add_tail(&p->inside, &b->r.n);
b->size = size;
return b->data;
}
void *
mb_allocz(pool *p, unsigned size)
{
void *x = mb_alloc(p, size);
bzero(x, size);
return x;
}
void
mb_free(void *m)
{
struct mblock *b = SKIP_BACK(struct mblock, data, m);
rfree(b);
}