Branch data Line data Source code
1 : : /* GLIB sliced memory - fast concurrent memory chunk allocator
2 : : * Copyright (C) 2005 Tim Janik
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * This library is distributed in the hope that it will be useful,
12 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : * Lesser General Public License for more details.
15 : : *
16 : : * You should have received a copy of the GNU Lesser General Public
17 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 : : */
19 : : /* MT safe */
20 : :
21 : : #include "config.h"
22 : : #include "glibconfig.h"
23 : :
24 : : #include <stdio.h>
25 : : #include <string.h>
26 : :
27 : : #include "gslice.h"
28 : :
29 : : #include "gmem.h" /* gslice.h */
30 : : #include "glib_trace.h"
31 : : #include "gprintf.h"
32 : :
33 : :
34 : : /* --- auxiliary functions --- */
35 : : void
36 : 0 : g_slice_set_config (GSliceConfig ckey,
37 : : gint64 value)
38 : : {
39 : : /* deprecated, no implementation */
40 : 0 : }
41 : :
42 : : gint64
43 : 0 : g_slice_get_config (GSliceConfig ckey)
44 : : {
45 : : /* deprecated, no implementation */
46 : 0 : return 0;
47 : : }
48 : :
49 : : gint64*
50 : 0 : g_slice_get_config_state (GSliceConfig ckey,
51 : : gint64 address,
52 : : guint *n_values)
53 : : {
54 : : /* deprecated, no implementation */
55 : 0 : return NULL;
56 : : }
57 : :
58 : : /* --- API functions --- */
59 : :
60 : : /**
61 : : * g_slice_new:
62 : : * @type: the type to allocate, typically a structure name
63 : : *
64 : : * A convenience macro to allocate a block of memory from the
65 : : * slice allocator.
66 : : *
67 : : * It calls g_slice_alloc() with `sizeof (@type)` and casts the
68 : : * returned pointer to a pointer of the given type, avoiding a type
69 : : * cast in the source code.
70 : : *
71 : : * This can never return %NULL as the minimum allocation size from
72 : : * `sizeof (@type)` is 1 byte.
73 : : *
74 : : * Since GLib 2.76 this always uses the system malloc() implementation
75 : : * internally.
76 : : *
77 : : * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
78 : : * to @type
79 : : *
80 : : * Since: 2.10
81 : : */
82 : :
83 : : /**
84 : : * g_slice_new0:
85 : : * @type: the type to allocate, typically a structure name
86 : : *
87 : : * A convenience macro to allocate a block of memory from the
88 : : * slice allocator and set the memory to 0.
89 : : *
90 : : * It calls g_slice_alloc0() with `sizeof (@type)`
91 : : * and casts the returned pointer to a pointer of the given type,
92 : : * avoiding a type cast in the source code.
93 : : *
94 : : * This can never return %NULL as the minimum allocation size from
95 : : * `sizeof (@type)` is 1 byte.
96 : : *
97 : : * Since GLib 2.76 this always uses the system malloc() implementation
98 : : * internally.
99 : : *
100 : : * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
101 : : * to @type
102 : : *
103 : : * Since: 2.10
104 : : */
105 : :
106 : : /**
107 : : * g_slice_dup:
108 : : * @type: the type to duplicate, typically a structure name
109 : : * @mem: (not nullable): the memory to copy into the allocated block
110 : : *
111 : : * A convenience macro to duplicate a block of memory using
112 : : * the slice allocator.
113 : : *
114 : : * It calls g_slice_copy() with `sizeof (@type)`
115 : : * and casts the returned pointer to a pointer of the given type,
116 : : * avoiding a type cast in the source code.
117 : : *
118 : : * This can never return %NULL.
119 : : *
120 : : * Since GLib 2.76 this always uses the system malloc() implementation
121 : : * internally.
122 : : *
123 : : * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
124 : : * to @type
125 : : *
126 : : * Since: 2.14
127 : : */
128 : :
129 : : /**
130 : : * g_slice_free:
131 : : * @type: the type of the block to free, typically a structure name
132 : : * @mem: (nullable): a pointer to the block to free
133 : : *
134 : : * A convenience macro to free a block of memory that has
135 : : * been allocated from the slice allocator.
136 : : *
137 : : * It calls g_slice_free1() using `sizeof (type)`
138 : : * as the block size.
139 : : * Note that the exact release behaviour can be changed with the
140 : : * [`G_DEBUG=gc-friendly`](running.html#environment-variables) environment variable.
141 : : *
142 : : * If @mem is %NULL, this macro does nothing.
143 : : *
144 : : * Since GLib 2.76 this always uses the system free() implementation internally.
145 : : *
146 : : * Since: 2.10
147 : : */
148 : :
149 : : /**
150 : : * g_slice_free_chain:
151 : : * @type: the type of the @mem_chain blocks
152 : : * @mem_chain: (nullable): a pointer to the first block of the chain
153 : : * @next: the field name of the next pointer in @type
154 : : *
155 : : * Frees a linked list of memory blocks of structure type @type.
156 : : *
157 : : * The memory blocks must be equal-sized, allocated via
158 : : * g_slice_alloc() or g_slice_alloc0() and linked together by
159 : : * a @next pointer (similar to #GSList). The name of the
160 : : * @next field in @type is passed as third argument.
161 : : * Note that the exact release behaviour can be changed with the
162 : : * [`G_DEBUG=gc-friendly`](running.html#environment-variables) environment variable.
163 : : *
164 : : * If @mem_chain is %NULL, this function does nothing.
165 : : *
166 : : * Since GLib 2.76 this always uses the system free() implementation internally.
167 : : *
168 : : * Since: 2.10
169 : : */
170 : :
171 : : /**
172 : : * g_slice_alloc:
173 : : * @block_size: the number of bytes to allocate
174 : : *
175 : : * Allocates a block of memory from the libc allocator.
176 : : *
177 : : * The block address handed out can be expected to be aligned
178 : : * to at least `1 * sizeof (void*)`.
179 : : *
180 : : * Since GLib 2.76 this always uses the system malloc() implementation
181 : : * internally.
182 : : *
183 : : * Returns: (nullable): a pointer to the allocated memory block, which will
184 : : * be %NULL if and only if @mem_size is 0
185 : : *
186 : : * Since: 2.10
187 : : */
188 : : gpointer
189 : 31771201 : g_slice_alloc (gsize mem_size)
190 : : {
191 : : gpointer mem;
192 : :
193 : 31771201 : mem = g_malloc (mem_size);
194 : 31771201 : TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
195 : :
196 : 31771201 : return mem;
197 : : }
198 : :
199 : : /**
200 : : * g_slice_alloc0:
201 : : * @block_size: the number of bytes to allocate
202 : : *
203 : : * Allocates a block of memory via g_slice_alloc() and initializes
204 : : * the returned memory to 0.
205 : : *
206 : : * Since GLib 2.76 this always uses the system malloc() implementation
207 : : * internally.
208 : : *
209 : : * Returns: (nullable): a pointer to the allocated block, which will be %NULL
210 : : * if and only if @mem_size is 0
211 : : *
212 : : * Since: 2.10
213 : : */
214 : : gpointer
215 : 10553524 : g_slice_alloc0 (gsize mem_size)
216 : : {
217 : 10553524 : gpointer mem = g_slice_alloc (mem_size);
218 : 10553524 : if (mem)
219 : 10553524 : memset (mem, 0, mem_size);
220 : 10553524 : return mem;
221 : : }
222 : :
223 : : /**
224 : : * g_slice_copy:
225 : : * @block_size: the number of bytes to allocate
226 : : * @mem_block: the memory to copy
227 : : *
228 : : * Allocates a block of memory from the slice allocator
229 : : * and copies @block_size bytes into it from @mem_block.
230 : : *
231 : : * @mem_block must be non-%NULL if @block_size is non-zero.
232 : : *
233 : : * Since GLib 2.76 this always uses the system malloc() implementation
234 : : * internally.
235 : : *
236 : : * Returns: (nullable): a pointer to the allocated memory block,
237 : : * which will be %NULL if and only if @mem_size is 0
238 : : *
239 : : * Since: 2.14
240 : : */
241 : : gpointer
242 : 15141 : g_slice_copy (gsize mem_size,
243 : : gconstpointer mem_block)
244 : : {
245 : 15141 : gpointer mem = g_slice_alloc (mem_size);
246 : 15141 : if (mem)
247 : 15141 : memcpy (mem, mem_block, mem_size);
248 : 15141 : return mem;
249 : : }
250 : :
251 : : /**
252 : : * g_slice_free1:
253 : : * @block_size: the size of the block
254 : : * @mem_block: (nullable): a pointer to the block to free
255 : : *
256 : : * Frees a block of memory.
257 : : *
258 : : * The memory must have been allocated via g_slice_alloc() or
259 : : * g_slice_alloc0() and the @block_size has to match the size
260 : : * specified upon allocation. Note that the exact release behaviour
261 : : * can be changed with the [`G_DEBUG=gc-friendly`](running.html#environment-variables) environment
262 : : * variable.
263 : : *
264 : : * If @mem_block is %NULL, this function does nothing.
265 : : *
266 : : * Since GLib 2.76 this always uses the system free_sized() implementation
267 : : * internally.
268 : : *
269 : : * Since: 2.10
270 : : */
271 : : void
272 : 20441648 : g_slice_free1 (gsize mem_size,
273 : : gpointer mem_block)
274 : : {
275 : 20441648 : if (G_UNLIKELY (g_mem_gc_friendly && mem_block))
276 : 20095146 : memset (mem_block, 0, mem_size);
277 : 20441648 : g_free_sized (mem_block, mem_size);
278 : 20441648 : TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
279 : 20441648 : }
280 : :
281 : : /**
282 : : * g_slice_free_chain_with_offset:
283 : : * @block_size: the size of the blocks
284 : : * @mem_chain: (nullable): a pointer to the first block of the chain
285 : : * @next_offset: the offset of the @next field in the blocks
286 : : *
287 : : * Frees a linked list of memory blocks of structure type @type.
288 : : *
289 : : * The memory blocks must be equal-sized, allocated via
290 : : * g_slice_alloc() or g_slice_alloc0() and linked together by a
291 : : * @next pointer (similar to #GSList). The offset of the @next
292 : : * field in each block is passed as third argument.
293 : : * Note that the exact release behaviour can be changed with the
294 : : * [`G_DEBUG=gc-friendly`](running.html#environment-variables) environment variable.
295 : : *
296 : : * If @mem_chain is %NULL, this function does nothing.
297 : : *
298 : : * Since GLib 2.76 this always uses the system free_sized() implementation
299 : : * internally.
300 : : *
301 : : * Since: 2.10
302 : : */
303 : : void
304 : 9318877 : g_slice_free_chain_with_offset (gsize mem_size,
305 : : gpointer mem_chain,
306 : : gsize next_offset)
307 : : {
308 : 9318877 : gpointer slice = mem_chain;
309 : 20471797 : while (slice)
310 : : {
311 : 11152920 : guint8 *current = slice;
312 : 11152920 : slice = *(gpointer *) (current + next_offset);
313 : 11152920 : if (G_UNLIKELY (g_mem_gc_friendly))
314 : 10908545 : memset (current, 0, mem_size);
315 : 11152920 : g_free_sized (current, mem_size);
316 : : }
317 : 9318877 : }
318 : :
319 : : #ifdef G_ENABLE_DEBUG
320 : : void
321 : 0 : g_slice_debug_tree_statistics (void)
322 : : {
323 : 0 : g_fprintf (stderr, "GSlice: Implementation dropped in GLib 2.76\n");
324 : 0 : }
325 : : #endif /* G_ENABLE_DEBUG */
|