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; +} | 
