From edfd847d47584f8772d8e818f42f34882e594aaa Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 18 Apr 2025 11:26:43 +0200 Subject: [PATCH] fundamental: Move alignment logic to memory-util-fundamental.h Aligning is closely related to memory management, so let's move these macros and functions to memory-util-fundamental.h. This will allow us to move assertion related logic out of macro-fundamental.h as well in a later commit. --- src/fundamental/macro-fundamental.h | 76 ----------------------- src/fundamental/memory-util-fundamental.h | 76 +++++++++++++++++++++++ 2 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/fundamental/macro-fundamental.h b/src/fundamental/macro-fundamental.h index 06fca4a8e50..ac18326a43a 100644 --- a/src/fundamental/macro-fundamental.h +++ b/src/fundamental/macro-fundamental.h @@ -438,82 +438,6 @@ (typeof(memory)) NULL; \ }) -static inline size_t ALIGN_TO(size_t l, size_t ali) { - assert(ISPOWEROF2(ali)); - - if (l > SIZE_MAX - (ali - 1)) - return SIZE_MAX; /* indicate overflow */ - - return ((l + (ali - 1)) & ~(ali - 1)); -} - -static inline uint64_t ALIGN_TO_U64(uint64_t l, uint64_t ali) { - assert(ISPOWEROF2(ali)); - - if (l > UINT64_MAX - (ali - 1)) - return UINT64_MAX; /* indicate overflow */ - - return ((l + (ali - 1)) & ~(ali - 1)); -} - -static inline size_t ALIGN_DOWN(size_t l, size_t ali) { - assert(ISPOWEROF2(ali)); - - return l & ~(ali - 1); -} - -static inline uint64_t ALIGN_DOWN_U64(uint64_t l, uint64_t ali) { - assert(ISPOWEROF2(ali)); - - return l & ~(ali - 1); -} - -static inline size_t ALIGN_OFFSET(size_t l, size_t ali) { - assert(ISPOWEROF2(ali)); - - return l & (ali - 1); -} - -static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) { - assert(ISPOWEROF2(ali)); - - return l & (ali - 1); -} - -#define ALIGN2(l) ALIGN_TO(l, 2) -#define ALIGN4(l) ALIGN_TO(l, 4) -#define ALIGN8(l) ALIGN_TO(l, 8) -#define ALIGN2_PTR(p) ((void*) ALIGN2((uintptr_t) p)) -#define ALIGN4_PTR(p) ((void*) ALIGN4((uintptr_t) p)) -#define ALIGN8_PTR(p) ((void*) ALIGN8((uintptr_t) p)) -#define ALIGN(l) ALIGN_TO(l, sizeof(void*)) -#define ALIGN_PTR(p) ((void*) ALIGN((uintptr_t) (p))) - -/* Checks if the specified pointer is aligned as appropriate for the specific type */ -#define IS_ALIGNED16(p) (((uintptr_t) p) % alignof(uint16_t) == 0) -#define IS_ALIGNED32(p) (((uintptr_t) p) % alignof(uint32_t) == 0) -#define IS_ALIGNED64(p) (((uintptr_t) p) % alignof(uint64_t) == 0) - -/* Same as ALIGN_TO but callable in constant contexts. */ -#define CONST_ALIGN_TO(l, ali) \ - __builtin_choose_expr( \ - __builtin_constant_p(l) && \ - __builtin_constant_p(ali) && \ - CONST_ISPOWEROF2(ali) && \ - (l <= SIZE_MAX - (ali - 1)), /* overflow? */ \ - ((l) + (ali) - 1) & ~((ali) - 1), \ - VOID_0) - -/* Similar to ((t *) (void *) (p)) to cast a pointer. The macro asserts that the pointer has a suitable - * alignment for type "t". This exists for places where otherwise "-Wcast-align=strict" would issue a - * warning or if you want to assert that the cast gives a pointer of suitable alignment. */ -#define CAST_ALIGN_PTR(t, p) \ - ({ \ - const void *_p = (p); \ - assert(((uintptr_t) _p) % alignof(t) == 0); \ - (t *) _p; \ - }) - #define UPDATE_FLAG(orig, flag, b) \ ((b) ? ((orig) | (flag)) : ((orig) & ~(flag))) #define SET_FLAG(v, flag, b) \ diff --git a/src/fundamental/memory-util-fundamental.h b/src/fundamental/memory-util-fundamental.h index 068f5ee215e..f42d54f97a2 100644 --- a/src/fundamental/memory-util-fundamental.h +++ b/src/fundamental/memory-util-fundamental.h @@ -142,3 +142,79 @@ static inline void array_cleanup(const ArrayCleanup *c) { *p = (empty); \ } \ } + +static inline size_t ALIGN_TO(size_t l, size_t ali) { + assert(ISPOWEROF2(ali)); + + if (l > SIZE_MAX - (ali - 1)) + return SIZE_MAX; /* indicate overflow */ + + return ((l + (ali - 1)) & ~(ali - 1)); +} + +static inline uint64_t ALIGN_TO_U64(uint64_t l, uint64_t ali) { + assert(ISPOWEROF2(ali)); + + if (l > UINT64_MAX - (ali - 1)) + return UINT64_MAX; /* indicate overflow */ + + return ((l + (ali - 1)) & ~(ali - 1)); +} + +static inline size_t ALIGN_DOWN(size_t l, size_t ali) { + assert(ISPOWEROF2(ali)); + + return l & ~(ali - 1); +} + +static inline uint64_t ALIGN_DOWN_U64(uint64_t l, uint64_t ali) { + assert(ISPOWEROF2(ali)); + + return l & ~(ali - 1); +} + +static inline size_t ALIGN_OFFSET(size_t l, size_t ali) { + assert(ISPOWEROF2(ali)); + + return l & (ali - 1); +} + +static inline uint64_t ALIGN_OFFSET_U64(uint64_t l, uint64_t ali) { + assert(ISPOWEROF2(ali)); + + return l & (ali - 1); +} + +#define ALIGN2(l) ALIGN_TO(l, 2) +#define ALIGN4(l) ALIGN_TO(l, 4) +#define ALIGN8(l) ALIGN_TO(l, 8) +#define ALIGN2_PTR(p) ((void*) ALIGN2((uintptr_t) p)) +#define ALIGN4_PTR(p) ((void*) ALIGN4((uintptr_t) p)) +#define ALIGN8_PTR(p) ((void*) ALIGN8((uintptr_t) p)) +#define ALIGN(l) ALIGN_TO(l, sizeof(void*)) +#define ALIGN_PTR(p) ((void*) ALIGN((uintptr_t) (p))) + +/* Checks if the specified pointer is aligned as appropriate for the specific type */ +#define IS_ALIGNED16(p) (((uintptr_t) p) % alignof(uint16_t) == 0) +#define IS_ALIGNED32(p) (((uintptr_t) p) % alignof(uint32_t) == 0) +#define IS_ALIGNED64(p) (((uintptr_t) p) % alignof(uint64_t) == 0) + +/* Same as ALIGN_TO but callable in constant contexts. */ +#define CONST_ALIGN_TO(l, ali) \ + __builtin_choose_expr( \ + __builtin_constant_p(l) && \ + __builtin_constant_p(ali) && \ + CONST_ISPOWEROF2(ali) && \ + (l <= SIZE_MAX - (ali - 1)), /* overflow? */ \ + ((l) + (ali) - 1) & ~((ali) - 1), \ + VOID_0) + +/* Similar to ((t *) (void *) (p)) to cast a pointer. The macro asserts that the pointer has a suitable + * alignment for type "t". This exists for places where otherwise "-Wcast-align=strict" would issue a + * warning or if you want to assert that the cast gives a pointer of suitable alignment. */ +#define CAST_ALIGN_PTR(t, p) \ + ({ \ + const void *_p = (p); \ + assert(((uintptr_t) _p) % alignof(t) == 0); \ + (t *) _p; \ + }) -- 2.47.3