Added lp_flush() which flushes contents of a linear pool, leaving all the
memory available for subsequent allocations from the same pool. Both flushing and re-using the memory costs just few instructions.
This commit is contained in:
parent
f54801ffed
commit
f5c687f791
2 changed files with 42 additions and 12 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BIRD Resource Manager -- Memory Pools
|
* BIRD Resource Manager -- Memory Pools
|
||||||
*
|
*
|
||||||
* (c) 1998 Martin Mares <mj@ucw.cz>
|
* (c) 1998--1999 Martin Mares <mj@ucw.cz>
|
||||||
*
|
*
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
@ -20,8 +20,9 @@ struct lp_chunk {
|
||||||
struct linpool {
|
struct linpool {
|
||||||
resource r;
|
resource r;
|
||||||
byte *ptr, *end;
|
byte *ptr, *end;
|
||||||
struct lp_chunk *first, **plast;
|
struct lp_chunk *first, *current, **plast; /* Normal (reusable) chunks */
|
||||||
unsigned chunk_size, threshold, total;
|
struct lp_chunk *first_large; /* Large chunks */
|
||||||
|
unsigned chunk_size, threshold, total, total_large;
|
||||||
};
|
};
|
||||||
|
|
||||||
void lp_free(resource *);
|
void lp_free(resource *);
|
||||||
|
@ -39,11 +40,12 @@ linpool
|
||||||
{
|
{
|
||||||
linpool *m = ralloc(p, &lp_class);
|
linpool *m = ralloc(p, &lp_class);
|
||||||
m->ptr = m->end = NULL;
|
m->ptr = m->end = NULL;
|
||||||
m->first = NULL;
|
m->first = m->current = NULL;
|
||||||
m->plast = &m->first;
|
m->plast = &m->first;
|
||||||
|
m->first_large = NULL;
|
||||||
m->chunk_size = blk;
|
m->chunk_size = blk;
|
||||||
m->threshold = 3*blk/4;
|
m->threshold = 3*blk/4;
|
||||||
m->total = 0;
|
m->total = m->total_large = 0;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,19 +65,30 @@ lp_alloc(linpool *m, unsigned size)
|
||||||
struct lp_chunk *c;
|
struct lp_chunk *c;
|
||||||
if (size >= m->threshold)
|
if (size >= m->threshold)
|
||||||
{
|
{
|
||||||
|
/* Too large => allocate large chunk */
|
||||||
c = xmalloc(sizeof(struct lp_chunk) + size);
|
c = xmalloc(sizeof(struct lp_chunk) + size);
|
||||||
m->total += size;
|
m->total_large += size;
|
||||||
|
c->next = m->first_large;
|
||||||
|
m->first_large = c->next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
|
if (m->current && m->current->next)
|
||||||
|
/* Still have free chunks from previous incarnation (before lp_flush()) */
|
||||||
|
c = m->current->next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Need to allocate a new chunk */
|
||||||
|
c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
|
||||||
|
m->total += m->chunk_size;
|
||||||
|
*m->plast = c;
|
||||||
|
m->plast = &c->next;
|
||||||
|
c->next = NULL;
|
||||||
|
}
|
||||||
|
m->current = c;
|
||||||
m->ptr = c->data + size;
|
m->ptr = c->data + size;
|
||||||
m->end = c->data + m->chunk_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;
|
return c->data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +116,22 @@ lp_allocz(linpool *m, unsigned size)
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
lp_flush(linpool *m)
|
||||||
|
{
|
||||||
|
struct lp_chunk *c;
|
||||||
|
|
||||||
|
/* Relink all normal chunks to free list and free all large chunks */
|
||||||
|
m->ptr = m->end = NULL;
|
||||||
|
m->current = m->first;
|
||||||
|
while (c = m->first_large)
|
||||||
|
{
|
||||||
|
m->first_large = c->next;
|
||||||
|
xfree(c);
|
||||||
|
}
|
||||||
|
m->total_large = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
lp_free(resource *r)
|
lp_free(resource *r)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* BIRD Resource Manager
|
* BIRD Resource Manager
|
||||||
*
|
*
|
||||||
* (c) 1998 Martin Mares <mj@ucw.cz>
|
* (c) 1998--1999 Martin Mares <mj@ucw.cz>
|
||||||
*
|
*
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
*/
|
*/
|
||||||
|
@ -54,6 +54,7 @@ linpool *lp_new(pool *, unsigned blk);
|
||||||
void *lp_alloc(linpool *, unsigned size); /* Aligned */
|
void *lp_alloc(linpool *, unsigned size); /* Aligned */
|
||||||
void *lp_allocu(linpool *, unsigned size); /* Unaligned */
|
void *lp_allocu(linpool *, unsigned size); /* Unaligned */
|
||||||
void *lp_allocz(linpool *, unsigned size); /* With clear */
|
void *lp_allocz(linpool *, unsigned size); /* With clear */
|
||||||
|
void lp_flush(linpool *); /* Free everything, but leave linpool */
|
||||||
|
|
||||||
/* Slabs */
|
/* Slabs */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue