about summary refs log tree commit diff
path: root/shared/systemd/src/basic/macro.h
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2020-05-19 16:38:51 +0200
committerSebastien Bacher <seb128@ubuntu.com>2020-05-19 16:38:51 +0200
commit96642ebde58e1eea692aea6a92d33f45452fa9c0 (patch)
tree106ddfa2180b3997e8965787b5cb122982ebab9d /shared/systemd/src/basic/macro.h
parent8f6881ac06714ef99cc470a03e7ac0ce1af49a16 (diff)
parentd460892bbfece74fb6d3cd846bf6ef548290be41 (diff)
Merge branch 'upstream/latest' of https://salsa.debian.org/utopia-team/network-manager into upstream/latestt pu
Diffstat (limited to 'shared/systemd/src/basic/macro.h')
-rw-r--r--shared/systemd/src/basic/macro.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/shared/systemd/src/basic/macro.h b/shared/systemd/src/basic/macro.h
index fc733366..6cd9c516 100644
--- a/shared/systemd/src/basic/macro.h
+++ b/shared/systemd/src/basic/macro.h
@@ -172,6 +172,11 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
 
 /* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */
 static inline unsigned long ALIGN_POWER2(unsigned long u) {
+
+        /* Avoid subtraction overflow */
+        if (u == 0)
+                return 0;
+
         /* clz(0) is undefined */
         if (u == 1)
                 return 1;
@@ -183,6 +188,29 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
         return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL));
 }
 
+static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
+        size_t m;
+
+        /* Round up allocation sizes a bit to some reasonable, likely larger value. This is supposed to be
+         * used for cases which are likely called in an allocation loop of some form, i.e. that repetitively
+         * grow stuff, for example strv_extend() and suchlike.
+         *
+         * Note the difference to GREEDY_REALLOC() here, as this helper operates on a single size value only,
+         * and rounds up to next multiple of 2, needing no further counter.
+         *
+         * Note the benefits of direct ALIGN_POWER2() usage: type-safety for size_t, sane handling for very
+         * small (i.e. <= 2) and safe handling for very large (i.e. > SSIZE_MAX) values. */
+
+        if (l <= 2)
+                return 2; /* Never allocate less than 2 of something.  */
+
+        m = ALIGN_POWER2(l);
+        if (m == 0) /* overflow? */
+                return l;
+
+        return m;
+}
+
 #ifndef __COVERITY__
 #  define VOID_0 ((void)0)
 #else