mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-01-05 08:31:53 +00:00
Stonehenge: multi-slab allocator
To mid-term allocate and free lots of small blocks in a fast pace, mb_alloc is too slow and causes heap bloating. We can already allocate blocks from slabs, and if we allow for a little bit of inefficiency, we can just use multiple slabs with stepped sizes. This technique is already used in ea_list allocation which is gonna be converted to Stonehenge.
This commit is contained in:
parent
f7639a9faf
commit
f6ef8b5b58
@ -139,6 +139,20 @@ void *sl_allocz(slab *);
|
|||||||
void sl_free(void *);
|
void sl_free(void *);
|
||||||
void sl_delete(slab *);
|
void sl_delete(slab *);
|
||||||
|
|
||||||
|
/* A whole stonehenge of slabs */
|
||||||
|
|
||||||
|
typedef struct stonehenge stonehenge;
|
||||||
|
typedef struct sth_block {
|
||||||
|
void *block;
|
||||||
|
bool large;
|
||||||
|
} sth_block;
|
||||||
|
|
||||||
|
stonehenge *sth_new(pool *);
|
||||||
|
sth_block sth_alloc(stonehenge *, uint size);
|
||||||
|
sth_block sth_allocz(stonehenge *, uint size);
|
||||||
|
void sth_free(sth_block);
|
||||||
|
void sth_delete(stonehenge *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Low-level memory allocation functions, please don't use
|
* Low-level memory allocation functions, please don't use
|
||||||
* outside resource manager and possibly sysdep code.
|
* outside resource manager and possibly sysdep code.
|
||||||
|
62
lib/slab.c
62
lib/slab.c
@ -469,4 +469,66 @@ slab_lookup(resource *r, unsigned long a)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const uint stonehenge_sizes[] = { 56, 112, 168, 288, 448, 800, 1344 };
|
||||||
|
|
||||||
|
struct stonehenge {
|
||||||
|
pool *p;
|
||||||
|
slab *s[ARRAY_SIZE(stonehenge_sizes)];
|
||||||
|
};
|
||||||
|
|
||||||
|
sth_block
|
||||||
|
sth_alloc(stonehenge *sth, uint size)
|
||||||
|
{
|
||||||
|
for (uint i=0; i<ARRAY_SIZE(stonehenge_sizes); i++)
|
||||||
|
if (size <= stonehenge_sizes[i])
|
||||||
|
{
|
||||||
|
if (!sth->s[i])
|
||||||
|
sth->s[i] = sl_new(sth->p, stonehenge_sizes[i]);
|
||||||
|
|
||||||
|
return (sth_block) { .block = sl_alloc(sth->s[i]), };
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sth_block) {
|
||||||
|
.block = mb_alloc(sth->p, size),
|
||||||
|
.large = 1,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sth_block
|
||||||
|
sth_allocz(stonehenge *sth, uint size)
|
||||||
|
{
|
||||||
|
sth_block b = sth_alloc(sth, size);
|
||||||
|
bzero(b.block, size);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sth_free(sth_block b)
|
||||||
|
{
|
||||||
|
if (b.large)
|
||||||
|
mb_free(b.block);
|
||||||
|
else
|
||||||
|
sl_free(b.block);
|
||||||
|
}
|
||||||
|
|
||||||
|
stonehenge *
|
||||||
|
sth_new(pool *pp)
|
||||||
|
{
|
||||||
|
stonehenge tmps = {
|
||||||
|
.p = rp_new(pp, pp->domain, "Stonehenge"),
|
||||||
|
};
|
||||||
|
|
||||||
|
stonehenge *s = sth_alloc(&tmps, sizeof(stonehenge)).block;
|
||||||
|
*s = tmps;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sth_delete(stonehenge *s)
|
||||||
|
{
|
||||||
|
pool *p = s->p;
|
||||||
|
sth_free((sth_block) { s });
|
||||||
|
rp_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user