1 /* GLIB sliced memory - fast concurrent memory chunk allocator
2 * Copyright (C) 2005 Tim Janik
4 * SPDX-License-Identifier: LGPL-2.1-or-later
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.
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.
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/>.
22 #include "glibconfig.h"
29 #include "gmem.h" /* gslice.h */
30 #include "glib_trace.h"
34 * SECTION:memory_slices
35 * @title: Memory Slices
36 * @short_description: efficient way to allocate groups of equal-sized
39 * GSlice was a space-efficient and multi-processing scalable way to allocate
40 * equal sized pieces of memory. Since GLib 2.76, its implementation has been
41 * removed and it calls g_malloc() and g_free_sized(), because the performance
42 * of the system-default allocators has improved on all platforms since GSlice
45 * The GSlice APIs have not been deprecated, as they are widely in use and doing
46 * so would be very disruptive for little benefit.
48 * New code should be written using g_new()/g_malloc() and g_free_sized() or
49 * g_free(). There is no particular benefit in porting existing code away from
50 * g_slice_new()/g_slice_free() unless it’s being rewritten anyway.
52 * Here is an example for using the slice allocator:
53 * |[<!-- language="C" -->
57 * // Allocate 10000 blocks.
58 * for (i = 0; i < 10000; i++)
60 * mem[i] = g_slice_alloc (50);
62 * // Fill in the memory with some junk.
63 * for (j = 0; j < 50; j++)
67 * // Now free all of the blocks.
68 * for (i = 0; i < 10000; i++)
69 * g_slice_free1 (50, mem[i]);
72 * And here is an example for using the using the slice allocator
73 * with data structures:
74 * |[<!-- language="C" -->
77 * // Allocate one block, using the g_slice_new() macro.
78 * array = g_slice_new (GRealArray);
80 * // We can now use array just like a normal pointer to a structure.
84 * array->zero_terminated = (zero_terminated ? 1 : 0);
85 * array->clear = (clear ? 1 : 0);
86 * array->elt_size = elt_size;
88 * // We can free the block, so it can be reused.
89 * g_slice_free (GRealArray, array);
93 /* --- auxiliary functions --- */
95 g_slice_set_config (GSliceConfig ckey,
98 /* deprecated, no implementation */
102 g_slice_get_config (GSliceConfig ckey)
104 /* deprecated, no implementation */
109 g_slice_get_config_state (GSliceConfig ckey,
113 /* deprecated, no implementation */
117 /* --- API functions --- */
121 * @type: the type to allocate, typically a structure name
123 * A convenience macro to allocate a block of memory from the
126 * It calls g_slice_alloc() with `sizeof (@type)` and casts the
127 * returned pointer to a pointer of the given type, avoiding a type
128 * cast in the source code.
130 * This can never return %NULL as the minimum allocation size from
131 * `sizeof (@type)` is 1 byte.
133 * Since GLib 2.76 this always uses the system malloc() implementation
136 * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
144 * @type: the type to allocate, typically a structure name
146 * A convenience macro to allocate a block of memory from the
147 * slice allocator and set the memory to 0.
149 * It calls g_slice_alloc0() with `sizeof (@type)`
150 * and casts the returned pointer to a pointer of the given type,
151 * avoiding a type cast in the source code.
153 * This can never return %NULL as the minimum allocation size from
154 * `sizeof (@type)` is 1 byte.
156 * Since GLib 2.76 this always uses the system malloc() implementation
159 * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
167 * @type: the type to duplicate, typically a structure name
168 * @mem: (not nullable): the memory to copy into the allocated block
170 * A convenience macro to duplicate a block of memory using
171 * the slice allocator.
173 * It calls g_slice_copy() with `sizeof (@type)`
174 * and casts the returned pointer to a pointer of the given type,
175 * avoiding a type cast in the source code.
177 * This can never return %NULL.
179 * Since GLib 2.76 this always uses the system malloc() implementation
182 * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
190 * @type: the type of the block to free, typically a structure name
191 * @mem: (nullable): a pointer to the block to free
193 * A convenience macro to free a block of memory that has
194 * been allocated from the slice allocator.
196 * It calls g_slice_free1() using `sizeof (type)`
198 * Note that the exact release behaviour can be changed with the
199 * [`G_DEBUG=gc-friendly`][G_DEBUG] environment variable.
201 * If @mem is %NULL, this macro does nothing.
203 * Since GLib 2.76 this always uses the system free() implementation internally.
209 * g_slice_free_chain:
210 * @type: the type of the @mem_chain blocks
211 * @mem_chain: (nullable): a pointer to the first block of the chain
212 * @next: the field name of the next pointer in @type
214 * Frees a linked list of memory blocks of structure type @type.
216 * The memory blocks must be equal-sized, allocated via
217 * g_slice_alloc() or g_slice_alloc0() and linked together by
218 * a @next pointer (similar to #GSList). The name of the
219 * @next field in @type is passed as third argument.
220 * Note that the exact release behaviour can be changed with the
221 * [`G_DEBUG=gc-friendly`][G_DEBUG] environment variable.
223 * If @mem_chain is %NULL, this function does nothing.
225 * Since GLib 2.76 this always uses the system free() implementation internally.
232 * @block_size: the number of bytes to allocate
234 * Allocates a block of memory from the libc allocator.
236 * The block address handed out can be expected to be aligned
237 * to at least `1 * sizeof (void*)`.
239 * Since GLib 2.76 this always uses the system malloc() implementation
242 * Returns: (nullable): a pointer to the allocated memory block, which will
243 * be %NULL if and only if @mem_size is 0
248 g_slice_alloc (gsize mem_size)
252 mem = g_malloc (mem_size);
253 TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
260 * @block_size: the number of bytes to allocate
262 * Allocates a block of memory via g_slice_alloc() and initializes
263 * the returned memory to 0.
265 * Since GLib 2.76 this always uses the system malloc() implementation
268 * Returns: (nullable): a pointer to the allocated block, which will be %NULL
269 * if and only if @mem_size is 0
274 g_slice_alloc0 (gsize mem_size)
276 gpointer mem = g_slice_alloc (mem_size);
278 memset (mem, 0, mem_size);
284 * @block_size: the number of bytes to allocate
285 * @mem_block: the memory to copy
287 * Allocates a block of memory from the slice allocator
288 * and copies @block_size bytes into it from @mem_block.
290 * @mem_block must be non-%NULL if @block_size is non-zero.
292 * Since GLib 2.76 this always uses the system malloc() implementation
295 * Returns: (nullable): a pointer to the allocated memory block,
296 * which will be %NULL if and only if @mem_size is 0
301 g_slice_copy (gsize mem_size,
302 gconstpointer mem_block)
304 gpointer mem = g_slice_alloc (mem_size);
306 memcpy (mem, mem_block, mem_size);
312 * @block_size: the size of the block
313 * @mem_block: (nullable): a pointer to the block to free
315 * Frees a block of memory.
317 * The memory must have been allocated via g_slice_alloc() or
318 * g_slice_alloc0() and the @block_size has to match the size
319 * specified upon allocation. Note that the exact release behaviour
320 * can be changed with the [`G_DEBUG=gc-friendly`][G_DEBUG] environment
323 * If @mem_block is %NULL, this function does nothing.
325 * Since GLib 2.76 this always uses the system free_sized() implementation
331 g_slice_free1 (gsize mem_size,
334 if (G_UNLIKELY (g_mem_gc_friendly && mem_block))
335 memset (mem_block, 0, mem_size);
336 g_free_sized (mem_block, mem_size);
337 TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
341 * g_slice_free_chain_with_offset:
342 * @block_size: the size of the blocks
343 * @mem_chain: (nullable): a pointer to the first block of the chain
344 * @next_offset: the offset of the @next field in the blocks
346 * Frees a linked list of memory blocks of structure type @type.
348 * The memory blocks must be equal-sized, allocated via
349 * g_slice_alloc() or g_slice_alloc0() and linked together by a
350 * @next pointer (similar to #GSList). The offset of the @next
351 * field in each block is passed as third argument.
352 * Note that the exact release behaviour can be changed with the
353 * [`G_DEBUG=gc-friendly`][G_DEBUG] environment variable.
355 * If @mem_chain is %NULL, this function does nothing.
357 * Since GLib 2.76 this always uses the system free_sized() implementation
363 g_slice_free_chain_with_offset (gsize mem_size,
367 gpointer slice = mem_chain;
370 guint8 *current = slice;
371 slice = *(gpointer *) (current + next_offset);
372 if (G_UNLIKELY (g_mem_gc_friendly))
373 memset (current, 0, mem_size);
374 g_free_sized (current, mem_size);
378 #ifdef G_ENABLE_DEBUG
380 g_slice_debug_tree_statistics (void)
382 g_fprintf (stderr, "GSlice: Implementation dropped in GLib 2.76\n");
384 #endif /* G_ENABLE_DEBUG */