diff options
Diffstat (limited to 'lib/mempool.c')
-rw-r--r-- | lib/mempool.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/lib/mempool.c b/lib/mempool.c index 90d7c774..c75f1f5b 100644 --- a/lib/mempool.c +++ b/lib/mempool.c @@ -39,9 +39,11 @@ struct linpool { byte *ptr, *end; struct lp_chunk *first, *current; /* Normal (reusable) chunks */ struct lp_chunk *first_large; /* Large chunks */ - uint chunk_size, threshold, total, total_large; + uint chunk_size, threshold, total:31, use_pages:1, total_large; }; +_Thread_local linpool *tmp_linpool; + static void lp_free(resource *); static void lp_dump(resource *); static resource *lp_lookup(resource *, unsigned long); @@ -69,6 +71,12 @@ linpool *lp_new(pool *p, uint blk) { linpool *m = 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; @@ -121,7 +129,11 @@ lp_alloc(linpool *m, uint size) else { /* Need to allocate a new chunk */ - c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size); + if (m->use_pages) + c = alloc_page(); + else + c = xmalloc(sizeof(struct lp_chunk) + m->chunk_size); + m->total += m->chunk_size; c->next = NULL; c->size = m->chunk_size; @@ -258,7 +270,10 @@ lp_free(resource *r) for(d=m->first; d; d = c) { c = d->next; - xfree(d); + if (m->use_pages) + free_page(d); + else + xfree(d); } for(d=m->first_large; d; d = c) { @@ -291,19 +306,24 @@ static struct resmem lp_memsize(resource *r) { linpool *m = (linpool *) r; - struct lp_chunk *c; - int cnt = 0; + struct resmem sz = { + .overhead = sizeof(struct linpool) + ALLOC_OVERHEAD, + }; - for(c=m->first; c; c=c->next) - cnt++; - for(c=m->first_large; c; c=c->next) - cnt++; + for (struct lp_chunk *c = m->first_large; c; c = c->next) + { + sz.effective += c->size; + sz.overhead += lp_chunk_size + ALLOC_OVERHEAD; + } - return (struct resmem) { - .effective = m->total + m->total_large, - .overhead = ALLOC_OVERHEAD + sizeof(struct linpool) + - cnt * (ALLOC_OVERHEAD + sizeof(struct lp_chunk)), - }; + uint regular = 0; + for (struct lp_chunk *c = m->first; c; c = c->next) + regular++; + + sz.effective += m->chunk_size * regular; + sz.overhead += (lp_chunk_size + ALLOC_OVERHEAD) * regular; + + return sz; } |