Skip to content
SlabAllocatorInit

SlabAllocatorInit

Description

Initialize a SlabAllocator with the given slot size. Slot size must be a power of two in [16, PAGE_SIZE]; the validator aborts on first allocation otherwise. Default alignment = 16 (MAX_ALIGN) since the minimum slot size is also 16 and every slot is naturally MAX_ALIGN-aligned within its OS page.

slot_size_bytes MUST be side-effect-free – the macro expands it through SLAB_ROUNDUP_POW2 and SLAB_SHIFT_FROM_SIZE, each of which evaluates its argument many times in a ternary cascade. Pass a literal or a const local; do NOT pass expr++ or a function call.

Success

Returns a fully-initialised SlabAllocator value. No OS calls happen at init; the first allocation triggers the first kernel page map.

Failure

Cannot fail at macro-expansion time. A bad slot_size_bytes is caught on first allocation by the validator.

Usage example (Cross-references)

Usage examples (Cross-references)
    
    static bool test_basic_alloc_and_free(void) {
        SlabAllocator slab       = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc_base = ALLOCATOR_OF(&slab);
        Node         *a          = (Node *)AllocatorAlloc(alloc_base, sizeof(Node), true);
    
    static bool test_free_then_alloc_recycles(void) {
        SlabAllocator slab       = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc_base = ALLOCATOR_OF(&slab);
        Node         *a          = (Node *)AllocatorAlloc(alloc_base, sizeof(Node), true);
    
    static bool test_grow_across_chunks(void) {
        SlabAllocator slab       = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc_base = ALLOCATOR_OF(&slab);
        Node         *slots[600];
    
    static bool test_oversized_request_fails(void) {
        SlabAllocator slab       = SlabAllocatorInit(sizeof(int));
        Allocator    *alloc_base = ALLOCATOR_OF(&slab);
        void         *big        = AllocatorAlloc(alloc_base, 4096, true);
    
    static bool test_free_half_then_realloc(void) {
        SlabAllocator slab       = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc_base = ALLOCATOR_OF(&slab);
        Node         *slots[200];
    
    static bool test_reject_foreign_pointer(void) {
        SlabAllocator s1 = SlabAllocatorInit(sizeof(Node));
        SlabAllocator s2 = SlabAllocatorInit(sizeof(Node));
        Allocator    *a1 = ALLOCATOR_OF(&s1);
    static bool test_reject_foreign_pointer(void) {
        SlabAllocator s1 = SlabAllocatorInit(sizeof(Node));
        SlabAllocator s2 = SlabAllocatorInit(sizeof(Node));
        Allocator    *a1 = ALLOCATOR_OF(&s1);
        Allocator    *a2 = ALLOCATOR_OF(&s2);
    
    static bool test_reject_misaligned_pointer(void) {
        SlabAllocator slab  = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc = ALLOCATOR_OF(&slab);
        u8           *p     = (u8 *)AllocatorAlloc(alloc, sizeof(Node), false);
    
    static bool test_reject_double_free(void) {
        SlabAllocator slab  = SlabAllocatorInit(sizeof(Node));
        Allocator    *alloc = ALLOCATOR_OF(&slab);
        Node         *p     = (Node *)AllocatorAlloc(alloc, sizeof(Node), false);
Last updated on