summaryrefslogtreecommitdiffstats
path: root/src/alloc.h
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-10-29 14:37:19 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-11-02 11:25:10 -0400
commitc90d4af8750bef77ce9abe91df80d5d98ba297d7 (patch)
tree2e3213be7021b2be425954e33b34ea228f0d9f85 /src/alloc.h
parentb00341a45238d383fa27289a53798eef856092bb (diff)
downloadbfs-c90d4af8750bef77ce9abe91df80d5d98ba297d7.tar.xz
alloc: Don't require size % align == 0
Allowing unaligned sizes will allow us to allocate aligned slabs with additional metadata in the tail without ballooning the allocation size for large alignments. Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2244.htm#dr_460 Link: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2072.htm
Diffstat (limited to 'src/alloc.h')
-rw-r--r--src/alloc.h34
1 files changed, 14 insertions, 20 deletions
diff --git a/src/alloc.h b/src/alloc.h
index 4f119e0..7865d5d 100644
--- a/src/alloc.h
+++ b/src/alloc.h
@@ -30,25 +30,24 @@ static inline size_t align_ceil(size_t align, size_t size) {
}
/**
- * Saturating array size.
- *
- * @align
- * Array element alignment.
- * @size
- * Array element size.
- * @count
- * Array element count.
- * @return
- * size * count, saturating to the maximum aligned value on overflow.
+ * Saturating size addition.
*/
-static inline size_t array_size(size_t align, size_t size, size_t count) {
+static inline size_t size_add(size_t lhs, size_t rhs) {
+ size_t ret = lhs + rhs;
+ return ret >= lhs ? ret : (size_t)-1;
+}
+
+/**
+ * Saturating size multiplication.
+ */
+static inline size_t size_mul(size_t size, size_t count) {
size_t ret = size * count;
- return ret / size == count ? ret : ~(align - 1);
+ return ret / size == count ? ret : (size_t)-1;
}
/** Saturating array sizeof. */
#define sizeof_array(type, count) \
- array_size(alignof(type), sizeof(type), count)
+ size_mul(sizeof(type), count)
/** Size of a struct/union field. */
#define sizeof_member(type, member) \
@@ -72,13 +71,8 @@ static inline size_t array_size(size_t align, size_t size, size_t count) {
* to the maximum aligned value on overflow.
*/
static inline size_t flex_size(size_t align, size_t min, size_t offset, size_t size, size_t count) {
- size_t ret = size * count;
- size_t overflow = ret / size != count;
-
- size_t extra = offset + align - 1;
- ret += extra;
- overflow |= ret < extra;
- ret |= -overflow;
+ size_t ret = size_mul(size, count);
+ ret = size_add(ret, offset + align - 1);
ret = align_floor(align, ret);
// Make sure flex_sizeof(type, member, 0) >= sizeof(type), even if the