LCOV - code coverage report
Current view: top level - glib/glib - gslice.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 29 38 76.3 %
Date: 2024-04-23 05:16:05 Functions: 5 9 55.6 %
Branches: 10 12 83.3 %

           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`][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                 :   37705079 : g_slice_alloc (gsize mem_size)
     190                 :            : {
     191                 :            :   gpointer mem;
     192                 :            : 
     193                 :   37705079 :   mem = g_malloc (mem_size);
     194                 :   37705079 :   TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
     195                 :            : 
     196                 :   37705079 :   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                 :   10594185 : g_slice_alloc0 (gsize mem_size)
     216                 :            : {
     217                 :   10594185 :   gpointer mem = g_slice_alloc (mem_size);
     218         [ +  - ]:   10594185 :   if (mem)
     219                 :   10594185 :     memset (mem, 0, mem_size);
     220                 :   10594185 :   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                 :      15794 : g_slice_copy (gsize         mem_size,
     243                 :            :               gconstpointer mem_block)
     244                 :            : {
     245                 :      15794 :   gpointer mem = g_slice_alloc (mem_size);
     246         [ +  - ]:      15794 :   if (mem)
     247                 :      15794 :     memcpy (mem, mem_block, mem_size);
     248                 :      15794 :   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`][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                 :   25732990 : g_slice_free1 (gsize    mem_size,
     273                 :            :                gpointer mem_block)
     274                 :            : {
     275   [ +  +  +  + ]:   25732990 :   if (G_UNLIKELY (g_mem_gc_friendly && mem_block))
     276                 :   25718183 :     memset (mem_block, 0, mem_size);
     277                 :   25732990 :   g_free_sized (mem_block, mem_size);
     278                 :   25732990 :   TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
     279                 :   25732990 : }
     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                 :   10728622 : g_slice_free_chain_with_offset (gsize    mem_size,
     305                 :            :                                 gpointer mem_chain,
     306                 :            :                                 gsize    next_offset)
     307                 :            : {
     308                 :   10728622 :   gpointer slice = mem_chain;
     309         [ +  + ]:   22525441 :   while (slice)
     310                 :            :     {
     311                 :   11796819 :       guint8 *current = slice;
     312                 :   11796819 :       slice = *(gpointer *) (current + next_offset);
     313         [ +  + ]:   11796819 :       if (G_UNLIKELY (g_mem_gc_friendly))
     314                 :   11792851 :         memset (current, 0, mem_size);
     315                 :   11796819 :       g_free_sized (current, mem_size);
     316                 :            :     }
     317                 :   10728622 : }
     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 */

Generated by: LCOV version 1.14