2 * Copyright © 2006 Joonas Pihlaja
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 #ifndef CAIRO_FREELIST_H
23 #define CAIRO_FREELIST_H
25 #include "cairo-types-private.h"
26 #include "cairo-compiler-private.h"
27 #include "cairo-freelist-type-private.h"
29 /* for stand-alone compilation*/
35 #define NULL (void *) 0
38 /* Initialise a freelist that will be responsible for allocating
39 * nodes of size nodesize. */
41 _cairo_freelist_init (cairo_freelist_t
*freelist
, unsigned nodesize
);
43 /* Deallocate any nodes in the freelist. */
45 _cairo_freelist_fini (cairo_freelist_t
*freelist
);
47 /* Allocate a new node from the freelist. If the freelist contains no
48 * nodes, a new one will be allocated using malloc(). The caller is
49 * responsible for calling _cairo_freelist_free() or free() on the
50 * returned node. Returns %NULL on memory allocation error. */
52 _cairo_freelist_alloc (cairo_freelist_t
*freelist
);
54 /* Allocate a new node from the freelist. If the freelist contains no
55 * nodes, a new one will be allocated using calloc(). The caller is
56 * responsible for calling _cairo_freelist_free() or free() on the
57 * returned node. Returns %NULL on memory allocation error. */
59 _cairo_freelist_calloc (cairo_freelist_t
*freelist
);
61 /* Return a node to the freelist. This does not deallocate the memory,
62 * but makes it available for later reuse by
63 * _cairo_freelist_alloc(). */
65 _cairo_freelist_free (cairo_freelist_t
*freelist
, void *node
);
69 _cairo_freepool_init (cairo_freepool_t
*freepool
, unsigned nodesize
);
72 _cairo_freepool_fini (cairo_freepool_t
*freepool
);
75 _cairo_freepool_reset (cairo_freepool_t
*freepool
)
77 while (freepool
->pools
!= &freepool
->embedded_pool
) {
78 cairo_freelist_pool_t
*pool
= freepool
->pools
;
79 freepool
->pools
= pool
->next
;
80 pool
->next
= freepool
->freepools
;
81 freepool
->freepools
= pool
;
84 freepool
->embedded_pool
.rem
= sizeof (freepool
->embedded_data
);
85 freepool
->embedded_pool
.data
= freepool
->embedded_data
;
89 _cairo_freepool_alloc_from_new_pool (cairo_freepool_t
*freepool
);
92 _cairo_freepool_alloc_from_pool (cairo_freepool_t
*freepool
)
94 cairo_freelist_pool_t
*pool
;
97 pool
= freepool
->pools
;
98 if (unlikely (freepool
->nodesize
> pool
->rem
))
99 return _cairo_freepool_alloc_from_new_pool (freepool
);
102 pool
->data
+= freepool
->nodesize
;
103 pool
->rem
-= freepool
->nodesize
;
104 VG (VALGRIND_MAKE_MEM_UNDEFINED (ptr
, freepool
->nodesize
));
109 _cairo_freepool_alloc (cairo_freepool_t
*freepool
)
111 cairo_freelist_node_t
*node
;
113 node
= freepool
->first_free_node
;
115 return _cairo_freepool_alloc_from_pool (freepool
);
117 VG (VALGRIND_MAKE_MEM_DEFINED (node
, sizeof (node
->next
)));
118 freepool
->first_free_node
= node
->next
;
119 VG (VALGRIND_MAKE_MEM_UNDEFINED (node
, freepool
->nodesize
));
124 cairo_private cairo_status_t
125 _cairo_freepool_alloc_array (cairo_freepool_t
*freepool
,
130 _cairo_freepool_free (cairo_freepool_t
*freepool
, void *ptr
)
132 cairo_freelist_node_t
*node
= ptr
;
134 node
->next
= freepool
->first_free_node
;
135 freepool
->first_free_node
= node
;
136 VG (VALGRIND_MAKE_MEM_NOACCESS (node
, freepool
->nodesize
));
139 #endif /* CAIRO_FREELIST_H */