Allocators Testing Added. Pull and Chunk allocators updates.
This commit is contained in:
parent
4a2ab6f5d0
commit
9e5ac1e975
30 changed files with 704 additions and 701 deletions
|
|
@ -1,21 +1,23 @@
|
|||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
static tp::ModuleManifest* sModuleDependencies[] = { &tp::gModuleBase, NULL };
|
||||
tp::ModuleManifest tp::gModuleAllocator = ModuleManifest("Allocators", NULL, NULL, sModuleDependencies);
|
||||
#include <cstdlib>
|
||||
|
||||
static tp::ModuleManifest* sModuleDependencies[] = { &tp::gModuleBase, nullptr };
|
||||
tp::ModuleManifest tp::gModuleAllocators = ModuleManifest("Allocators", nullptr, nullptr, sModuleDependencies);
|
||||
|
||||
|
||||
void* operator new(size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||
void* operator new[](size_t aSize) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||
void operator delete(void* aPtr) { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
void operator delete[](void* aPtr) { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
void operator delete(void* aPtr) noexcept { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
void operator delete[](void* aPtr) noexcept { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
|
||||
void* operator new(size_t aSize, tp::HeapAlloc& aAlloc) { return aAlloc.allocate(aSize); }
|
||||
void* operator new[](size_t aSize, tp::HeapAlloc& aAlloc) { return aAlloc.allocate(aSize); }
|
||||
void operator delete(void* aPtr, tp::HeapAlloc& aAlloc) { aAlloc.deallocate(aPtr); }
|
||||
void operator delete[](void* aPtr, tp::HeapAlloc& aAlloc) { aAlloc.deallocate(aPtr); }
|
||||
|
||||
void* operator new(size_t aSize, tp::HeapAllocGlobal& aAlloc) { return aAlloc.allocate(aSize); }
|
||||
void* operator new[](size_t aSize, tp::HeapAllocGlobal& aAlloc) { return aAlloc.allocate(aSize); }
|
||||
void operator delete(void* aPtr, tp::HeapAllocGlobal& aAlloc) { aAlloc.deallocate(aPtr); }
|
||||
void operator delete[](void* aPtr, tp::HeapAllocGlobal& aAlloc) { aAlloc.deallocate(aPtr); }
|
||||
void* operator new(size_t aSize, tp::HeapAllocGlobal& aAlloc) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||
void* operator new[](size_t aSize, tp::HeapAllocGlobal& aAlloc) { return tp::HeapAllocGlobal::allocate(aSize); }
|
||||
void operator delete(void* aPtr, tp::HeapAllocGlobal& aAlloc) { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
void operator delete[](void* aPtr, tp::HeapAllocGlobal& aAlloc) { tp::HeapAllocGlobal::deallocate(aPtr); }
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Implementation uses embedded one-directional linked list to track free blocks.
|
||||
* The embedded part ensures that there is no memory overhead on block specifically.
|
||||
* Linked list is initialized iteratively on each allocation if it has not been already.
|
||||
|
||||
* Allocating:
|
||||
* 1) updating list entry to stored in the entry itself next free pointer
|
||||
* 2) returning entry before (1).
|
||||
*
|
||||
* Deallocating:
|
||||
* 1) assigning list entry value to the deleted block
|
||||
* 2) updating list entry to that block.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ChunkAllocator.hpp"
|
||||
#include "PrivateConfig.hpp"
|
||||
|
||||
#include "HeapAllocatorGlobal.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
enum : ualni {
|
||||
ALIGNED_SIZE = ENV_ALNI_SIZE_B,
|
||||
WRAP_SIZE_ALN = MEM_WRAP_SIZE,
|
||||
WRAP_SIZE = WRAP_SIZE_ALN * ALIGNED_SIZE,
|
||||
WRAP_VAL = MEM_WRAP_FILL_VAL,
|
||||
CLEAR_ALLOC_VAL = MEM_CLEAR_ON_ALLOC_VAL,
|
||||
CLEAR_DEALLOC_VAL = MEM_CLEAR_ON_DEALLOC_VAL,
|
||||
};
|
||||
|
||||
ChunkAlloc::ChunkAlloc(ualni aBlockSize, void* aMemory, ualni aMemSize) {
|
||||
auto const temp = aBlockSize / ALIGNED_SIZE;
|
||||
mBSize = ((aBlockSize % ALIGNED_SIZE) ? temp + 1 : temp) + WRAP_SIZE_ALN * 2;
|
||||
mBuff = (ualni*) aMemory;
|
||||
mNBlocks = (aMemSize / ALIGNED_SIZE) / mBSize;
|
||||
mNFreeBlocks = mNBlocks;
|
||||
}
|
||||
|
||||
ChunkAlloc::ChunkAlloc(ualni aBlockSize, ualni aNBlocks) {
|
||||
auto const temp = aBlockSize / ALIGNED_SIZE;
|
||||
mBSize = ((aBlockSize % ALIGNED_SIZE) ? temp + 1 : temp) + WRAP_SIZE_ALN * 2;
|
||||
mNBlocks = aNBlocks;
|
||||
mNFreeBlocks = mNBlocks;
|
||||
mBuff = (ualni*)HeapAllocGlobal::allocate(mNBlocks * mBSize * ALIGNED_SIZE);
|
||||
mOwnBuff = true;
|
||||
}
|
||||
|
||||
void* ChunkAlloc::allocate() {
|
||||
ASSERT(mNFreeBlocks && "Out Of Memory");
|
||||
|
||||
// 1) PreInitialize blocks
|
||||
if (mNInitBlocks < mNBlocks) {
|
||||
*(mBuff + mNInitBlocks * mBSize) = (ualni)(mBuff + (mNInitBlocks++) * mBSize);
|
||||
}
|
||||
|
||||
// 2) Find free block and update next free block
|
||||
auto data = mNextBlock;
|
||||
mNextBlock = (ualni*)(*data);
|
||||
mNFreeBlocks--;
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
// 3) Fill Wrap and offset data
|
||||
auto wrap_top = data;
|
||||
data += WRAP_SIZE_ALN;
|
||||
auto wrap_bottom = data + mBSize;
|
||||
|
||||
memsetv(wrap_top, WRAP_SIZE, WRAP_VAL);
|
||||
memsetv(wrap_bottom, WRAP_SIZE, WRAP_VAL);
|
||||
|
||||
// 4) Clear data
|
||||
#ifdef MEM_CLEAR_ON_ALLOC
|
||||
memsetv(data, mBSize * ALIGNED_SIZE, CLEAR_ALLOC_VAL);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void ChunkAlloc::deallocate(void* aPtr) {
|
||||
auto block = (ualni*)aPtr;
|
||||
|
||||
#ifdef MEM_DEBUG
|
||||
// 3) Check Wrap and offset data
|
||||
auto wrap_bottom = block + mBSize;
|
||||
auto wrap_top = block - WRAP_SIZE_ALN;
|
||||
block = wrap_top;
|
||||
|
||||
// 3) Check the wrap
|
||||
RelAssert(memequalv(wrap_top, WRAP_SIZE, WRAP_VAL) && memequalv(wrap_bottom, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!");
|
||||
|
||||
// 4) Clear data
|
||||
#ifdef MEM_CLEAR_ON_ALLOC
|
||||
memsetv(aPtr, mBSize * ALIGNED_SIZE, CLEAR_DEALLOC_VAL);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
(*block) = (ualni)mNextBlock;
|
||||
mNextBlock = block;
|
||||
mNFreeBlocks++;
|
||||
}
|
||||
|
||||
bool ChunkAlloc::isFull() const { return !mNFreeBlocks; }
|
||||
bool ChunkAlloc::isEmpty() const { return mNFreeBlocks == mNBlocks; }
|
||||
|
||||
ChunkAlloc::~ChunkAlloc() {
|
||||
// TODO : check for leaks
|
||||
if (mOwnBuff) {
|
||||
HeapAllocGlobal::deallocate(mBuff);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,6 @@
|
|||
|
||||
#include "PrivateConfig.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace tp;
|
||||
|
||||
#if not defined(MEM_DEBUG)
|
||||
|
|
@ -24,7 +21,7 @@ namespace tp {
|
|||
MemHeadLocal* mPrev;
|
||||
MemHeadLocal* mNext;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void* HeapAlloc::allocate(ualni aBlockSize) {
|
||||
auto head = (MemHeadLocal*) HeapAllocGlobal::allocate(aBlockSize + sizeof(MemHeadLocal));
|
||||
|
|
@ -32,12 +29,11 @@ void* HeapAlloc::allocate(ualni aBlockSize) {
|
|||
|
||||
mNumAllocations++;
|
||||
if (mEntry) {
|
||||
head->mNext = mEntry->mNext;
|
||||
head->mPrev = mEntry->mPrev;
|
||||
if (mEntry->mNext) mEntry->mNext->mPrev = head;
|
||||
if (mEntry->mPrev) mEntry->mPrev->mNext = head;
|
||||
}
|
||||
else {
|
||||
DEBUG_ASSERT(!mEntry->mNext)
|
||||
head->mNext = nullptr;
|
||||
head->mPrev = mEntry;
|
||||
mEntry->mNext = head;
|
||||
} else {
|
||||
head->mNext = nullptr;
|
||||
head->mPrev = nullptr;
|
||||
}
|
||||
|
|
@ -50,15 +46,11 @@ void HeapAlloc::deallocate(void* aPtr) {
|
|||
auto head = ((MemHeadLocal*)(aPtr)) - 1;
|
||||
|
||||
mNumAllocations--;
|
||||
if (mEntry->mNext) mEntry->mNext->mPrev = mEntry->mPrev;
|
||||
if (mEntry->mPrev) mEntry->mPrev->mNext = mEntry->mNext;
|
||||
DEBUG_ASSERT(!mEntry->mNext)
|
||||
if (head->mNext) head->mNext->mPrev = head->mPrev;
|
||||
if (head->mPrev) head->mPrev->mNext = head->mNext;
|
||||
if (head == mEntry) {
|
||||
if (mEntry->mNext) {
|
||||
mEntry = mEntry->mNext;
|
||||
}
|
||||
else {
|
||||
mEntry = mEntry->mPrev;
|
||||
}
|
||||
mEntry = head->mPrev;
|
||||
}
|
||||
|
||||
HeapAllocGlobal::deallocate(head);
|
||||
|
|
@ -66,7 +58,7 @@ void HeapAlloc::deallocate(void* aPtr) {
|
|||
|
||||
HeapAlloc::~HeapAlloc() {
|
||||
if (mNumAllocations) {
|
||||
DEBUG_BREAK("Destruction of not freed Allocator");
|
||||
DEBUG_BREAK("Destruction of not freed Allocator")
|
||||
|
||||
#ifdef MEM_STACK_TRACE
|
||||
// TODO : log leaks and free them up
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
#include "HeapAllocatorGlobal.hpp"
|
||||
#include "PrivateConfig.hpp"
|
||||
|
||||
#include "Utils.hpp"
|
||||
#include "Debugging.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace tp;
|
||||
|
|
@ -40,10 +40,10 @@ namespace tp {
|
|||
MemHead* mNext;
|
||||
ualni mBlockSize;
|
||||
#ifdef MEM_STACK_TRACE
|
||||
CallStackSnapshots::StackShapshot mCallStack;
|
||||
const CallStackCapture::CallStack* mCallStack;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
enum : ualni {
|
||||
ALIGNED_SIZE = ENV_ALNI_SIZE_B,
|
||||
|
|
@ -74,29 +74,28 @@ void* HeapAllocGlobal::allocate(ualni aBlockSize) {
|
|||
// 2) Link with existing blocks
|
||||
mNumAllocations++;
|
||||
if (mEntry) {
|
||||
head->mNext = mEntry->mNext;
|
||||
head->mPrev = mEntry->mPrev;
|
||||
if (mEntry->mNext) mEntry->mNext->mPrev = head;
|
||||
if (mEntry->mPrev) mEntry->mPrev->mNext = head;
|
||||
}
|
||||
else {
|
||||
DEBUG_ASSERT(!mEntry->mNext)
|
||||
head->mNext = nullptr;
|
||||
head->mPrev = mEntry;
|
||||
mEntry->mNext = head;
|
||||
} else {
|
||||
head->mNext = nullptr;
|
||||
head->mPrev = nullptr;
|
||||
}
|
||||
mEntry = head;
|
||||
|
||||
// 3) Wrap fill
|
||||
memsetv(wrap_top, WRAP_SIZE, WRAP_VAL);
|
||||
memsetv(wrap_bottom, WRAP_SIZE, WRAP_VAL);
|
||||
memSetVal(wrap_top, WRAP_SIZE, WRAP_VAL);
|
||||
memSetVal(wrap_bottom, WRAP_SIZE, WRAP_VAL);
|
||||
|
||||
// 4) Trace the stack
|
||||
#ifdef MEM_STACK_TRACE
|
||||
head->mCallStack = gCallStackSnapshots.capture();
|
||||
head->mCallStack = gCSCapture->getSnapshot();
|
||||
#endif
|
||||
|
||||
// 5) clear data
|
||||
#ifdef MEM_CLEAR_ON_ALLOC
|
||||
memsetv(data, aBlockSize, CLEAR_ALLOC_VAL);
|
||||
memSetVal(data, aBlockSize, CLEAR_ALLOC_VAL);
|
||||
#endif
|
||||
|
||||
return data;
|
||||
|
|
@ -104,46 +103,48 @@ void* HeapAllocGlobal::allocate(ualni aBlockSize) {
|
|||
|
||||
void HeapAllocGlobal::deallocate(void* aPtr) {
|
||||
// 1) Restore the pointers
|
||||
auto head = ((MemHead*)(aPtr)) - 1;
|
||||
auto head = ((MemHead*)((int1*)aPtr - WRAP_SIZE)) - 1;
|
||||
auto wrap_top = (int1*)(head + 1);
|
||||
auto data = wrap_top + WRAP_SIZE;
|
||||
auto wrap_bottom = data + head->mBlockSize;
|
||||
|
||||
// 2) Unlink with blocks
|
||||
mNumAllocations--;
|
||||
if (mEntry->mNext) mEntry->mNext->mPrev = mEntry->mPrev;
|
||||
if (mEntry->mPrev) mEntry->mPrev->mNext = mEntry->mNext;
|
||||
DEBUG_ASSERT(!mEntry->mNext)
|
||||
if (head->mNext) head->mNext->mPrev = head->mPrev;
|
||||
if (head->mPrev) head->mPrev->mNext = head->mNext;
|
||||
if (head == mEntry) {
|
||||
if (mEntry->mNext) {
|
||||
mEntry = mEntry->mNext;
|
||||
}
|
||||
else {
|
||||
mEntry = mEntry->mPrev;
|
||||
}
|
||||
mEntry = head->mPrev;
|
||||
}
|
||||
|
||||
// 3) Check the wrap
|
||||
RelAssert(memequalv(wrap_top, WRAP_SIZE, WRAP_VAL) && memequalv(wrap_bottom, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!");
|
||||
ASSERT(!memCompareVal(wrap_top, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!")
|
||||
ASSERT(!memCompareVal(wrap_bottom, WRAP_SIZE, WRAP_VAL) && "Allocated Block Wrap Corrupted!")
|
||||
|
||||
// 4) clear data
|
||||
#ifdef MEM_CLEAR_ON_ALLOC
|
||||
memsetv(data, head->mBlockSize, CLEAR_DEALLOC_VAL);
|
||||
memSetVal(data, head->mBlockSize, CLEAR_DEALLOC_VAL);
|
||||
#endif
|
||||
|
||||
// 5) free the block
|
||||
free(aPtr);
|
||||
free(head);
|
||||
}
|
||||
|
||||
HeapAllocGlobal::~HeapAllocGlobal() {
|
||||
bool HeapAllocGlobal::checkLeaks() {
|
||||
// 1) Check for not deallocated memory
|
||||
if (mNumAllocations) {
|
||||
DEBUG_BREAK("Destruction of not freed Allocator");
|
||||
|
||||
#ifdef MEM_STACK_TRACE
|
||||
// TODO: log leaks
|
||||
gCSCapture->logLeaks();
|
||||
#endif
|
||||
|
||||
DEBUG_BREAK("Destruction of not freed Allocator")
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HeapAllocGlobal::~HeapAllocGlobal() = default;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
|
||||
/*
|
||||
*
|
||||
Implementation:
|
||||
* Adding chunk pointer to each chunk to form one-directional list that keeps track of free chunk
|
||||
* Storing ordered pointers to chunks in order to find desired chunk from delete pointer on de-allocation in log time
|
||||
*
|
||||
* Allocations:
|
||||
* 1) allocate with chunk stored in list entry
|
||||
* 2) ...
|
||||
*
|
||||
* De-allocations:
|
||||
* 1) binary-search with delete pointer to find desired chunk
|
||||
* 2) ...
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Allocators.hpp"
|
||||
#include "PrivateConfig.hpp"
|
||||
|
||||
void tp::PoolAlloc::Chunks::add(Chunk* aChunk) {
|
||||
// ensure order
|
||||
auto smaller_address = findUtil(mBuff, mBuff + mUsedLen, aChunk);
|
||||
for (auto iter = mBuff + mUsedLen; iter != smaller_address; iter--) { *(iter + 1) = *iter; }
|
||||
|
||||
*(smaller_address + 1) = aChunk;
|
||||
mUsedLen++;
|
||||
|
||||
// check for buff overflow
|
||||
if (mUsedLen == mLen) {
|
||||
auto prevBuff = mBuff;
|
||||
mBuff = (Chunk**) HeapAllocGlobal::allocate(sizeof(Chunk*) * mLen * 2);
|
||||
memcp(mBuff, prevBuff, sizeof(Chunk*) * mUsedLen);
|
||||
mLen *= 2;
|
||||
HeapAllocGlobal::deallocate(prevBuff);
|
||||
}
|
||||
}
|
||||
|
||||
void tp::PoolAlloc::Chunks::remove(Chunk* aChunk) {
|
||||
// ensure order
|
||||
auto del_address = findUtil(mBuff, mBuff + mUsedLen, aChunk);
|
||||
for (auto iter = del_address; iter != mBuff + mUsedLen; iter++) { *iter = *(iter + 1); }
|
||||
|
||||
mUsedLen--;
|
||||
|
||||
// check for buff low usage
|
||||
if ((halnf)mUsedLen / (halnf)mLen < 0.25f) {
|
||||
auto prevBuff = mBuff;
|
||||
mBuff = (Chunk**)HeapAllocGlobal::allocate(sizeof(Chunk*) * mLen / 2);
|
||||
memcp(mBuff, prevBuff, sizeof(Chunk*) * mUsedLen);
|
||||
mLen /= 2;
|
||||
HeapAllocGlobal::deallocate(prevBuff);
|
||||
}
|
||||
}
|
||||
|
||||
tp::PoolAlloc::Chunk* tp::PoolAlloc::Chunks::find(void* aPtr) {
|
||||
return *findUtil(mBuff, mBuff + mUsedLen, aPtr);
|
||||
}
|
||||
|
||||
tp::PoolAlloc::Chunk* tp::PoolAlloc::Chunks::findNotFull() {
|
||||
for (ualni idx = 0; idx < mUsedLen; idx++) {
|
||||
if (!mBuff[idx]->isFull()) {
|
||||
return mBuff[idx];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
tp::PoolAlloc::Chunk** tp::PoolAlloc::Chunks::findUtil(Chunk** aLeft, Chunk** aRight, void* aPtr) {
|
||||
auto range = ualni(aRight - aLeft);
|
||||
if (range == 1) { return aLeft; }
|
||||
auto middle = aLeft + range / 2;
|
||||
return (aPtr > *middle) ? findUtil(middle, aRight, aPtr) : findUtil(aLeft, middle, aPtr);
|
||||
}
|
||||
|
||||
|
||||
tp::PoolAlloc::PoolAlloc(ualni aBlockSize, ualni aChunkSize) : mBlockSize(aBlockSize), mChunkSize(aChunkSize) {}
|
||||
|
||||
void* tp::PoolAlloc::allocate() {
|
||||
|
||||
if (!mFreeChunk || mFreeChunk->isFull()) {
|
||||
auto new_free_chunk = mChunks.findNotFull();
|
||||
|
||||
if (!new_free_chunk) {
|
||||
|
||||
new_free_chunk = new ((Chunk*)HeapAllocGlobal::allocate(sizeof(Chunk))) Chunk(mBlockSize, mChunkSize);
|
||||
ASSERT(new_free_chunk);
|
||||
mChunks.add(new_free_chunk);
|
||||
|
||||
if (mFreeChunk) {
|
||||
new_free_chunk->mNext = mFreeChunk->mNext;
|
||||
new_free_chunk->mPrev = mFreeChunk->mPrev;
|
||||
if (mFreeChunk->mNext) mFreeChunk->mNext->mPrev = new_free_chunk;
|
||||
if (mFreeChunk->mPrev) mFreeChunk->mPrev->mNext = new_free_chunk;
|
||||
}
|
||||
else {
|
||||
new_free_chunk->mNext = nullptr;
|
||||
new_free_chunk->mPrev = nullptr;
|
||||
}
|
||||
|
||||
mFreeChunk = new_free_chunk;
|
||||
}
|
||||
}
|
||||
|
||||
return mFreeChunk->allocate();
|
||||
}
|
||||
|
||||
void tp::PoolAlloc::deallocate(void* aPtr) {
|
||||
auto chunk = mChunks.find(aPtr);
|
||||
chunk->deallocate(aPtr);
|
||||
|
||||
if (mFreeChunk->isEmpty()) {
|
||||
|
||||
Chunk* new_chunk = nullptr;
|
||||
for (ualni idx = 0; idx < mChunks.mUsedLen; idx++) {
|
||||
if (!mChunks.mBuff[idx]->isFull() && new_chunk != mFreeChunk) {
|
||||
new_chunk = mChunks.mBuff[idx];
|
||||
}
|
||||
}
|
||||
|
||||
if (new_chunk) {
|
||||
if (mFreeChunk->mNext) mFreeChunk->mNext->mPrev = mFreeChunk->mPrev;
|
||||
if (mFreeChunk->mPrev) mFreeChunk->mPrev->mNext = mFreeChunk->mNext;
|
||||
mChunks.remove(mFreeChunk);
|
||||
HeapAllocGlobal::deallocate(mFreeChunk);
|
||||
mFreeChunk = new_chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tp::PoolAlloc::~PoolAlloc() = default;
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#define MEM_WRAP_SIZE 8 // Wrapping Size in aligned units
|
||||
#define MEM_WRAP_FILL_VAL 0xBB // Wrapping Fill Value
|
||||
#define MEM_CLEAR_ON_ALLOC // Clear data on allocation
|
||||
#define MEM_CLEAR_ON_DEALLOC // Clear data on free
|
||||
#define MEM_CLEAR_ON_DEALLOC_VAL 0xAA // Clear data on free
|
||||
#define MEM_CLEAR_ON_ALLOC_VAL 0xCC // Clear data on free
|
||||
#define MEM_STACK_TRACE // Save stack on allocation call
|
||||
#define MEM_STACK_TRACE_MAX_DEPTH 32 // Call stack max depth
|
||||
Loading…
Add table
Add a link
Reference in a new issue