feat: overhaul userspace heap and virtual memory
This commit is contained in:
+20
-18
@@ -9,49 +9,51 @@
|
||||
|
||||
.SH DESCRIPTION
|
||||
The userspace heap provides dynamic memory allocation on top of
|
||||
the kernel's page-mapping syscall (SYS_ALLOC). Include the
|
||||
header <montauk/heap.h> to use these functions.
|
||||
anonymous virtual memory. The Montauk C++ API and libc's
|
||||
malloc/free API use the same process-wide allocator.
|
||||
|
||||
.SS malloc
|
||||
Allocates 'size' bytes from the free list. Returns a 16-byte
|
||||
aligned pointer, or nullptr on failure. When the free list is
|
||||
empty, it requests more pages from the kernel via SYS_ALLOC
|
||||
(minimum 16 KiB growth, initial seed of 64 KiB).
|
||||
empty, it reserves more pages from the kernel. Physical pages
|
||||
are committed as they are first touched.
|
||||
|
||||
char* buf = (char*)montauk::malloc(1024);
|
||||
|
||||
.SS mfree
|
||||
Returns the block to the userspace free list. No syscall is
|
||||
made -- the memory stays mapped and is immediately reusable.
|
||||
Returns the block to the userspace allocator. Arena blocks are
|
||||
immediately reusable; large direct mappings are returned to the
|
||||
kernel, including their virtual address range.
|
||||
Passing nullptr is a safe no-op.
|
||||
|
||||
montauk::mfree(buf);
|
||||
|
||||
.SS realloc
|
||||
Resizes the allocation to 'size' bytes. Allocates a new block,
|
||||
copies the smaller of old/new sizes, and frees the old block.
|
||||
Resizes the allocation to 'size' bytes. A block with sufficient
|
||||
capacity is retained; otherwise a new block is allocated, the
|
||||
smaller of old/new requested sizes is copied, and the old block
|
||||
is freed. Integer overflow fails without changing the old block.
|
||||
If ptr is nullptr, behaves like malloc.
|
||||
|
||||
buf = (char*)montauk::realloc(buf, 2048);
|
||||
|
||||
.SH IMPLEMENTATION
|
||||
The allocator uses a linked free-list with first-fit search.
|
||||
Blocks larger than needed are split. The allocation header is
|
||||
16 bytes (magic + size). All allocations are 16-byte aligned.
|
||||
The allocator uses segregated size-class bins and a coalescing
|
||||
address-ordered overflow list. Headers retain both requested size
|
||||
and actual block extent. A process-wide lock serializes C and C++
|
||||
allocation calls. All returned pointers are 16-byte aligned.
|
||||
|
||||
The heap grows by requesting pages from the kernel via
|
||||
SYS_ALLOC. These pages are never returned to the kernel (since
|
||||
SYS_FREE is currently a no-op), but mfree makes them available
|
||||
for future malloc calls within the process.
|
||||
Allocations of 256 KiB or more use direct page mappings so they
|
||||
can be released promptly. Smaller allocations use growing arenas.
|
||||
|
||||
.SH LOW-LEVEL PAGE API
|
||||
For large allocations or when direct page control is needed:
|
||||
|
||||
void* montauk::alloc(uint64_t size); // SYS_ALLOC
|
||||
void montauk::free(void* ptr); // SYS_FREE (no-op)
|
||||
void montauk::free(void* ptr); // SYS_FREE
|
||||
|
||||
alloc() maps zeroed pages starting at 0x40000000 and growing
|
||||
upward. Size is rounded up to 4 KiB page boundaries.
|
||||
alloc() reserves zero-filled, read/write, non-executable pages.
|
||||
Size is rounded up to 4 KiB. Freed ranges are reusable.
|
||||
|
||||
.SH SEE ALSO
|
||||
syscalls(2), file(2)
|
||||
|
||||
+16
-1
@@ -185,9 +185,24 @@
|
||||
void* montauk::alloc(uint64_t size);
|
||||
|
||||
.B SYS_FREE (12)
|
||||
Reserved (currently a no-op).
|
||||
Release a complete mapping previously returned by SYS_ALLOC.
|
||||
void montauk::free(void* ptr);
|
||||
|
||||
.B SYS_MMAP_ANON (168)
|
||||
Reserve a zero-filled anonymous mapping with read/write/execute
|
||||
protection flags. Pages are committed on first access. Writable
|
||||
executable mappings are rejected.
|
||||
void* mmap(void*, size_t, int, int, int, long);
|
||||
|
||||
.B SYS_MUNMAP (169)
|
||||
Release a page-aligned range. Partial unmap splits the VM area and
|
||||
makes the virtual range reusable.
|
||||
int munmap(void* addr, size_t length);
|
||||
|
||||
.B SYS_MPROTECT (170)
|
||||
Change read/write/execute permissions on an anonymous mapping.
|
||||
int mprotect(void* addr, size_t length, int prot);
|
||||
|
||||
.B SYS_MEMSTATS (67)
|
||||
Get kernel-wide physical memory usage (total/free/used bytes,
|
||||
page size).
|
||||
|
||||
Reference in New Issue
Block a user