Examples
Arena allocation
#include <xo/alloc2/arena/DArena.hpp>
using namespace xo::mm;
using namespace std;
Create an arena:
// create arena, size 64k
DArena arena = DArena::map(ArenaConfig { .size_ = 64*1024; });
cout << arena.lo() << ".." << arena.hi();
This determines a VM memory address range. Actually address range is rounded up to a whole number of VM pages. Size here is a hard maximum. It cannot be changed for this arena instance.
arena.reserved(); // 64k
arena.committed(); // 0k
arena.allocated(); // ok
arena.available(); // 0k
Although we know the address range for arena, it doesn’t own any physical memory yet. Two ways to commit memory:
Attempt allocation:
std::byte * mem = arena.alloc(5*1024); if (!mem) throw std::runtime_error("alloc failed"); arena.reserved(); // 64k arena.committed(); // 8k - 2 pages arena.allocateed(); // 5k arena.available(); // 3k
Expand committed memory explicitly:
bool ok = arena.expand(5*1024); assert(ok); arena.reserved(); // 64k arena.committed(); // 8k - 2 pages arena.allocated(); // 0k arena.available(); // 8k
Examining alloc metadata
Given a successful allocation:
std::size_t req_z = 5*1024;
std::byte * mem = arena.alloc(req_z);
if (!mem)
throw std::runtime_error("alloc failed");
AllocInfo info = arena.alloc_info(mem);
info.payload(); // [mem, mem + req_z (+ up to 7 bytes padding)]
info.is_valid(); // true
info.guard_lo(); // guard bytes preceding alloc
info.guard_hi(); // guard bytes following alloc
Can alternatively scan all live allocs in arena:
for (AllocInfo info : arena) {
info.payload(); // allocated memory range
info.is_valid(); // true
info.guard_lo(); // guard bytes preceding alloc
info.guard_hi(); // guard bytes following alloc
}
Recycling memory
// arena in non-empty state
arena.reserved(); // 64k
arena.committed(); // 8k - 2 pages
arena.allocateed(); // 5k
arena.available(); // 3k
arena.clear();
arena.reserved() // 64k
arena.committed(); // 8k - 2 pages
arena.allocated(); // 0k
arena.available(); // 8k
Memory recycled by DArena::clear()
is available for reuse by application; it’s still owned by arena.
We’re just resetting the free pointer back to the beginning of arena
memory.
To release memory to the operating system, destroy arena:
arena.~DArena(); // or just let arena go out of scope