[freelist] Lazy initialisation of pools

This commit is contained in:
Chris Wilson 2009-08-02 13:09:30 +01:00
parent 6f0340e2e5
commit 09377a7163
2 changed files with 56 additions and 50 deletions

View file

@ -44,11 +44,19 @@ typedef struct _cairo_freelist {
unsigned nodesize;
} cairo_freelist_t;
typedef struct _cairo_freelist_pool cairo_freelist_pool_t;
struct _cairo_freelist_pool {
cairo_freelist_pool_t *next;
unsigned size, rem;
uint8_t *data;
};
typedef struct _cairo_freepool {
cairo_freelist_node_t *first_free_node;
cairo_freelist_node_t *pools;
cairo_freelist_pool_t *pools;
unsigned nodesize;
char embedded_pool[1000];
cairo_freelist_pool_t embedded_pool;
uint8_t embedded_data[1000];
} cairo_freepool_t;
@ -91,6 +99,23 @@ _cairo_freepool_fini (cairo_freepool_t *freepool);
cairo_private void *
_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool);
static inline void *
_cairo_freepool_alloc_from_pool (cairo_freepool_t *freepool)
{
cairo_freelist_pool_t *pool;
uint8_t *ptr;
pool = freepool->pools;
if (unlikely (freepool->nodesize > pool->rem))
return _cairo_freepool_alloc_from_new_pool (freepool);
ptr = pool->data;
pool->data += freepool->nodesize;
pool->rem -= freepool->nodesize;
VG (VALGRIND_MAKE_MEM_UNDEFINED (ptr, freepool->nodesize));
return ptr;
}
static inline void *
_cairo_freepool_alloc (cairo_freepool_t *freepool)
{
@ -98,7 +123,7 @@ _cairo_freepool_alloc (cairo_freepool_t *freepool)
node = freepool->first_free_node;
if (unlikely (node == NULL))
return _cairo_freepool_alloc_from_new_pool (freepool);
return _cairo_freepool_alloc_from_pool (freepool);
VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
freepool->first_free_node = node->next;

View file

@ -87,40 +87,27 @@ _cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
void
_cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize)
{
int poolsize;
char *ptr;
freepool->first_free_node = NULL;
freepool->pools = NULL;
freepool->pools = &freepool->embedded_pool;
freepool->nodesize = nodesize;
poolsize = sizeof (freepool->embedded_pool);
ptr = freepool->embedded_pool + poolsize - freepool->nodesize;
freepool->embedded_pool.next = NULL;
freepool->embedded_pool.size = sizeof (freepool->embedded_data);
freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
freepool->embedded_pool.data = freepool->embedded_data;
poolsize /= freepool->nodesize;
while (poolsize--) {
cairo_freelist_node_t *node = (cairo_freelist_node_t *) ptr;
ptr -= freepool->nodesize;
node->next = freepool->first_free_node;
freepool->first_free_node = node;
}
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_pool,
sizeof (freepool->embedded_pool)));
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data,
sizeof (freepool->embedded_data)));
}
void
_cairo_freepool_fini (cairo_freepool_t *freepool)
{
cairo_freelist_node_t *node = freepool->pools;
while (node != NULL) {
cairo_freelist_node_t *next;
VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
next = node->next;
free (node);
node = next;
cairo_freelist_pool_t *pool = freepool->pools;
while (pool != &freepool->embedded_pool) {
cairo_freelist_pool_t *next = pool->next;
free (pool);
pool = next;
}
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
}
@ -128,32 +115,26 @@ _cairo_freepool_fini (cairo_freepool_t *freepool)
void *
_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
{
cairo_freelist_node_t *node;
char *ptr;
cairo_freelist_pool_t *pool;
int poolsize;
poolsize = (128 * freepool->nodesize + 8191) & -8192;
node = malloc (poolsize);
if (unlikely (node == NULL))
return node;
if (freepool->pools != &freepool->embedded_pool)
poolsize = 2 * freepool->pools->size;
else
poolsize = (128 * freepool->nodesize + 8191) & -8192;
pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
if (unlikely (pool == NULL))
return pool;
node->next = freepool->pools;
freepool->pools = node;
pool->next = freepool->pools;
freepool->pools = pool;
ptr = (char *) node + poolsize - freepool->nodesize;
pool->size = poolsize;
pool->rem = poolsize - freepool->nodesize;
pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;
poolsize -= sizeof (cairo_freelist_node_t);
poolsize /= freepool->nodesize;
VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));
while (--poolsize) {
node = (cairo_freelist_node_t *) ptr;
ptr -= freepool->nodesize;
node->next = freepool->first_free_node;
freepool->first_free_node = node;
}
VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->pools,
(128 * freepool->nodesize + 8191) & -8192));
return ptr;
return pool + 1;
}