# NonLocalAllocator

NonLocalAllocator is a heap which manages memory with data structures that are independent of the memory itself. This results in a heap design that is different from a local allocator (in-place linked list heap) like GeneralAllocator and many other conventional heaps.

The requirements for (and thus the resulting design of) NonLocalAllocator are primarily based on suggestions received from teams within EA during the requirements-gathering process. NonLocalAllocator isn't implemented simply the same way as GeneralAllocator except being for non-local memory. These differences are driven by the common intended uses for the allocators. For example, GeneralAllocator implements a small-block cache and delayed coalescing of freed blocks, whereas NonLocalAllocator keeps no such cache and always coalesces all free blocks.

### Features

NonLocalAllocator has many of the features of PPMalloc GeneralAllocator/GeneralAllocatorDebug, though it implements them within a single class instead of two classes. The features are implemented very similarly and often identically to the equivalent features in GeneralAllocator/GeneralAllocatorDebug.

- Allows managing a heap of not just memory but any virtual data source such as disk file space.
- Optional thread safety, identical to GeneralAllocator.
- Ability for the user to add additional (non-local) core memory, as well as extend any existing core memory in place.
- Provides the following allocation functions:
  - Malloc(size_t nSize, int nAllocationFlags = 0)
  - MallocAligned(size_t nSize, size_t nAlignment, size_t nAlignmentOffset = 0, int nAllocationFlags = 0)
  - MallocMultiple(size_t count, const size_t* pSizeArray, const size_t* pAlignmentArray,
    const size_t* pAlignmentOffsetArray, void* pResultArray[], int nAllocationFlags = 0)
  - Realloc(void* p, size_t nNewSize, int nAllocationFlags = 0)
  - ReallocAligned(void* p, size_t nNewSize, size_t nAlignment, size_t nAlignmentOffset = 0,
    int nAllocationFlags = 0)
  - Free(void* p, size_t size = 0)
- Allocation flags: Perm, BestFit, Contig.
- Allocation hooks, identical to GeneralAllocator.
- Provides the following utility/debug functionality in all builds:
  - ValidateAddress(void* p)
  - ValidateHeap()
  - SetAutoHeapValidation(HeapValidationLevel heapValidationLevel, size_t nFrequency)
  - GetUsableSize(void* p)
  - GetLargestFreeBlock()
  - DescribeData(const void* pData, char* pBuffer, size_t nBufferLength)
- Provides the following debug functionality in debug builds:
  - Guard fills / free fills (if debug writing to the non-local heap is enabled)
  - Same debug info tracking options as GeneralAllocatorDebug:
    - Callstack
    - File/line
    - Group id
    - Time
    - Count
    - User size
    - Overhead
    - Checksum
    - Flags
  - Leak detection
  - Pointer validation / double free detection.
- Has heap reporting functionality similar to GeneralAllocator:
  - ReportBegin(), ReportNext(), ReportEnd()
  - ReportHeap
    TraceAllocatedMemory()
- Metrics tracking, same as GeneralAllocatorDebug.
- Assertion failure functionality, same as GeneralAllocator.

### Future Features

A few features that are currently missing but can be added if there is interest include:

- User-driven (possibly async) realloc. This would, for example, allow you to pack video memory between frames somewhat like a handle-based heap but without needing to use handles.
- Delayed frees. These are present in GeneralAllocatorDebug but are currently omitted in NonLocalAllocator.

### Example Usage

The following demonstrates a minimum usage of NonLocalAllocator.

> void* AllocFunction(NonLocalAllocator*, size_t nSize, void*)
> {
> return pGeneralAllocator->Malloc(nSize);
> }
> size_t FreeFunction(NonLocalAllocator*, void* p, size_t nSize, void*)
> {
> pGeneralAllocator->Free(p);
> }
> NonLocalAllocator nla(AllocFunction, FreeFunction, NULL, pNonLocalMemory, nonLocalMemorySize);
> void* p = nla.Malloc(1700);
> nla.Free(p);