diff options
author | Thomas Haller <thaller@redhat.com> | 2020-07-05 10:19:52 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-07-06 14:11:22 +0200 |
commit | 220825836a8e9d03e4b934aeaff31215ac4abffa (patch) | |
tree | 7b794e1d3f81e9b70fa47b8ae1b10b19e4beffec /shared | |
parent | 19613016e23fc891fb4d993e5d75a919a3b8a179 (diff) | |
download | NetworkManager-220825836a8e9d03e4b934aeaff31215ac4abffa.tar.gz |
shared: move nm_utils_get_next_realloc_size() to nm-std-aux
Diffstat (limited to 'shared')
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.c | 69 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-shared-utils.h | 26 | ||||
-rw-r--r-- | shared/nm-std-aux/nm-std-utils.c | 70 | ||||
-rw-r--r-- | shared/nm-std-aux/nm-std-utils.h | 30 |
4 files changed, 100 insertions, 95 deletions
diff --git a/shared/nm-glib-aux/nm-shared-utils.c b/shared/nm-glib-aux/nm-shared-utils.c index 120b8bea08..e952a0ce22 100644 --- a/shared/nm-glib-aux/nm-shared-utils.c +++ b/shared/nm-glib-aux/nm-shared-utils.c @@ -97,75 +97,6 @@ G_STATIC_ASSERT (ETH_ALEN == 6); /*****************************************************************************/ -gsize -nm_utils_get_next_realloc_size (gboolean true_realloc, gsize requested) -{ - gsize n, x; - - /* https://doc.qt.io/qt-5/containers.html#growth-strategies */ - - if (requested <= 40) { - /* small allocations. Increase in small steps of 8 bytes. - * - * We get thus sizes of 8, 16, 32, 40. */ - if (requested <= 8) - return 8; - if (requested <= 16) - return 16; - if (requested <= 32) - return 32; - - /* The return values for < 104 are essentially hard-coded, and the choice here is - * made without very strong reasons. - * - * We want to stay 24 bytes below the power-of-two border 64. Hence, return 40 here. - * However, the next step then is already 104 (128 - 24). It's a larger gap than in - * the steps before. - * - * It's not clear whether some of the steps should be adjusted (or how exactly). */ - return 40; - } - - if ( requested <= 0x2000u - 24u - || G_UNLIKELY (!true_realloc)) { - /* mid sized allocations. Return next power of two, minus 24 bytes extra space - * at the beginning. - * That means, we double the size as we grow. - * - * With !true_realloc, it means that the caller does not intend to call - * realloc() but instead clone the buffer. This is for example the case, when we - * want to nm_explicit_bzero() the old buffer. In that case we really want to grow - * the buffer exponentially every time and not increment in page sizes of 4K (below). - * - * We get thus sizes of 104, 232, 488, 1000, 2024, 4072, 8168... */ - - if (G_UNLIKELY (requested > G_MAXSIZE / 2u - 24u)) - return G_MAXSIZE; - - x = requested + 24u; - n = 128u; - while (n < x) { - n <<= 1; - nm_assert (n > 128u); - } - - nm_assert (n > 24u && n - 24u >= requested); - return n - 24u; - } - - if (G_UNLIKELY (requested > G_MAXSIZE - 0x1000u - 24u)) - return G_MAXSIZE; - - /* For large allocations (with !true_realloc) we allocate memory in chunks of - * 4K (- 24 bytes extra), assuming that the memory gets mmapped and thus - * realloc() is efficient by just reordering pages. */ - n = ((requested + (0x0FFFu + 24u)) & ~((gsize) 0x0FFFu)) - 24u; - nm_assert (n >= requested); - return n; -} - -/*****************************************************************************/ - pid_t nm_utils_gettid (void) { diff --git a/shared/nm-glib-aux/nm-shared-utils.h b/shared/nm-glib-aux/nm-shared-utils.h index 142190ae4b..415111cc6c 100644 --- a/shared/nm-glib-aux/nm-shared-utils.h +++ b/shared/nm-glib-aux/nm-shared-utils.h @@ -1993,32 +1993,6 @@ void nm_indirect_g_free (gpointer arg); /*****************************************************************************/ -/* nm_utils_get_next_realloc_size() is used to grow buffers exponentially, when - * the final size is unknown. As such, it has borders for which it allocates - * certain buffer sizes. - * - * The use of these defines is to get favorable allocation sequences. - * For example, nm_str_buf_init() asks for an initial allocation size. Note that - * it reserves the exactly requested amount, under the assumption that the - * user may know how many bytes will be required. However, often the caller - * doesn't know in advance, and NMStrBuf grows exponentially by calling - * nm_utils_get_next_realloc_size(). - * Imagine you call nm_str_buf_init() with an initial buffer size 100, and you - * add one character at a time. Then the first reallocation will increase the - * buffer size only from 100 to 104. - * If you however start with an initial buffer size of 104, then the next reallocation - * via nm_utils_get_next_realloc_size() gives you 232, and so on. By using - * these sizes, it results in one less allocation, if you anyway don't know the - * exact size in advance. */ -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((gsize) 32) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((gsize) 40) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((gsize) 104) -#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((gsize) 1000) - -gsize nm_utils_get_next_realloc_size (gboolean true_realloc, gsize requested); - -/*****************************************************************************/ - typedef enum { NMU_IFACE_ANY, NMU_IFACE_KERNEL, diff --git a/shared/nm-std-aux/nm-std-utils.c b/shared/nm-std-aux/nm-std-utils.c index 8175ee2c56..f6c2bc43ff 100644 --- a/shared/nm-std-aux/nm-std-utils.c +++ b/shared/nm-std-aux/nm-std-utils.c @@ -4,3 +4,73 @@ #include "nm-std-utils.h" +#include <stdint.h> + +/*****************************************************************************/ + +size_t +nm_utils_get_next_realloc_size (bool true_realloc, size_t requested) +{ + size_t n, x; + + /* https://doc.qt.io/qt-5/containers.html#growth-strategies */ + + if (requested <= 40) { + /* small allocations. Increase in small steps of 8 bytes. + * + * We get thus sizes of 8, 16, 32, 40. */ + if (requested <= 8) + return 8; + if (requested <= 16) + return 16; + if (requested <= 32) + return 32; + + /* The return values for < 104 are essentially hard-coded, and the choice here is + * made without very strong reasons. + * + * We want to stay 24 bytes below the power-of-two border 64. Hence, return 40 here. + * However, the next step then is already 104 (128 - 24). It's a larger gap than in + * the steps before. + * + * It's not clear whether some of the steps should be adjusted (or how exactly). */ + return 40; + } + + if ( requested <= 0x2000u - 24u + || NM_UNLIKELY (!true_realloc)) { + /* mid sized allocations. Return next power of two, minus 24 bytes extra space + * at the beginning. + * That means, we double the size as we grow. + * + * With !true_realloc, it means that the caller does not intend to call + * realloc() but instead clone the buffer. This is for example the case, when we + * want to nm_explicit_bzero() the old buffer. In that case we really want to grow + * the buffer exponentially every time and not increment in page sizes of 4K (below). + * + * We get thus sizes of 104, 232, 488, 1000, 2024, 4072, 8168... */ + + if (NM_UNLIKELY (requested > SIZE_MAX / 2u - 24u)) + return SIZE_MAX; + + x = requested + 24u; + n = 128u; + while (n < x) { + n <<= 1; + nm_assert (n > 128u); + } + + nm_assert (n > 24u && n - 24u >= requested); + return n - 24u; + } + + if (NM_UNLIKELY (requested > SIZE_MAX - 0x1000u - 24u)) + return SIZE_MAX; + + /* For large allocations (with !true_realloc) we allocate memory in chunks of + * 4K (- 24 bytes extra), assuming that the memory gets mmapped and thus + * realloc() is efficient by just reordering pages. */ + n = ((requested + (0x0FFFu + 24u)) & ~((size_t) 0x0FFFu)) - 24u; + nm_assert (n >= requested); + return n; +} diff --git a/shared/nm-std-aux/nm-std-utils.h b/shared/nm-std-aux/nm-std-utils.h index 4afdde6468..0945c8600f 100644 --- a/shared/nm-std-aux/nm-std-utils.h +++ b/shared/nm-std-aux/nm-std-utils.h @@ -3,4 +3,34 @@ #ifndef __NM_STD_UTILS_H__ #define __NM_STD_UTILS_H__ +#include <stdbool.h> + +#include "nm-std-aux.h" + +/*****************************************************************************/ + +/* nm_utils_get_next_realloc_size() is used to grow buffers exponentially, when + * the final size is unknown. As such, it has borders for which it allocates + * certain buffer sizes. + * + * The use of these defines is to get favorable allocation sequences. + * For example, nm_str_buf_init() asks for an initial allocation size. Note that + * it reserves the exactly requested amount, under the assumption that the + * user may know how many bytes will be required. However, often the caller + * doesn't know in advance, and NMStrBuf grows exponentially by calling + * nm_utils_get_next_realloc_size(). + * Imagine you call nm_str_buf_init() with an initial buffer size 100, and you + * add one character at a time. Then the first reallocation will increase the + * buffer size only from 100 to 104. + * If you however start with an initial buffer size of 104, then the next reallocation + * via nm_utils_get_next_realloc_size() gives you 232, and so on. By using + * these sizes, it results in one less allocation, if you anyway don't know the + * exact size in advance. */ +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_32 ((size_t) 32) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_40 ((size_t) 40) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_104 ((size_t) 104) +#define NM_UTILS_GET_NEXT_REALLOC_SIZE_1000 ((size_t) 1000) + +size_t nm_utils_get_next_realloc_size (bool true_realloc, size_t requested); + #endif /* __NM_STD_UTILS_H__ */ |