Vixen
02b45cc4
csharp
public sealed class BuddyAllocator

Suballocates offsets within a fixed region by repeatedly halving it. Owns no memory of its own — it hands out Int64 offsets, and what those index into is the caller's business.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

Written for device memory. A Vulkan driver gives out a handful of large heaps and charges for every allocation from them, so the engine takes a few big ones and carves resources out of them itself. Because this deals only in offsets, it has no Vulkan in it and can be tested exhaustively without a GPU — which is the whole reason it lives here rather than in the backend.

Why buddy and not a free list. Merging is the hard part of a general allocator: two adjacent free blocks have to be found and joined, or the heap fragments until a large allocation fails while plenty is free. A buddy allocator makes that lookup arithmetic — a block's partner is its offset with one bit flipped — so a free is O(log n) with no search and no bookkeeping list to walk.

The cost is internal fragmentation: every request rounds up to a power of two, so a 33 KiB resource occupies 64 KiB. That is the trade, it is bounded at under 2×, and it is why the backend sends allocations above a threshold straight to the driver instead.

Fields and properties (5)

  • public long TotalSize

    The size of the region being carved up.

  • public long AllocatedBytes

    How many bytes are handed out, counting the rounding-up.

  • public long FreeBytes

    How many bytes are not handed out.

  • public int AllocationCount

    How many allocations are outstanding.

  • public long LargestFreeBlock

    The largest single allocation that can currently succeed. Below FreeBytes whenever the region is fragmented, and the number worth watching.

Methods (6)

  • public BuddyAllocator(long totalSize, long minimumBlockSize = 256)

    Creates an allocator over a region.

  • public bool TryAllocate(long size, long alignment, out long offset)

    Reserves a range.

  • public bool Free(long offset)

    Releases a range, merging it back with its neighbour wherever it can.

  • public bool IsAllocated(long offset)

    Whether an offset is currently allocated.

  • public bool TryGetSize(long offset, out long size)

    How many bytes an allocation actually reserved, rounding included.

  • public void Reset()

    Releases everything, returning the region to one free block.

Used by (1)

  • MemoryTestsVixen.Core.Memory.Tests