Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 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 | |||
23 | #include "cairoint.h" |
||
24 | |||
25 | #include "cairo-error-private.h" |
||
26 | #include "cairo-freelist-private.h" |
||
27 | |||
28 | void |
||
29 | _cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize) |
||
30 | { |
||
31 | memset (freelist, 0, sizeof (cairo_freelist_t)); |
||
32 | freelist->nodesize = nodesize; |
||
33 | } |
||
34 | |||
35 | void |
||
36 | _cairo_freelist_fini (cairo_freelist_t *freelist) |
||
37 | { |
||
38 | cairo_freelist_node_t *node = freelist->first_free_node; |
||
39 | while (node) { |
||
40 | cairo_freelist_node_t *next; |
||
41 | |||
42 | VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); |
||
43 | next = node->next; |
||
44 | |||
45 | free (node); |
||
46 | node = next; |
||
47 | } |
||
48 | } |
||
49 | |||
50 | void * |
||
51 | _cairo_freelist_alloc (cairo_freelist_t *freelist) |
||
52 | { |
||
53 | if (freelist->first_free_node) { |
||
54 | cairo_freelist_node_t *node; |
||
55 | |||
56 | node = freelist->first_free_node; |
||
57 | VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); |
||
58 | freelist->first_free_node = node->next; |
||
59 | VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize)); |
||
60 | |||
61 | return node; |
||
62 | } |
||
63 | |||
64 | return malloc (freelist->nodesize); |
||
65 | } |
||
66 | |||
67 | void * |
||
68 | _cairo_freelist_calloc (cairo_freelist_t *freelist) |
||
69 | { |
||
70 | void *node = _cairo_freelist_alloc (freelist); |
||
71 | if (node) |
||
72 | memset (node, 0, freelist->nodesize); |
||
73 | return node; |
||
74 | } |
||
75 | |||
76 | void |
||
77 | _cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode) |
||
78 | { |
||
79 | cairo_freelist_node_t *node = voidnode; |
||
80 | if (node) { |
||
81 | node->next = freelist->first_free_node; |
||
82 | freelist->first_free_node = node; |
||
83 | VG (VALGRIND_MAKE_MEM_NOACCESS (node, freelist->nodesize)); |
||
84 | } |
||
85 | } |
||
86 | |||
87 | void |
||
88 | _cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize) |
||
89 | { |
||
90 | freepool->first_free_node = NULL; |
||
91 | freepool->pools = &freepool->embedded_pool; |
||
92 | freepool->freepools = NULL; |
||
93 | freepool->nodesize = nodesize; |
||
94 | |||
95 | freepool->embedded_pool.next = NULL; |
||
96 | freepool->embedded_pool.size = sizeof (freepool->embedded_data); |
||
97 | freepool->embedded_pool.rem = sizeof (freepool->embedded_data); |
||
98 | freepool->embedded_pool.data = freepool->embedded_data; |
||
99 | |||
100 | VG (VALGRIND_MAKE_MEM_NOACCESS (freepool->embedded_data, sizeof (freepool->embedded_data))); |
||
101 | } |
||
102 | |||
103 | void |
||
104 | _cairo_freepool_fini (cairo_freepool_t *freepool) |
||
105 | { |
||
106 | cairo_freelist_pool_t *pool; |
||
107 | |||
108 | pool = freepool->pools; |
||
109 | while (pool != &freepool->embedded_pool) { |
||
110 | cairo_freelist_pool_t *next = pool->next; |
||
111 | free (pool); |
||
112 | pool = next; |
||
113 | } |
||
114 | |||
115 | pool = freepool->freepools; |
||
116 | while (pool != NULL) { |
||
117 | cairo_freelist_pool_t *next = pool->next; |
||
118 | free (pool); |
||
119 | pool = next; |
||
120 | } |
||
121 | |||
122 | VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool))); |
||
123 | } |
||
124 | |||
125 | void * |
||
126 | _cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool) |
||
127 | { |
||
128 | cairo_freelist_pool_t *pool; |
||
129 | int poolsize; |
||
130 | |||
131 | if (freepool->freepools != NULL) { |
||
132 | pool = freepool->freepools; |
||
133 | freepool->freepools = pool->next; |
||
134 | |||
135 | poolsize = pool->size; |
||
136 | } else { |
||
137 | if (freepool->pools != &freepool->embedded_pool) |
||
138 | poolsize = 2 * freepool->pools->size; |
||
139 | else |
||
140 | poolsize = (128 * freepool->nodesize + 8191) & -8192; |
||
141 | |||
142 | pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize); |
||
143 | if (unlikely (pool == NULL)) |
||
144 | return pool; |
||
145 | |||
146 | pool->size = poolsize; |
||
147 | } |
||
148 | |||
149 | pool->next = freepool->pools; |
||
150 | freepool->pools = pool; |
||
151 | |||
152 | pool->rem = poolsize - freepool->nodesize; |
||
153 | pool->data = (uint8_t *) (pool + 1) + freepool->nodesize; |
||
154 | |||
155 | VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, pool->rem)); |
||
156 | |||
157 | return pool + 1; |
||
158 | } |
||
159 | |||
160 | cairo_status_t |
||
161 | _cairo_freepool_alloc_array (cairo_freepool_t *freepool, |
||
162 | int count, |
||
163 | void **array) |
||
164 | { |
||
165 | int i; |
||
166 | |||
167 | for (i = 0; i < count; i++) { |
||
168 | cairo_freelist_node_t *node; |
||
169 | |||
170 | node = freepool->first_free_node; |
||
171 | if (likely (node != NULL)) { |
||
172 | VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next))); |
||
173 | freepool->first_free_node = node->next; |
||
174 | VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize)); |
||
175 | } else { |
||
176 | node = _cairo_freepool_alloc_from_pool (freepool); |
||
177 | if (unlikely (node == NULL)) |
||
178 | goto CLEANUP; |
||
179 | } |
||
180 | |||
181 | array[i] = node; |
||
182 | } |
||
183 | |||
184 | return CAIRO_STATUS_SUCCESS; |
||
185 | |||
186 | CLEANUP: |
||
187 | while (i--) |
||
188 | _cairo_freepool_free (freepool, array[i]); |
||
189 | |||
190 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
||
191 | }> |