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.
This commit is contained in:
Daan De Meyer
2025-04-18 13:59:06 +02:00
parent 5a124e8ee1
commit edfd847d47
2 changed files with 76 additions and 76 deletions
-76
View File
@@ -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) \
+76
View File
@@ -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; \
})