mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-27 12:42:10 +01:00
Merge branch 'free-sized' into 'main'
gmem: Add g_free_sized() and g_aligned_free_sized() See merge request GNOME/glib!3231
This commit is contained in:
commit
95cbff0fd2
@ -1082,6 +1082,7 @@ g_try_realloc_n
|
|||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
g_free
|
g_free
|
||||||
|
g_free_sized
|
||||||
g_clear_pointer
|
g_clear_pointer
|
||||||
g_steal_pointer
|
g_steal_pointer
|
||||||
g_mem_gc_friendly
|
g_mem_gc_friendly
|
||||||
@ -1096,6 +1097,7 @@ g_newa0
|
|||||||
g_aligned_alloc
|
g_aligned_alloc
|
||||||
g_aligned_alloc0
|
g_aligned_alloc0
|
||||||
g_aligned_free
|
g_aligned_free
|
||||||
|
g_aligned_free_sized
|
||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
g_memmove
|
g_memmove
|
||||||
|
62
glib/gmem.c
62
glib/gmem.c
@ -220,6 +220,9 @@ g_realloc (gpointer mem,
|
|||||||
*
|
*
|
||||||
* Frees the memory pointed to by @mem.
|
* Frees the memory pointed to by @mem.
|
||||||
*
|
*
|
||||||
|
* If you know the allocated size of @mem, calling g_free_sized() may be faster,
|
||||||
|
* depending on the libc implementation in use.
|
||||||
|
*
|
||||||
* If @mem is %NULL it simply returns, so there is no need to check @mem
|
* If @mem is %NULL it simply returns, so there is no need to check @mem
|
||||||
* against %NULL before calling this function.
|
* against %NULL before calling this function.
|
||||||
*/
|
*/
|
||||||
@ -230,6 +233,33 @@ g_free (gpointer mem)
|
|||||||
TRACE(GLIB_MEM_FREE((void*) mem));
|
TRACE(GLIB_MEM_FREE((void*) mem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_free_sized:
|
||||||
|
* @mem: (nullable): the memory to free
|
||||||
|
* @size: size of @mem, in bytes
|
||||||
|
*
|
||||||
|
* Frees the memory pointed to by @mem, assuming it is has the given @size.
|
||||||
|
*
|
||||||
|
* If @mem is %NULL this is a no-op (and @size is ignored).
|
||||||
|
*
|
||||||
|
* It is an error if @size doesn’t match the size passed when @mem was
|
||||||
|
* allocated. @size is passed to this function to allow optimizations in the
|
||||||
|
* allocator. If you don’t know the allocation size, use g_free() instead.
|
||||||
|
*
|
||||||
|
* Since: 2.76
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_free_sized (void *mem,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_FREE_SIZED
|
||||||
|
free_sized (mem, size);
|
||||||
|
#else
|
||||||
|
free (mem);
|
||||||
|
#endif
|
||||||
|
TRACE (GLIB_MEM_FREE ((void*) mem));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_clear_pointer: (skip)
|
* g_clear_pointer: (skip)
|
||||||
* @pp: (nullable) (not optional) (inout) (transfer full): a pointer to a
|
* @pp: (nullable) (not optional) (inout) (transfer full): a pointer to a
|
||||||
@ -578,7 +608,7 @@ g_mem_profile (void)
|
|||||||
* the program is terminated.
|
* the program is terminated.
|
||||||
*
|
*
|
||||||
* Aligned memory allocations returned by this function can only be
|
* Aligned memory allocations returned by this function can only be
|
||||||
* freed using g_aligned_free().
|
* freed using g_aligned_free_sized() or g_aligned_free().
|
||||||
*
|
*
|
||||||
* Returns: (transfer full): the allocated memory
|
* Returns: (transfer full): the allocated memory
|
||||||
*
|
*
|
||||||
@ -702,3 +732,33 @@ g_aligned_free (gpointer mem)
|
|||||||
{
|
{
|
||||||
aligned_free (mem);
|
aligned_free (mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_aligned_free_sized:
|
||||||
|
* @mem: (nullable): the memory to free
|
||||||
|
* @alignment: alignment of @mem
|
||||||
|
* @size: size of @mem, in bytes
|
||||||
|
*
|
||||||
|
* Frees the memory pointed to by @mem, assuming it is has the given @size and
|
||||||
|
* @alignment.
|
||||||
|
*
|
||||||
|
* If @mem is %NULL this is a no-op (and @size is ignored).
|
||||||
|
*
|
||||||
|
* It is an error if @size doesn’t match the size, or @alignment doesn’t match
|
||||||
|
* the alignment, passed when @mem was allocated. @size and @alignment are
|
||||||
|
* passed to this function to allow optimizations in the allocator. If you
|
||||||
|
* don’t know either of them, use g_aligned_free() instead.
|
||||||
|
*
|
||||||
|
* Since: 2.76
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
g_aligned_free_sized (void *mem,
|
||||||
|
size_t alignment,
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_FREE_ALIGNED_SIZED
|
||||||
|
free_aligned_sized (mem, alignment, size);
|
||||||
|
#else
|
||||||
|
aligned_free (mem);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@ -72,6 +72,9 @@ typedef struct _GMemVTable GMemVTable;
|
|||||||
|
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
void g_free (gpointer mem);
|
void g_free (gpointer mem);
|
||||||
|
GLIB_AVAILABLE_IN_2_76
|
||||||
|
void g_free_sized (gpointer mem,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
GLIB_AVAILABLE_IN_2_34
|
GLIB_AVAILABLE_IN_2_34
|
||||||
void g_clear_pointer (gpointer *pp,
|
void g_clear_pointer (gpointer *pp,
|
||||||
@ -123,6 +126,10 @@ gpointer g_aligned_alloc0 (gsize n_blocks,
|
|||||||
gsize alignment) G_GNUC_WARN_UNUSED_RESULT G_GNUC_ALLOC_SIZE2(1,2);
|
gsize alignment) G_GNUC_WARN_UNUSED_RESULT G_GNUC_ALLOC_SIZE2(1,2);
|
||||||
GLIB_AVAILABLE_IN_2_72
|
GLIB_AVAILABLE_IN_2_72
|
||||||
void g_aligned_free (gpointer mem);
|
void g_aligned_free (gpointer mem);
|
||||||
|
GLIB_AVAILABLE_IN_2_76
|
||||||
|
void g_aligned_free_sized (gpointer mem,
|
||||||
|
size_t alignment,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58
|
#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58
|
||||||
#define g_clear_pointer(pp, destroy) \
|
#define g_clear_pointer(pp, destroy) \
|
||||||
|
@ -38,15 +38,15 @@
|
|||||||
*
|
*
|
||||||
* GSlice was a space-efficient and multi-processing scalable way to allocate
|
* GSlice was a space-efficient and multi-processing scalable way to allocate
|
||||||
* equal sized pieces of memory. Since GLib 2.76, its implementation has been
|
* equal sized pieces of memory. Since GLib 2.76, its implementation has been
|
||||||
* removed and it calls g_malloc() and g_free(), because the performance of the
|
* removed and it calls g_malloc() and g_free_sized(), because the performance
|
||||||
* system-default allocators has improved on all platforms since GSlice was
|
* of the system-default allocators has improved on all platforms since GSlice
|
||||||
* written.
|
* was written.
|
||||||
*
|
*
|
||||||
* The GSlice APIs have not been deprecated, as they are widely in use and doing
|
* The GSlice APIs have not been deprecated, as they are widely in use and doing
|
||||||
* so would be very disruptive for little benefit.
|
* so would be very disruptive for little benefit.
|
||||||
*
|
*
|
||||||
* New code should be written using g_new()/g_malloc() and g_free(). There is no
|
* New code should be written using g_new()/g_malloc() and g_free_sized() or
|
||||||
* particular benefit in porting existing code away from
|
* g_free(). There is no particular benefit in porting existing code away from
|
||||||
* g_slice_new()/g_slice_free() unless it’s being rewritten anyway.
|
* g_slice_new()/g_slice_free() unless it’s being rewritten anyway.
|
||||||
*
|
*
|
||||||
* Here is an example for using the slice allocator:
|
* Here is an example for using the slice allocator:
|
||||||
@ -322,7 +322,8 @@ g_slice_copy (gsize mem_size,
|
|||||||
*
|
*
|
||||||
* If @mem_block is %NULL, this function does nothing.
|
* If @mem_block is %NULL, this function does nothing.
|
||||||
*
|
*
|
||||||
* Since GLib 2.76 this always uses the system free() implementation internally.
|
* Since GLib 2.76 this always uses the system free_sized() implementation
|
||||||
|
* internally.
|
||||||
*
|
*
|
||||||
* Since: 2.10
|
* Since: 2.10
|
||||||
*/
|
*/
|
||||||
@ -332,7 +333,7 @@ g_slice_free1 (gsize mem_size,
|
|||||||
{
|
{
|
||||||
if (G_UNLIKELY (g_mem_gc_friendly))
|
if (G_UNLIKELY (g_mem_gc_friendly))
|
||||||
memset (mem_block, 0, mem_size);
|
memset (mem_block, 0, mem_size);
|
||||||
g_free (mem_block);
|
g_free_sized (mem_block, mem_size);
|
||||||
TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
|
TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,7 +354,8 @@ g_slice_free1 (gsize mem_size,
|
|||||||
*
|
*
|
||||||
* If @mem_chain is %NULL, this function does nothing.
|
* If @mem_chain is %NULL, this function does nothing.
|
||||||
*
|
*
|
||||||
* Since GLib 2.76 this always uses the system free() implementation internally.
|
* Since GLib 2.76 this always uses the system free_sized() implementation
|
||||||
|
* internally.
|
||||||
*
|
*
|
||||||
* Since: 2.10
|
* Since: 2.10
|
||||||
*/
|
*/
|
||||||
@ -369,7 +371,7 @@ g_slice_free_chain_with_offset (gsize mem_size,
|
|||||||
slice = *(gpointer *) (current + next_offset);
|
slice = *(gpointer *) (current + next_offset);
|
||||||
if (G_UNLIKELY (g_mem_gc_friendly))
|
if (G_UNLIKELY (g_mem_gc_friendly))
|
||||||
memset (current, 0, mem_size);
|
memset (current, 0, mem_size);
|
||||||
g_free (current);
|
g_free_sized (current, mem_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,6 +1142,39 @@ test_aligned_mem_zeroed (void)
|
|||||||
g_aligned_free (p);
|
g_aligned_free (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_aligned_mem_free_sized (void)
|
||||||
|
{
|
||||||
|
gsize n_blocks = 10;
|
||||||
|
guint *p;
|
||||||
|
|
||||||
|
g_test_summary ("Check that g_aligned_free_sized() works");
|
||||||
|
|
||||||
|
p = g_aligned_alloc (n_blocks, sizeof (*p), 16);
|
||||||
|
g_assert_nonnull (p);
|
||||||
|
|
||||||
|
g_aligned_free_sized (p, sizeof (*p), n_blocks * 16);
|
||||||
|
|
||||||
|
/* NULL should be ignored */
|
||||||
|
g_aligned_free_sized (NULL, sizeof (*p), n_blocks * 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_free_sized (void)
|
||||||
|
{
|
||||||
|
gpointer p;
|
||||||
|
|
||||||
|
g_test_summary ("Check that g_free_sized() works");
|
||||||
|
|
||||||
|
p = g_malloc (123);
|
||||||
|
g_assert_nonnull (p);
|
||||||
|
|
||||||
|
g_free_sized (p, 123);
|
||||||
|
|
||||||
|
/* NULL should be ignored */
|
||||||
|
g_free_sized (NULL, 123);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_nullify (void)
|
test_nullify (void)
|
||||||
{
|
{
|
||||||
@ -1317,6 +1350,8 @@ main (int argc,
|
|||||||
g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov);
|
g_test_add_func ("/utils/aligned-mem/subprocess/aligned_alloc_nmov", aligned_alloc_nmov);
|
||||||
g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment);
|
g_test_add_func ("/utils/aligned-mem/alignment", test_aligned_mem_alignment);
|
||||||
g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed);
|
g_test_add_func ("/utils/aligned-mem/zeroed", test_aligned_mem_zeroed);
|
||||||
|
g_test_add_func ("/utils/aligned-mem/free-sized", test_aligned_mem_free_sized);
|
||||||
|
g_test_add_func ("/utils/free-sized", test_free_sized);
|
||||||
g_test_add_func ("/utils/nullify", test_nullify);
|
g_test_add_func ("/utils/nullify", test_nullify);
|
||||||
g_test_add_func ("/utils/atexit", test_atexit);
|
g_test_add_func ("/utils/atexit", test_atexit);
|
||||||
g_test_add_func ("/utils/check-setuid", test_check_setuid);
|
g_test_add_func ("/utils/check-setuid", test_check_setuid);
|
||||||
|
@ -614,6 +614,8 @@ functions = [
|
|||||||
'fchmod',
|
'fchmod',
|
||||||
'fchown',
|
'fchown',
|
||||||
'fdwalk',
|
'fdwalk',
|
||||||
|
'free_aligned_sized',
|
||||||
|
'free_sized',
|
||||||
'fsync',
|
'fsync',
|
||||||
'getauxval',
|
'getauxval',
|
||||||
'getc_unlocked',
|
'getc_unlocked',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user