summaryrefslogtreecommitdiff
path: root/lib/mempool.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mempool.c')
-rw-r--r--lib/mempool.c48
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;
}