Line data Source code
1 : /*
2 : * Copyright © 2006 Joonas Pihlaja
3 : *
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.
13 : *
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
20 : * OF THIS SOFTWARE.
21 : */
22 : #ifndef CAIRO_FREELIST_H
23 : #define CAIRO_FREELIST_H
24 :
25 : #include "cairo-types-private.h"
26 : #include "cairo-compiler-private.h"
27 : #include "cairo-freelist-type-private.h"
28 :
29 : /* for stand-alone compilation*/
30 : #ifndef VG
31 : #define VG(x)
32 : #endif
33 :
34 : #ifndef NULL
35 : #define NULL (void *) 0
36 : #endif
37 :
38 : /* Initialise a freelist that will be responsible for allocating
39 : * nodes of size nodesize. */
40 : cairo_private void
41 : _cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize);
42 :
43 : /* Deallocate any nodes in the freelist. */
44 : cairo_private void
45 : _cairo_freelist_fini (cairo_freelist_t *freelist);
46 :
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. */
51 : cairo_private void *
52 : _cairo_freelist_alloc (cairo_freelist_t *freelist);
53 :
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. */
58 : cairo_private void *
59 : _cairo_freelist_calloc (cairo_freelist_t *freelist);
60 :
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(). */
64 : cairo_private void
65 : _cairo_freelist_free (cairo_freelist_t *freelist, void *node);
66 :
67 :
68 : cairo_private void
69 : _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize);
70 :
71 : cairo_private void
72 : _cairo_freepool_fini (cairo_freepool_t *freepool);
73 :
74 : static inline void
75 0 : _cairo_freepool_reset (cairo_freepool_t *freepool)
76 : {
77 0 : while (freepool->pools != &freepool->embedded_pool) {
78 0 : cairo_freelist_pool_t *pool = freepool->pools;
79 0 : freepool->pools = pool->next;
80 0 : pool->next = freepool->freepools;
81 0 : freepool->freepools = pool;
82 : }
83 :
84 0 : freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
85 0 : freepool->embedded_pool.data = freepool->embedded_data;
86 0 : }
87 :
88 : cairo_private void *
89 : _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool);
90 :
91 : static inline void *
92 0 : _cairo_freepool_alloc_from_pool (cairo_freepool_t *freepool)
93 : {
94 : cairo_freelist_pool_t *pool;
95 : uint8_t *ptr;
96 :
97 0 : pool = freepool->pools;
98 0 : if (unlikely (freepool->nodesize > pool->rem))
99 0 : return _cairo_freepool_alloc_from_new_pool (freepool);
100 :
101 0 : ptr = pool->data;
102 0 : pool->data += freepool->nodesize;
103 0 : pool->rem -= freepool->nodesize;
104 : VG (VALGRIND_MAKE_MEM_UNDEFINED (ptr, freepool->nodesize));
105 0 : return ptr;
106 : }
107 :
108 : static inline void *
109 0 : _cairo_freepool_alloc (cairo_freepool_t *freepool)
110 : {
111 : cairo_freelist_node_t *node;
112 :
113 0 : node = freepool->first_free_node;
114 0 : if (unlikely (node == NULL))
115 0 : return _cairo_freepool_alloc_from_pool (freepool);
116 :
117 : VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
118 0 : freepool->first_free_node = node->next;
119 : VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize));
120 :
121 0 : return node;
122 : }
123 :
124 : cairo_private cairo_status_t
125 : _cairo_freepool_alloc_array (cairo_freepool_t *freepool,
126 : int count,
127 : void **array);
128 :
129 : static inline void
130 0 : _cairo_freepool_free (cairo_freepool_t *freepool, void *ptr)
131 : {
132 0 : cairo_freelist_node_t *node = ptr;
133 :
134 0 : node->next = freepool->first_free_node;
135 0 : freepool->first_free_node = node;
136 : VG (VALGRIND_MAKE_MEM_NOACCESS (node, freepool->nodesize));
137 0 : }
138 :
139 : #endif /* CAIRO_FREELIST_H */
|