0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00
bird/lib/mempool.c
1998-05-24 14:46:20 +00:00

134 lines
2.1 KiB
C

/*
* BIRD Resource Manager -- Memory Pools
*
* (c) 1998 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include <stdlib.h>
#include <string.h>
#include "nest/bird.h"
#include "lib/resource.h"
struct mp_chunk {
struct mp_chunk *next;
byte data[0];
};
struct mempool {
resource r;
byte *ptr, *end;
struct mp_chunk *first, **plast;
unsigned chunk_size, threshold, total;
};
void mp_free(resource *);
void mp_dump(resource *);
static struct resclass mp_class = {
"MemPool",
sizeof(struct mempool),
mp_free,
mp_dump
};
mempool
*mp_new(pool *p, unsigned blk)
{
mempool *m = ralloc(p, &mp_class);
m->ptr = m->end = NULL;
m->first = NULL;
m->plast = &m->first;
m->chunk_size = blk;
m->threshold = 3*blk/4;
m->total = 0;
return m;
}
void *
mp_alloc(mempool *m, unsigned size)
{
byte *a = (byte *) ALIGN((unsigned long) m->ptr, CPU_STRUCT_ALIGN);
byte *e = a + size;
if (e <= m->end)
{
m->ptr = e;
return a;
}
else
{
struct mp_chunk *c;
if (size >= m->threshold)
{
c = xmalloc(sizeof(struct mp_chunk) + size);
m->total += size;
}
else
{
c = xmalloc(sizeof(struct mp_chunk) + m->chunk_size);
m->ptr = c->data + size;
m->end = c->data + m->chunk_size;
m->total += m->chunk_size;
}
*m->plast = c;
m->plast = &c->next;
c->next = NULL;
return c->data;
}
}
void *
mp_allocu(mempool *m, unsigned size)
{
byte *a = m->ptr;
byte *e = a + size;
if (e <= m->end)
{
m->ptr = e;
return a;
}
return mp_alloc(m, size);
}
void *
mp_allocz(mempool *m, unsigned size)
{
void *z = mp_alloc(m, size);
bzero(z, size);
return z;
}
void
mp_free(resource *r)
{
mempool *m = (mempool *) r;
struct mp_chunk *c, *d;
for(d=m->first; d; d = c)
{
c = d->next;
xfree(d);
}
}
void
mp_dump(resource *r)
{
mempool *m = (mempool *) r;
struct mp_chunk *c;
int cnt;
for(cnt=0, c=m->first; c; c=c->next, cnt++)
;
debug("(chunk=%d threshold=%d count=%d total=%d)\n",
m->chunk_size,
m->threshold,
cnt,
m->total);
}