src/rmem

Source   Edit  

Example:

import src/rmem
# Example 1: MemPool

var buffer {.align(sizeof(int)).}: array[1024, byte] # variable buffer is aligned
# Create a memory pool with 1024 bytes
var mp = createMemPool(buffer)
# Allocate memory
# Every address is 4*sizeof(int) byte aligned.
let ptr1 = mp.alloc(100)
let ptr2 = mp.alloc(200)
# Check free memory
echo "Free memory: ", mp.getFreeMemory()
# Reallocate
let ptr3 = mp.realloc(ptr1, 150)
# Free memory
mp.free(ptr2)
echo "Free memory after free: ", mp.getFreeMemory()

# Example 2: ObjPool
type
  MyObject = object
    x, y: int
    data: array[20, char]
    used: bool

# Supports destructors
proc `=destroy`(x: MyObject) =
  if x.used:
    echo "destroying object"
proc `=wasMoved`(x: var MyObject) =
  x.used = false

# Create an object pool
var op = createObjPool[MyObject](buffer)
# Allocate MyObject objects
var objects: array[5, ptr MyObject]
for i in 0..4:
  objects[i] = op.alloc()
  objects[i].x = i
  objects[i].y = i * 2
  objects[i].used = true
# Free some objects
op.free(objects[1])
op.free(objects[3])
let newObj = op.alloc() # Reuses a slot, preventing fragmentation
echo "Allocated a new object, x = ", newObj.x # Memory is cleared

# Example 3: BiStack

# Create a BiStack with 1024 bytes
var bs = createBiStack(buffer)
# Choose between front and back allocations based on the lifetimes and
# usage patterns of your data.
let front1 = cast[ptr int](bs.allocFront(sizeof(int)))
let back1 = cast[ptr int](bs.allocBack(sizeof(int)))
front1[] = 10
back1[] = 20
# Check that the back portion doesn't collide with the front
echo "Margins: ", bs.margins()
# A number of 0 or less means that one of the portions has reached the other
# and a reset is necessary.
bs.resetFront()
echo "Margins after front reset: ", bs.margins()
# Reset all
bs.resetAll()

Types

BiStack = object
Source   Edit  
MemPool = object
Source   Edit  
ObjPool[T] = object
Source   Edit  

Procs

proc alignedAllocBack(s: var BiStack; size, align: Natural): pointer {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc alignedAllocFront(s: var BiStack; size, align: Natural): pointer {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc alloc(x: var MemPool; size: Natural): pointer {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc alloc[T](x: var ObjPool[T]): ptr T
Source   Edit  
proc allocBack(s: var BiStack; size: Natural): pointer {.inline, ...raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc allocFront(s: var BiStack; size: Natural): pointer {.inline, ...raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc createBiStack(buffer: openArray[byte]): BiStack {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc createBiStack(buffer: pointer; bufferLen: int): BiStack {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc createMemPool(buffer: openArray[byte]): MemPool {....raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc createMemPool(buffer: pointer; bufferLen: int): MemPool {....raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc createObjPool[T](buffer: openArray[byte]): ObjPool[T]
Source   Edit  
proc createObjPool[T](buffer: pointer; bufferLen: int): ObjPool[T]
Source   Edit  
proc free(x: var MemPool; p: pointer) {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc free[T](x: var ObjPool[T]; p: ptr T)
Source   Edit  
proc getFreeMemory(x: MemPool): int {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc margins(s: BiStack): int {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc realloc(x: var MemPool; p: pointer; newSize: Natural): pointer {.
    ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc resetAll(s: var BiStack) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc resetBack(s: var BiStack) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc resetFront(s: var BiStack) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit