//////////////////////////////////////////////////////////// //~ Buddy types //- Block Struct(BuddyBlock) { b32 is_used; struct BuddyLevel *level; BuddyBlock *parent; BuddyBlock *sibling; /* Links to block in level's unused list or in ctx's free list */ BuddyBlock *prev; BuddyBlock *next; u8 *memory; }; //- Level Struct(BuddyLevel) { struct BuddyCtx *ctx; b32 backed; /* Signals whether this level is backed by memory in the ctx arena */ u32 tier; u64 size; BuddyBlock *first_unused_block; }; //- Ctx Struct(BuddyCtx) { Arena *meta_arena; Arena *data_arena; BuddyLevel *levels; BuddyBlock *first_free_block; }; //////////////////////////////////////////////////////////// //~ Buddy context operations BuddyCtx *AcquireBuddyCtx(u64 reserve); void ReleaseBuddyCtx(BuddyCtx *ctx); //////////////////////////////////////////////////////////// //~ Buddy block operations //- Acquire / release BuddyBlock *AcquireBuddyBlock(BuddyCtx *ctx, u64 size); void ReleaseBuddyBlock(BuddyBlock *block); //- Push / pop BuddyBlock *PushBuddyBlock(BuddyCtx *ctx); void PopBuddyBlock(BuddyCtx *ctx, BuddyLevel *level, BuddyBlock *block); //- Get unused BuddyBlock *GetUnusedBuddyBlock(BuddyCtx *ctx, BuddyLevel *level);