Coverage Report

Created: 2025-11-16 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glib-2.80.0/glib/gslice.c
Line
Count
Source
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
g_slice_set_config (GSliceConfig ckey,
37
                    gint64       value)
38
0
{
39
  /* deprecated, no implementation */
40
0
}
41
42
gint64
43
g_slice_get_config (GSliceConfig ckey)
44
0
{
45
  /* deprecated, no implementation */
46
0
  return 0;
47
0
}
48
49
gint64*
50
g_slice_get_config_state (GSliceConfig ckey,
51
                          gint64       address,
52
                          guint       *n_values)
53
0
{
54
  /* deprecated, no implementation */
55
0
  return NULL;
56
0
}
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`][G_DEBUG] 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`][G_DEBUG] 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
g_slice_alloc (gsize mem_size)
190
26.6k
{
191
26.6k
  gpointer mem;
192
193
26.6k
  mem = g_malloc (mem_size);
194
26.6k
  TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
195
196
26.6k
  return mem;
197
26.6k
}
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
g_slice_alloc0 (gsize mem_size)
216
12.9k
{
217
12.9k
  gpointer mem = g_slice_alloc (mem_size);
218
12.9k
  if (mem)
219
12.9k
    memset (mem, 0, mem_size);
220
12.9k
  return mem;
221
12.9k
}
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
g_slice_copy (gsize         mem_size,
243
              gconstpointer mem_block)
244
0
{
245
0
  gpointer mem = g_slice_alloc (mem_size);
246
0
  if (mem)
247
0
    memcpy (mem, mem_block, mem_size);
248
0
  return mem;
249
0
}
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`][G_DEBUG] 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
g_slice_free1 (gsize    mem_size,
273
               gpointer mem_block)
274
19.6k
{
275
19.6k
  if (G_UNLIKELY (g_mem_gc_friendly && mem_block))
276
0
    memset (mem_block, 0, mem_size);
277
19.6k
  g_free_sized (mem_block, mem_size);
278
19.6k
  TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
279
19.6k
}
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`][G_DEBUG] 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
g_slice_free_chain_with_offset (gsize    mem_size,
305
                                gpointer mem_chain,
306
                                gsize    next_offset)
307
36.9k
{
308
36.9k
  gpointer slice = mem_chain;
309
43.8k
  while (slice)
310
6.89k
    {
311
6.89k
      guint8 *current = slice;
312
6.89k
      slice = *(gpointer *) (current + next_offset);
313
6.89k
      if (G_UNLIKELY (g_mem_gc_friendly))
314
0
        memset (current, 0, mem_size);
315
6.89k
      g_free_sized (current, mem_size);
316
6.89k
    }
317
36.9k
}
318
319
#ifdef G_ENABLE_DEBUG
320
void
321
g_slice_debug_tree_statistics (void)
322
{
323
  g_fprintf (stderr, "GSlice: Implementation dropped in GLib 2.76\n");
324
}
325
#endif /* G_ENABLE_DEBUG */