mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-04 21:08:10 +02:00
[freelist] Lazy initialisation of pools
This commit is contained in:
parent
6f0340e2e5
commit
09377a7163
2 changed files with 56 additions and 50 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue