diff options
author | talha <talha@talhaamir.xyz> | 2023-08-30 22:58:18 +0500 |
---|---|---|
committer | talha <talha@talhaamir.xyz> | 2023-08-30 22:58:18 +0500 |
commit | 66e84eabf70a11d91abbbe8777b1746573a51bae (patch) | |
tree | 3cca9403bde6a97889353b439ec84af5c661d988 /code/amr_memory.c | |
parent | d980dcd2b66e4879989ce18291d044d5a4ffc902 (diff) |
Refactored files:
- moved memory arenas to memory files
- replaced r32 and r64 with f32 and f64
- prefixing internal libs with amr_
Diffstat (limited to 'code/amr_memory.c')
-rw-r--r-- | code/amr_memory.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/code/amr_memory.c b/code/amr_memory.c new file mode 100644 index 0000000..f92f14a --- /dev/null +++ b/code/amr_memory.c @@ -0,0 +1,113 @@ +#include "amr_memory.h" + +bool amr_IsPowerOfTwo(uintptr_t x) +{ + return (x & (x-1)) == 0; +} + +uintptr_t amr_AlignForward(uintptr_t ptr, size_t align) +{ + uintptr_t p, a, modulo; + + assert(amr_IsPowerOfTwo(align)); + + p = ptr; + a = (uintptr_t)align; + modulo = p & (a-1); + + if (modulo != 0) + { + p += a - modulo; + } + return p; +} + +void *amr_ArenaAllocAlign(amr_DebugArena *Alloc, size_t Size, size_t Align) +{ + uintptr_t CurrOffset = (uintptr_t)Alloc->Buffer + (uintptr_t)Alloc->CurrOffset; + uintptr_t AlignedOffset = amr_AlignForward(CurrOffset, Align); + AlignedOffset -= (uintptr_t)(Alloc->Buffer); + + if (AlignedOffset + Size < Alloc->Size) + { + void *Ptr = &Alloc->Buffer[AlignedOffset]; + Alloc->PrevOffset = AlignedOffset; + Alloc->CurrOffset = AlignedOffset + Size; + + PlatformZeroMemory(Ptr, Size); + return Ptr; + } + return NULL; +} + +void amr_ArenaInit(amr_DebugArena *Alloc, void* BackingBuffer, size_t Size) +{ + Alloc->Buffer = (u8 *)BackingBuffer; + Alloc->Size = Size; + Alloc->CurrOffset = 0; + Alloc->PrevOffset = 0; +} + +void *amr_ArenaAlloc(amr_DebugArena *Alloc, size_t Size) +{ + return amr_ArenaAllocAlign(Alloc, Size, DEFAULT_ALIGNMENT); +} + +void amr_ArenaFree(amr_DebugArena *Alloc, void *Ptr) +{ + // @note: Arenas do not support freeing memory + // this is here to let me know I have not forgotten to implement it + return; +} + +void *amr_ArenaResizeAlign(amr_DebugArena *Alloc, void *OldMem, size_t OldSize, + size_t NewSize, size_t Align) +{ + assert(amr_IsPowerOfTwo(Align)); + if (OldMem == NULL || OldSize == 0) + { + return amr_ArenaAllocAlign(Alloc, NewSize, Align); + } + else if (Alloc->Buffer < OldMem && OldMem < Alloc->Buffer + Alloc->Size) + { + // check if old_memory falls on prev_offset + if (Alloc->Buffer + Alloc->PrevOffset == OldMem) + { + // re-use prev_offset and resize from there + size_t _CurrOffset = Alloc->CurrOffset; + Alloc->CurrOffset = Alloc->PrevOffset + NewSize; + if (NewSize > OldSize) + { + PlatformZeroMemory(&Alloc->Buffer[_CurrOffset], NewSize - OldSize); + } + return OldMem; + } + else + { + // generate new memory + // will have some fragmentation + void *NewMem = amr_ArenaAllocAlign(Alloc, NewSize, Align); + size_t CopySize = OldSize < NewSize ? OldSize : NewSize; + + // copy old memory to new memory location + PlatformCopyMemory(NewMem, OldMem, CopySize); + return NewMem; + } + } + else + { + assert(0 && "Memory is out of bounds of the buffer in this arena"); + return NULL; + } +} + +void *amr_ArenaResize(amr_DebugArena *Alloc, void *OldMem, size_t OldSize, size_t NewSize) +{ + return amr_ArenaResizeAlign(Alloc, OldMem, OldSize, NewSize, DEFAULT_ALIGNMENT); +} + +void amr_ArenaFreeAll(amr_DebugArena *Alloc) +{ + Alloc->CurrOffset = 0; + Alloc->PrevOffset = 0; +} |