All linpools use pages to allocate regular blocks
This commit is contained in:
parent
dabd7bccb3
commit
7e86ff2076
6 changed files with 28 additions and 56 deletions
|
@ -27,19 +27,18 @@
|
||||||
|
|
||||||
struct lp_chunk {
|
struct lp_chunk {
|
||||||
struct lp_chunk *next;
|
struct lp_chunk *next;
|
||||||
uint size;
|
|
||||||
uintptr_t data_align[0];
|
uintptr_t data_align[0];
|
||||||
byte data[0];
|
byte data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
const int lp_chunk_size = sizeof(struct lp_chunk);
|
#define LP_DATA_SIZE (page_size - OFFSETOF(struct lp_chunk, data))
|
||||||
|
|
||||||
struct linpool {
|
struct linpool {
|
||||||
resource r;
|
resource r;
|
||||||
byte *ptr, *end;
|
byte *ptr, *end;
|
||||||
struct lp_chunk *first, *current; /* Normal (reusable) chunks */
|
struct lp_chunk *first, *current; /* Normal (reusable) chunks */
|
||||||
struct lp_chunk *first_large; /* Large chunks */
|
struct lp_chunk *first_large; /* Large chunks */
|
||||||
uint chunk_size, threshold, total:31, use_pages:1, total_large;
|
uint total, total_large;
|
||||||
};
|
};
|
||||||
|
|
||||||
_Thread_local linpool *tmp_linpool;
|
_Thread_local linpool *tmp_linpool;
|
||||||
|
@ -61,25 +60,14 @@ static struct resclass lp_class = {
|
||||||
/**
|
/**
|
||||||
* lp_new - create a new linear memory pool
|
* lp_new - create a new linear memory pool
|
||||||
* @p: pool
|
* @p: pool
|
||||||
* @blk: block size
|
|
||||||
*
|
*
|
||||||
* lp_new() creates a new linear memory pool resource inside the pool @p.
|
* lp_new() creates a new linear memory pool resource inside the pool @p.
|
||||||
* The linear pool consists of a list of memory chunks of size at least
|
* The linear pool consists of a list of memory chunks of page size.
|
||||||
* @blk.
|
|
||||||
*/
|
*/
|
||||||
linpool
|
linpool
|
||||||
*lp_new(pool *p, uint blk)
|
*lp_new(pool *p)
|
||||||
{
|
{
|
||||||
linpool *m = ralloc(p, &lp_class);
|
return ralloc(p, &lp_class);
|
||||||
if (!blk)
|
|
||||||
{
|
|
||||||
m->use_pages = 1;
|
|
||||||
blk = page_size - lp_chunk_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
m->chunk_size = blk;
|
|
||||||
m->threshold = 3*blk/4;
|
|
||||||
return m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,14 +98,13 @@ lp_alloc(linpool *m, uint size)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct lp_chunk *c;
|
struct lp_chunk *c;
|
||||||
if (size >= m->threshold)
|
if (size > LP_DATA_SIZE)
|
||||||
{
|
{
|
||||||
/* Too large => allocate large chunk */
|
/* Too large => allocate large chunk */
|
||||||
c = xmalloc(sizeof(struct lp_chunk) + size);
|
c = xmalloc(sizeof(struct lp_chunk) + size);
|
||||||
m->total_large += size;
|
m->total_large += size;
|
||||||
c->next = m->first_large;
|
c->next = m->first_large;
|
||||||
m->first_large = c;
|
m->first_large = c;
|
||||||
c->size = size;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -129,14 +116,10 @@ lp_alloc(linpool *m, uint size)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Need to allocate a new chunk */
|
/* Need to allocate a new chunk */
|
||||||
if (m->use_pages)
|
|
||||||
c = alloc_page();
|
c = alloc_page();
|
||||||
else
|
|
||||||
c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size);
|
|
||||||
|
|
||||||
m->total += m->chunk_size;
|
m->total += LP_DATA_SIZE;
|
||||||
c->next = NULL;
|
c->next = NULL;
|
||||||
c->size = m->chunk_size;
|
|
||||||
|
|
||||||
if (m->current)
|
if (m->current)
|
||||||
m->current->next = c;
|
m->current->next = c;
|
||||||
|
@ -145,7 +128,7 @@ lp_alloc(linpool *m, uint size)
|
||||||
}
|
}
|
||||||
m->current = c;
|
m->current = c;
|
||||||
m->ptr = c->data + size;
|
m->ptr = c->data + size;
|
||||||
m->end = c->data + m->chunk_size;
|
m->end = c->data + LP_DATA_SIZE;
|
||||||
}
|
}
|
||||||
return c->data;
|
return c->data;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +190,7 @@ lp_flush(linpool *m)
|
||||||
/* Move ptr to the first chunk and free all large chunks */
|
/* Move ptr to the first chunk and free all large chunks */
|
||||||
m->current = c = m->first;
|
m->current = c = m->first;
|
||||||
m->ptr = c ? c->data : NULL;
|
m->ptr = c ? c->data : NULL;
|
||||||
m->end = c ? c->data + m->chunk_size : NULL;
|
m->end = c ? c->data + LP_DATA_SIZE : NULL;
|
||||||
|
|
||||||
while (c = m->first_large)
|
while (c = m->first_large)
|
||||||
{
|
{
|
||||||
|
@ -230,6 +213,7 @@ lp_save(linpool *m, lp_state *p)
|
||||||
{
|
{
|
||||||
p->current = m->current;
|
p->current = m->current;
|
||||||
p->large = m->first_large;
|
p->large = m->first_large;
|
||||||
|
p->total_large = m->total_large;
|
||||||
p->ptr = m->ptr;
|
p->ptr = m->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,12 +235,12 @@ lp_restore(linpool *m, lp_state *p)
|
||||||
/* Move ptr to the saved pos and free all newer large chunks */
|
/* Move ptr to the saved pos and free all newer large chunks */
|
||||||
m->current = c = p->current;
|
m->current = c = p->current;
|
||||||
m->ptr = p->ptr;
|
m->ptr = p->ptr;
|
||||||
m->end = c ? c->data + m->chunk_size : NULL;
|
m->end = c ? c->data + LP_DATA_SIZE : NULL;
|
||||||
|
m->total_large = p->total_large;
|
||||||
|
|
||||||
while ((c = m->first_large) && (c != p->large))
|
while ((c = m->first_large) && (c != p->large))
|
||||||
{
|
{
|
||||||
m->first_large = c->next;
|
m->first_large = c->next;
|
||||||
m->total_large -= c->size;
|
|
||||||
xfree(c);
|
xfree(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,10 +254,7 @@ lp_free(resource *r)
|
||||||
for(d=m->first; d; d = c)
|
for(d=m->first; d; d = c)
|
||||||
{
|
{
|
||||||
c = d->next;
|
c = d->next;
|
||||||
if (m->use_pages)
|
|
||||||
free_page(d);
|
free_page(d);
|
||||||
else
|
|
||||||
xfree(d);
|
|
||||||
}
|
}
|
||||||
for(d=m->first_large; d; d = c)
|
for(d=m->first_large; d; d = c)
|
||||||
{
|
{
|
||||||
|
@ -293,9 +274,7 @@ lp_dump(resource *r)
|
||||||
;
|
;
|
||||||
for(cntl=0, c=m->first_large; c; c=c->next, cntl++)
|
for(cntl=0, c=m->first_large; c; c=c->next, cntl++)
|
||||||
;
|
;
|
||||||
debug("(chunk=%d threshold=%d count=%d+%d total=%d+%d)\n",
|
debug("(count=%d+%d total=%d+%d)\n",
|
||||||
m->chunk_size,
|
|
||||||
m->threshold,
|
|
||||||
cnt,
|
cnt,
|
||||||
cntl,
|
cntl,
|
||||||
m->total,
|
m->total,
|
||||||
|
@ -308,20 +287,18 @@ lp_memsize(resource *r)
|
||||||
linpool *m = (linpool *) r;
|
linpool *m = (linpool *) r;
|
||||||
struct resmem sz = {
|
struct resmem sz = {
|
||||||
.overhead = sizeof(struct linpool) + ALLOC_OVERHEAD,
|
.overhead = sizeof(struct linpool) + ALLOC_OVERHEAD,
|
||||||
|
.effective = m->total_large,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (struct lp_chunk *c = m->first_large; c; c = c->next)
|
for (struct lp_chunk *c = m->first_large; c; c = c->next)
|
||||||
{
|
sz.overhead += sizeof(struct lp_chunk) + ALLOC_OVERHEAD;
|
||||||
sz.effective += c->size;
|
|
||||||
sz.overhead += lp_chunk_size + ALLOC_OVERHEAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint regular = 0;
|
uint regular = 0;
|
||||||
for (struct lp_chunk *c = m->first; c; c = c->next)
|
for (struct lp_chunk *c = m->first; c; c = c->next)
|
||||||
regular++;
|
regular++;
|
||||||
|
|
||||||
sz.effective += m->chunk_size * regular;
|
sz.effective += LP_DATA_SIZE * regular;
|
||||||
sz.overhead += (lp_chunk_size + ALLOC_OVERHEAD) * regular;
|
sz.overhead += (sizeof(struct lp_chunk) + ALLOC_OVERHEAD) * regular;
|
||||||
|
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
@ -334,10 +311,7 @@ lp_lookup(resource *r, unsigned long a)
|
||||||
struct lp_chunk *c;
|
struct lp_chunk *c;
|
||||||
|
|
||||||
for(c=m->first; c; c=c->next)
|
for(c=m->first; c; c=c->next)
|
||||||
if ((unsigned long) c->data <= a && (unsigned long) c->data + c->size > a)
|
if ((unsigned long) c->data <= a && (unsigned long) c->data + LP_DATA_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 r;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,10 @@ typedef struct linpool linpool;
|
||||||
typedef struct lp_state {
|
typedef struct lp_state {
|
||||||
void *current, *large;
|
void *current, *large;
|
||||||
byte *ptr;
|
byte *ptr;
|
||||||
|
uint total_large;
|
||||||
} lp_state;
|
} lp_state;
|
||||||
|
|
||||||
linpool *lp_new(pool *, unsigned blk);
|
linpool *lp_new(pool *);
|
||||||
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 */
|
||||||
|
@ -88,10 +89,7 @@ extern _Thread_local linpool *tmp_linpool; /* Temporary linpool autoflushed regu
|
||||||
#define tmp_init(p) tmp_linpool = lp_new_default(p)
|
#define tmp_init(p) tmp_linpool = lp_new_default(p)
|
||||||
#define tmp_flush() lp_flush(tmp_linpool)
|
#define tmp_flush() lp_flush(tmp_linpool)
|
||||||
|
|
||||||
extern const int lp_chunk_size;
|
#define lp_new_default lp_new
|
||||||
#define LP_GAS 1024
|
|
||||||
#define LP_GOOD_SIZE(x) (((x + LP_GAS - 1) & (~(LP_GAS - 1))) - lp_chunk_size)
|
|
||||||
#define lp_new_default(p) lp_new(p, 0)
|
|
||||||
|
|
||||||
/* Slabs */
|
/* Slabs */
|
||||||
|
|
||||||
|
|
|
@ -3410,7 +3410,7 @@ rt_init_hostcache(rtable *tab)
|
||||||
hc_alloc_table(hc, tab->rp, HC_DEF_ORDER);
|
hc_alloc_table(hc, tab->rp, HC_DEF_ORDER);
|
||||||
hc->slab = sl_new(tab->rp, sizeof(struct hostentry));
|
hc->slab = sl_new(tab->rp, sizeof(struct hostentry));
|
||||||
|
|
||||||
hc->lp = lp_new(tab->rp, LP_GOOD_SIZE(1024));
|
hc->lp = lp_new(tab->rp);
|
||||||
hc->trie = f_new_trie(hc->lp, 0);
|
hc->trie = f_new_trie(hc->lp, 0);
|
||||||
|
|
||||||
tab->hostcache = hc;
|
tab->hostcache = hc;
|
||||||
|
|
|
@ -560,8 +560,8 @@ mrt_table_dump_init(pool *pp)
|
||||||
struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
|
struct mrt_table_dump_state *s = mb_allocz(pool, sizeof(struct mrt_table_dump_state));
|
||||||
|
|
||||||
s->pool = pool;
|
s->pool = pool;
|
||||||
s->linpool = lp_new(pool, 4080);
|
s->linpool = lp_new(pool);
|
||||||
s->peer_lp = lp_new(pool, 4080);
|
s->peer_lp = lp_new(pool);
|
||||||
mrt_buffer_init(&s->buf, pool, 2 * MRT_ATTR_BUFFER_SIZE);
|
mrt_buffer_init(&s->buf, pool, 2 * MRT_ATTR_BUFFER_SIZE);
|
||||||
|
|
||||||
/* We lock the current config as we may reference it indirectly by filter */
|
/* We lock the current config as we may reference it indirectly by filter */
|
||||||
|
|
|
@ -299,7 +299,7 @@ ospf_start(struct proto *P)
|
||||||
p->lsab_size = 256;
|
p->lsab_size = 256;
|
||||||
p->lsab_used = 0;
|
p->lsab_used = 0;
|
||||||
p->lsab = mb_alloc(P->pool, p->lsab_size);
|
p->lsab = mb_alloc(P->pool, p->lsab_size);
|
||||||
p->nhpool = lp_new(P->pool, 12*sizeof(struct nexthop));
|
p->nhpool = lp_new(P->pool);
|
||||||
init_list(&(p->iface_list));
|
init_list(&(p->iface_list));
|
||||||
init_list(&(p->area_list));
|
init_list(&(p->area_list));
|
||||||
fib_init(&p->rtf, P->pool, ospf_get_af(p), sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
|
fib_init(&p->rtf, P->pool, ospf_get_af(p), sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
|
||||||
|
|
|
@ -486,7 +486,7 @@ static_start(struct proto *P)
|
||||||
struct static_route *r;
|
struct static_route *r;
|
||||||
|
|
||||||
if (!static_lp)
|
if (!static_lp)
|
||||||
static_lp = lp_new(&root_pool, LP_GOOD_SIZE(1024));
|
static_lp = lp_new(&root_pool);
|
||||||
|
|
||||||
if (p->igp_table_ip4)
|
if (p->igp_table_ip4)
|
||||||
rt_lock_table(p->igp_table_ip4);
|
rt_lock_table(p->igp_table_ip4);
|
||||||
|
|
Loading…
Reference in a new issue