summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-08-02 13:09:30 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-08-29 08:08:30 +0100
commit09377a716334df3683912747067cd396768cfab6 (patch)
tree232895ccaa9d219dfe486ad624cce97a4a732efe
parent6f0340e2e5079eba597c0a3a7d39da21cf2b5e7a (diff)
[freelist] Lazy initialisation of pools
-rw-r--r--src/cairo-freelist-private.h31
-rw-r--r--src/cairo-freelist.c75
2 files changed, 56 insertions, 50 deletions
diff --git a/src/cairo-freelist-private.h b/src/cairo-freelist-private.h
index 8f9f1534..d48a7201 100644
--- a/src/cairo-freelist-private.h
+++ b/src/cairo-freelist-private.h
@@ -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;
@@ -92,13 +100,30 @@ 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)
{
cairo_freelist_node_t *node;
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;
diff --git a/src/cairo-freelist.c b/src/cairo-freelist.c
index 6bbee844..6277f907 100644
--- a/src/cairo-freelist.c
+++ b/src/cairo-freelist.c
@@ -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;
-
- 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));
+ VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
+ VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));
- return ptr;
+ return pool + 1;
}