summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-10-06 16:25:37 +0200
committerThomas Haller <thaller@redhat.com>2022-10-06 17:33:48 +0200
commit06c7bc6a6bbded64b86ddf8775ba10cae96bea12 (patch)
tree734862845cf218a1a6e43aed39f9b75905493694
parent44d99e366b7ca1eedc54e45ca269d5c2c2bc6fed (diff)
downloadNetworkManager-06c7bc6a6bbded64b86ddf8775ba10cae96bea12.tar.gz
glib-aux: add nm_slice_*() API to replace GSlice
glib has for a long time the GSlice API. The *only* reason to have and use it, is the hope that it might perform better. After all, it's API is more limited, as it doesn't support realloc() and requires the caller to provide the memory size during free. It's hard to accurately benchmark whether an allocator clearly performs better, as it depends on usage and the system allocator that we compare against. But there are some doubts whether it's faster ([1]), and it might be even slower which totally defeats the purpose of having this. Also, there is an long open bug to deprecate the GSlice API ([2]). Move forward an redirect GSlice to the system allocator. Don't completely the call patter however. For one, that would require manual changes (or a good script). But more importantly, we already use the GSlice API, and at the places where we do, we acknowledge to use a more limited behavior (no realloc()) and we know the deallocation size. Replacing all GSlice uses right away with malloc()/free() uses that information and there is no easy way back. But the more limited API *might* have performance benefits in the future. For example, C++ has sized allocation for this reason ([3]). So don't drop a slice API entirely. Instead, add our own nm_slice*() for now, which redirects to g_malloc()/g_free(). [1] https://wiki.gnome.org/Projects/GLib/GSlicePeformanceTests [2] https://gitlab.gnome.org/GNOME/glib/-/issues/ ## 1079 [3] https://open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.c10
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.h43
2 files changed, 53 insertions, 0 deletions
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c
index 58c424fd34..7f5ffd18c3 100644
--- a/src/libnm-glib-aux/nm-shared-utils.c
+++ b/src/libnm-glib-aux/nm-shared-utils.c
@@ -10,6 +10,7 @@
#include <pwd.h>
#include <arpa/inet.h>
#include <poll.h>
+#include <malloc.h>
#include <fcntl.h>
#include <sys/syscall.h>
#include <net/if.h>
@@ -35,6 +36,15 @@ const void *const _NM_PTRARRAY_EMPTY[1] = {NULL};
/*****************************************************************************/
+void
+_nm_slice_assert_usable_size(gsize mem_size, gpointer mem_block)
+{
+ nm_assert(mem_block);
+ nm_assert(mem_size <= malloc_usable_size(mem_block));
+}
+
+/*****************************************************************************/
+
G_STATIC_ASSERT(ETH_ALEN == sizeof(struct ether_addr));
G_STATIC_ASSERT(ETH_ALEN == 6);
G_STATIC_ASSERT(ETH_ALEN == sizeof(NMEtherAddr));
diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h
index 3383e6d03f..6950c8ecce 100644
--- a/src/libnm-glib-aux/nm-shared-utils.h
+++ b/src/libnm-glib-aux/nm-shared-utils.h
@@ -807,6 +807,49 @@ const char *nm_utils_flags2str(const NMUtilsFlags2StrDesc *descs,
/*****************************************************************************/
+void _nm_slice_assert_usable_size(gsize mem_size, gpointer mem_block);
+
+#if NM_MORE_ASSERTS < 10
+#define _nm_slice_assert_usable_size(mem_size, mem_block) \
+ G_STMT_START \
+ { \
+ _nm_unused const gsize _mem_size2 = (mem_size); \
+ _nm_unused gpointer const _mem_block2 = (mem_block); \
+ } \
+ G_STMT_END
+#endif
+
+#define nm_slice_alloc(mem_size) g_malloc(mem_size)
+#define nm_slice_alloc0(mem_size) g_malloc0(mem_size)
+
+#define nm_slice_free_sized(mem_size, mem_block) \
+ G_STMT_START \
+ { \
+ const gsize _mem_size = (mem_size); \
+ gpointer const _mem_block = (mem_block); \
+ \
+ if (_mem_block) { \
+ _nm_slice_assert_usable_size(_mem_size, _mem_block); \
+ g_free(_mem_block); \
+ } \
+ } \
+ G_STMT_END
+
+#define nm_slice_free_typed(type, mem) \
+ G_STMT_START \
+ { \
+ if (1) \
+ nm_slice_free_sized(sizeof(type), (mem)); \
+ else \
+ (void) ((type *) 0 == (mem)); \
+ } \
+ G_STMT_END
+
+#define nm_slice_new(type) ((type *) nm_slice_alloc(sizeof(type)))
+#define nm_slice_new0(type) ((type *) nm_slice_alloc0(sizeof(type)))
+
+/*****************************************************************************/
+
#define _nm_g_slice_free_fcn_define(mem_size) \
static inline void _nm_g_slice_free_fcn_##mem_size(gpointer mem_block) \
{ \