feat(malloc): first-fit allocator with mmap fallback

This commit is contained in:
2026-09-03 20:44:08 -04:00
parent 06d2ec7c34
commit 5eb3cbe302
3 changed files with 1512 additions and 0 deletions
+112
View File
@@ -0,0 +1,112 @@
#ifndef VLIBC_STDLIB_H
#define VLIBC_STDLIB_H
/*
* vlibc — <stdlib.h>.
*
* This header is the shared home for the stdlib declarations; it currently
* holds only the memory-management family (todo 7). Later todos extend it
* in place: todo 11 adds the numeric conversions (atoi/strtol/strtod/...),
* todo 12 the pseudo-random and search/divide functions
* (rand/srand/qsort/bsearch/abs/div/...), and todo 13 the environment and
* multibyte helpers (getenv/setenv/mblen/mbtowc/...).
*
* Memory management functions, gated by the active compatibility profile
* (see include/vlibc/features.h). Levels are cumulative:
*
* Level 1 (onlyposix): ISO C core + POSIX base — malloc, free, calloc,
* realloc, aligned_alloc, posix_memalign.
* Level 2 (muslmimic): malloc_usable_size (BSD/musl).
*
* This header includes <vlibc/features.h> itself, so the gates below always
* see the configured VLIBC_LEVEL even when the caller included no vlibc
* header first, and <stddef.h> for size_t.
*/
#include <vlibc/features.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Level 1: memory management (always present). */
/*
* Allocate size bytes, 16-byte aligned. The memory is uninitialized.
* malloc(0) returns a unique minimum-size block (never NULL on success).
* NULL + errno ENOMEM on failure.
* malloc: the result does not alias any other pointer and has size bytes.
*/
__attribute__((malloc, alloc_size(1))) void *
malloc(size_t size);
/*
* Release the block at ptr, which must be NULL or a value returned by an
* earlier allocation in this family. free(NULL) is a no-op.
*/
void
free(void *ptr);
/*
* Allocate an array of nmemb elements of size bytes each, all bits zero.
* The product is overflow-checked: on overflow NULL + errno ENOMEM.
* calloc with a zero product returns a unique zeroed minimum-size block.
* malloc: the result does not alias any other pointer and has nmemb*size
* bytes.
*/
__attribute__((malloc, alloc_size(1, 2))) void *
calloc(size_t nmemb, size_t size);
/*
* Resize the block at ptr to size bytes, preserving the first min(old,
* size) bytes. realloc(NULL, size) behaves as malloc(size); realloc(ptr, 0)
* frees ptr and returns NULL. The old block is freed on success and left
* untouched on failure (NULL + errno ENOMEM).
* alloc_size(2): the result has size bytes.
*/
__attribute__((alloc_size(2))) void *
realloc(void *ptr, size_t size);
/*
* Allocate size bytes aligned to alignment. alignment must be a power of
* two that is a multiple of sizeof(void *), and size must be a multiple of
* alignment; a violation fails with NULL + errno EINVAL (a non-power-of-two
* alignment is undefined behavior in C23, so only well-formed arguments
* reach the allocator). size 0 returns NULL. The result is released with
* free.
* malloc + alloc_align(1): the result does not alias any other pointer and
* is aligned to alignment.
*/
__attribute__((malloc, alloc_size(2), alloc_align(1))) void *
aligned_alloc(size_t alignment, size_t size);
/*
* Allocate size bytes at address alignment and store the result in
* *memptr. alignment must be a power of two and a multiple of
* sizeof(void *). Returns 0 on success, EINVAL for a bad alignment, ENOMEM
* on allocation failure. Never sets errno itself, and never modifies
* *memptr on failure. size 0 returns a unique minimum-size block.
*/
__attribute__((access(write_only, 1))) int
posix_memalign(void **memptr, size_t alignment, size_t size);
#if VLIBC_LEVEL_GE(2)
/* Level 2 (muslmimic): BSD/musl extensions. */
/*
* Return the number of bytes actually available in the block at ptr,
* including any internal padding; at least as large as the requested size.
* ptr may be any block returned by the allocator family; NULL returns 0.
* pure: reads memory, no side effects.
*/
__attribute__((pure)) size_t
malloc_usable_size(void *ptr);
#endif /* VLIBC_LEVEL_GE(2) */
#ifdef __cplusplus
}
#endif
#endif /* VLIBC_STDLIB_H */