summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-06-23 13:03:02 -0400
committerAndrew Opalach <andrew@akon.city> 2025-06-23 13:03:02 -0400
commit923ff358ee9f4d37b70a224a49c8a4d6492989d1 (patch)
tree78c315f86227d7ecc3acd613bdeeb886b539da1a
parent93f664a69a3c688d196bdc228d572b45a65e7991 (diff)
downloadlibalabaster-923ff358ee9f4d37b70a224a49c8a4d6492989d1.tar.gz
libalabaster-923ff358ee9f4d37b70a224a49c8a4d6492989d1.tar.bz2
libalabaster-923ff358ee9f4d37b70a224a49c8a4d6492989d1.zip
lib: Inline checking for NULL ptr in realloc
Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--include/al/array_typed.h2
-rw-r--r--include/al/lib.h10
-rw-r--r--include/al/str.h2
-rw-r--r--include/al/wstr.h2
-rw-r--r--src/array.c2
-rw-r--r--src/lib.c36
6 files changed, 33 insertions, 21 deletions
diff --git a/include/al/array_typed.h b/include/al/array_typed.h
index 2092160..e4a6c53 100644
--- a/include/al/array_typed.h
+++ b/include/al/array_typed.h
@@ -84,7 +84,7 @@
} \
static inline void _al_array_reserve_internal(N, __VA_ARGS__)(array(N, __VA_ARGS__) *array, u32 size) \
{ \
- array->alloc = al_growing_allocation((void **)&array->data, array->alloc, size, al_malloc, al_realloc); \
+ array->alloc = al_growing_allocation((void **)&array->data, array->alloc, size, al_realloc); \
} \
static inline void al_array_free(N, __VA_ARGS__)(array(N, __VA_ARGS__) *array) \
{ \
diff --git a/include/al/lib.h b/include/al/lib.h
index e661572..3d6556b 100644
--- a/include/al/lib.h
+++ b/include/al/lib.h
@@ -18,6 +18,7 @@
typedef char type##__size_test[(!!(sizeof(type) == size)) * 2 - 1]
#define AL_USE_STDLIB
+//#define AL_PARANOID_REALLOC
//#define AL_MEMORY_TRACKING
//#define AL_FORCE_DISABLE_OUTPUT
@@ -61,12 +62,16 @@ void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, siz
s32 (*posix_memalign_func)(void **, size_t, size_t),
#endif
void (*free_func)(void *), void (*lock_func)(void), void (*unlock_func)(void));
-void al_malloc_stats(size_t *current, size_t *peak, size_t *total);
+void al_malloc_stats(size_t *current, size_t *peak, size_t *total, size_t *ops);
#else
#ifdef AL_USE_STDLIB
#define al_malloc malloc
#define al_calloc calloc
+#ifdef AL_PARANOID_REALLOC
+static inline void *al_realloc(void *ptr, size_t n) { return ptr ? realloc(ptr, n) : malloc(n); }
+#else
#define al_realloc realloc
+#endif
#ifdef AL_HAVE_POSIX_MEMALIGN
#define al_posix_memalign posix_memalign
#endif
@@ -246,8 +251,7 @@ static inline u16 al_u16_add_wrap(u16 v, u16 add, u16 max)
// Once a growing allocation expands past this number, only grow in multiples of it.
extern u32 al_grow_step;
-u32 al_growing_allocation(void **ptr, u32 prev_size, u32 size,
- void *(*malloc_func)(size_t), void *(*realloc_func)(void *, size_t));
+u32 al_growing_allocation(void **ptr, u32 prev_size, u32 size, void *(*realloc_func)(void *, size_t));
// Defaults to 4KB.
extern size_t al_page_size;
diff --git a/include/al/str.h b/include/al/str.h
index 2055301..93b4f4a 100644
--- a/include/al/str.h
+++ b/include/al/str.h
@@ -39,7 +39,7 @@ static inline void al_str_free(str *s)
static inline u32 al_str_reserve(str *s, u32 size)
{
- return al_growing_allocation((void **)&s->data, s->alloc, size, al_malloc, al_realloc);
+ return al_growing_allocation((void **)&s->data, s->alloc, size, al_realloc);
}
static inline void al_str_sized(str *s, u32 size)
diff --git a/include/al/wstr.h b/include/al/wstr.h
index 47dac45..c80eac2 100644
--- a/include/al/wstr.h
+++ b/include/al/wstr.h
@@ -49,7 +49,7 @@ static inline void al_wstr_free(wstr *w)
static inline u32 al_wstr_reserve(wstr *w, u32 size)
{
- return al_growing_allocation((void **)&w->data, w->alloc, size, al_malloc, al_realloc);
+ return al_growing_allocation((void **)&w->data, w->alloc, size, al_realloc);
}
static inline void al_wstr_sized(wstr *w, u32 size)
diff --git a/src/array.c b/src/array.c
index 37ae7b4..c94994b 100644
--- a/src/array.c
+++ b/src/array.c
@@ -141,5 +141,5 @@
static inline u32 _al_array_reserve(void **ptr, u32 prev_size, u32 size)
{
- return al_growing_allocation(ptr, prev_size, size, AL_ARRAY_MALLOC, AL_ARRAY_REALLOC);
+ return al_growing_allocation(ptr, prev_size, size, AL_ARRAY_REALLOC);
}
diff --git a/src/lib.c b/src/lib.c
index 96a43fe..05ce28b 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -40,6 +40,7 @@ static array(struct al_alloc_t) allocations;
static size_t current_alloc = 0;
static size_t peak_alloc = 0;
static size_t total_alloc = 0;
+static size_t alloc_operations = 0;
#define total_changed_by(n) \
total_alloc += (n); \
@@ -48,7 +49,8 @@ static size_t total_alloc = 0;
current_alloc += (n); \
if (current_alloc > peak_alloc) { \
peak_alloc = current_alloc; \
- }
+ } \
+ alloc_operations++;
void al_malloc_init(void)
{
@@ -76,11 +78,11 @@ void *al_calloc(size_t n, size_t size)
{
al_printf("**al_calloc(%zu, %zu)\n", n, size);
void *ptr = _al_calloc(n, size);
- size_t real_size = n * size;
+ size_t total_size = n * size;
_al_malloc_lock();
- total_changed_by(real_size);
- current_changed_by(real_size);
- al_array_push(allocations, ((struct al_alloc_t){ ptr, real_size }));
+ total_changed_by(total_size);
+ current_changed_by(total_size);
+ al_array_push(allocations, ((struct al_alloc_t){ ptr, total_size }));
_al_malloc_unlock();
return ptr;
}
@@ -88,15 +90,20 @@ void *al_calloc(size_t n, size_t size)
void *al_realloc(void *ptr, size_t n)
{
al_printf("**al_realloc(%p, %zu)\n", ptr, n);
+#ifdef AL_PARANOID_REALLOC
+ void *new_ptr = ptr ? _al_realloc(ptr, n) : _al_malloc(n);
+#else
void *new_ptr = _al_realloc(ptr, n);
+#endif
_al_malloc_lock();
total_changed_by(n);
if (!ptr) {
current_changed_by(n);
- al_array_push(allocations, ((struct al_alloc_t){ ptr, n }));
+ al_array_push(allocations, ((struct al_alloc_t){ new_ptr, n }));
} else {
struct al_alloc_t *alloc;
al_array_foreach_ptr(allocations, i, alloc) {
+ al_assert(alloc->ptr);
if (alloc->ptr == ptr) {
ptrdiff_t diff = (ptrdiff_t)n - (ptrdiff_t)alloc->size;
current_changed_by(diff);
@@ -118,10 +125,10 @@ void al_free(void *ptr)
struct al_alloc_t *alloc;
al_array_foreach_ptr(allocations, i, alloc) {
if (alloc->ptr == ptr) {
+ al_assert(!found);
current_changed_by(-alloc->size);
al_array_remove_at(allocations, i);
found = true;
- break;
}
}
al_assert(found);
@@ -144,12 +151,13 @@ s32 al_posix_memalign(void **ptr, size_t alignment, size_t n)
}
#endif
-void al_malloc_stats(size_t *current, size_t *peak, size_t *total)
+void al_malloc_stats(size_t *current, size_t *peak, size_t *total, size_t *ops)
{
_al_malloc_lock();
*current = current_alloc;
*peak = peak_alloc;
*total = total_alloc;
+ *ops = alloc_operations;
_al_malloc_unlock();
}
@@ -172,15 +180,15 @@ void al_set_alloc(void *(*malloc_func)(size_t), void *(*calloc_func)(size_t, siz
}
#endif
-u32 al_grow_step = 0x3fff; // 0b11111111111111
-
-u32 al_growing_allocation(void **ptr, u32 prev_size, u32 size,
- void *(*malloc_func)(size_t), void *(*realloc_func)(void *, size_t))
+u32 al_grow_step = 0xfff; // 0b111111111111, 4095
+//u32 al_grow_step = 0x3fff; // 0b11111111111111, 16383
+u32 al_growing_allocation(void **ptr, u32 prev_size, u32 size, void *(*realloc_func)(void *, size_t))
{
if (size <= prev_size) return prev_size;
al_assert(size > 0);
- if (size < al_grow_step) {
+ if (size <= al_grow_step) {
+ // next_power_of_two(4096) = 4096.
size = al_next_power_of_two(size);
} else {
size = al_u32_add_wrap(size, al_grow_step, MAX_ALLOC_32) & ~al_grow_step;
@@ -188,7 +196,7 @@ u32 al_growing_allocation(void **ptr, u32 prev_size, u32 size,
// size can only be 0 after wrapping around MAX_ALLOC_32 (zero all possible bits).
if (size == 0) size = MAX_ALLOC_32;
- *ptr = (!*ptr) ? malloc_func(size) : realloc_func(*ptr, size);
+ *ptr = realloc_func(*ptr, size);
al_assert(*ptr);
return size;