gkdbus: Fix underflow and unreachable code bug
[platform/upstream/glib.git] / glib / gslice.c
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  * SECTION:memory_slices
35  * @title: Memory Slices
36  * @short_description: efficient way to allocate groups of equal-sized
37  *     chunks of memory
38  *
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
43  * was written.
44  *
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.
47  *
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.
51  *
52  * Here is an example for using the slice allocator:
53  * |[<!-- language="C" --> 
54  * gchar *mem[10000];
55  * gint i;
56  *
57  * // Allocate 10000 blocks.
58  * for (i = 0; i < 10000; i++)
59  *   {
60  *     mem[i] = g_slice_alloc (50);
61  *
62  *     // Fill in the memory with some junk.
63  *     for (j = 0; j < 50; j++)
64  *       mem[i][j] = i * j;
65  *   }
66  *
67  * // Now free all of the blocks.
68  * for (i = 0; i < 10000; i++)
69  *   g_slice_free1 (50, mem[i]);
70  * ]|
71  *
72  * And here is an example for using the using the slice allocator
73  * with data structures:
74  * |[<!-- language="C" --> 
75  * GRealArray *array;
76  *
77  * // Allocate one block, using the g_slice_new() macro.
78  * array = g_slice_new (GRealArray);
79  *
80  * // We can now use array just like a normal pointer to a structure.
81  * array->data            = NULL;
82  * array->len             = 0;
83  * array->alloc           = 0;
84  * array->zero_terminated = (zero_terminated ? 1 : 0);
85  * array->clear           = (clear ? 1 : 0);
86  * array->elt_size        = elt_size;
87  *
88  * // We can free the block, so it can be reused.
89  * g_slice_free (GRealArray, array);
90  * ]|
91  */
92
93 /* --- auxiliary functions --- */
94 void
95 g_slice_set_config (GSliceConfig ckey,
96                     gint64       value)
97 {
98   /* deprecated, no implementation */
99 }
100
101 gint64
102 g_slice_get_config (GSliceConfig ckey)
103 {
104   /* deprecated, no implementation */
105   return 0;
106 }
107
108 gint64*
109 g_slice_get_config_state (GSliceConfig ckey,
110                           gint64       address,
111                           guint       *n_values)
112 {
113   /* deprecated, no implementation */
114   return NULL;
115 }
116
117 /* --- API functions --- */
118
119 /**
120  * g_slice_new:
121  * @type: the type to allocate, typically a structure name
122  *
123  * A convenience macro to allocate a block of memory from the
124  * slice allocator.
125  *
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.
129  *
130  * This can never return %NULL as the minimum allocation size from
131  * `sizeof (@type)` is 1 byte.
132  *
133  * Since GLib 2.76 this always uses the system malloc() implementation
134  * internally.
135  *
136  * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
137  *    to @type
138  *
139  * Since: 2.10
140  */
141
142 /**
143  * g_slice_new0:
144  * @type: the type to allocate, typically a structure name
145  *
146  * A convenience macro to allocate a block of memory from the
147  * slice allocator and set the memory to 0.
148  *
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.
152  *
153  * This can never return %NULL as the minimum allocation size from
154  * `sizeof (@type)` is 1 byte.
155  *
156  * Since GLib 2.76 this always uses the system malloc() implementation
157  * internally.
158  *
159  * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
160  *    to @type
161  *
162  * Since: 2.10
163  */
164
165 /**
166  * g_slice_dup:
167  * @type: the type to duplicate, typically a structure name
168  * @mem: (not nullable): the memory to copy into the allocated block
169  *
170  * A convenience macro to duplicate a block of memory using
171  * the slice allocator.
172  *
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.
176  *
177  * This can never return %NULL.
178  *
179  * Since GLib 2.76 this always uses the system malloc() implementation
180  * internally.
181  *
182  * Returns: (not nullable): a pointer to the allocated block, cast to a pointer
183  *    to @type
184  *
185  * Since: 2.14
186  */
187
188 /**
189  * g_slice_free:
190  * @type: the type of the block to free, typically a structure name
191  * @mem: (nullable): a pointer to the block to free
192  *
193  * A convenience macro to free a block of memory that has
194  * been allocated from the slice allocator.
195  *
196  * It calls g_slice_free1() using `sizeof (type)`
197  * as the block size.
198  * Note that the exact release behaviour can be changed with the
199  * [`G_DEBUG=gc-friendly`][G_DEBUG] environment variable.
200  *
201  * If @mem is %NULL, this macro does nothing.
202  *
203  * Since GLib 2.76 this always uses the system free() implementation internally.
204  *
205  * Since: 2.10
206  */
207
208 /**
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
213  *
214  * Frees a linked list of memory blocks of structure type @type.
215  *
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.
222  *
223  * If @mem_chain is %NULL, this function does nothing.
224  *
225  * Since GLib 2.76 this always uses the system free() implementation internally.
226  *
227  * Since: 2.10
228  */
229
230 /**
231  * g_slice_alloc:
232  * @block_size: the number of bytes to allocate
233  *
234  * Allocates a block of memory from the libc allocator.
235  *
236  * The block address handed out can be expected to be aligned
237  * to at least `1 * sizeof (void*)`.
238  *
239  * Since GLib 2.76 this always uses the system malloc() implementation
240  * internally.
241  *
242  * Returns: (nullable): a pointer to the allocated memory block, which will
243  *   be %NULL if and only if @mem_size is 0
244  *
245  * Since: 2.10
246  */
247 gpointer
248 g_slice_alloc (gsize mem_size)
249 {
250   gpointer mem;
251
252   mem = g_malloc (mem_size);
253   TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
254
255   return mem;
256 }
257
258 /**
259  * g_slice_alloc0:
260  * @block_size: the number of bytes to allocate
261  *
262  * Allocates a block of memory via g_slice_alloc() and initializes
263  * the returned memory to 0.
264  *
265  * Since GLib 2.76 this always uses the system malloc() implementation
266  * internally.
267  *
268  * Returns: (nullable): a pointer to the allocated block, which will be %NULL
269  *    if and only if @mem_size is 0
270  *
271  * Since: 2.10
272  */
273 gpointer
274 g_slice_alloc0 (gsize mem_size)
275 {
276   gpointer mem = g_slice_alloc (mem_size);
277   if (mem)
278     memset (mem, 0, mem_size);
279   return mem;
280 }
281
282 /**
283  * g_slice_copy:
284  * @block_size: the number of bytes to allocate
285  * @mem_block: the memory to copy
286  *
287  * Allocates a block of memory from the slice allocator
288  * and copies @block_size bytes into it from @mem_block.
289  *
290  * @mem_block must be non-%NULL if @block_size is non-zero.
291  *
292  * Since GLib 2.76 this always uses the system malloc() implementation
293  * internally.
294  *
295  * Returns: (nullable): a pointer to the allocated memory block,
296  *    which will be %NULL if and only if @mem_size is 0
297  *
298  * Since: 2.14
299  */
300 gpointer
301 g_slice_copy (gsize         mem_size,
302               gconstpointer mem_block)
303 {
304   gpointer mem = g_slice_alloc (mem_size);
305   if (mem)
306     memcpy (mem, mem_block, mem_size);
307   return mem;
308 }
309
310 /**
311  * g_slice_free1:
312  * @block_size: the size of the block
313  * @mem_block: (nullable): a pointer to the block to free
314  *
315  * Frees a block of memory.
316  *
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
321  * variable.
322  *
323  * If @mem_block is %NULL, this function does nothing.
324  *
325  * Since GLib 2.76 this always uses the system free_sized() implementation
326  * internally.
327  *
328  * Since: 2.10
329  */
330 void
331 g_slice_free1 (gsize    mem_size,
332                gpointer mem_block)
333 {
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));
338 }
339
340 /**
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
345  *
346  * Frees a linked list of memory blocks of structure type @type.
347  *
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.
354  *
355  * If @mem_chain is %NULL, this function does nothing.
356  *
357  * Since GLib 2.76 this always uses the system free_sized() implementation
358  * internally.
359  *
360  * Since: 2.10
361  */
362 void
363 g_slice_free_chain_with_offset (gsize    mem_size,
364                                 gpointer mem_chain,
365                                 gsize    next_offset)
366 {
367   gpointer slice = mem_chain;
368   while (slice)
369     {
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);
375     }
376 }
377
378 #ifdef G_ENABLE_DEBUG
379 void
380 g_slice_debug_tree_statistics (void)
381 {
382   g_fprintf (stderr, "GSlice: Implementation dropped in GLib 2.76\n");
383 }
384 #endif /* G_ENABLE_DEBUG */