diff --git a/public/tier1/utlscratchmemory.h b/public/tier1/utlscratchmemory.h index 4d852df4..72c5ea6a 100644 --- a/public/tier1/utlscratchmemory.h +++ b/public/tier1/utlscratchmemory.h @@ -11,66 +11,59 @@ struct UtlScratchMemoryPoolMark_t int m_nBytesFree; }; -// Chunks memory allocator of a size (m_nBlockSize), where first 16 bytes are allocated for -// MemoryBlock_t struct, that holds additional information about next chunk. +// Chunked memory allocator of a size (m_nBlockSize), where first sizeof(MemoryBlock_t) bytes are allocated for +// MemoryBlock_t struct, that holds additional information about next chunk in a linked-list manner. class CUtlScratchMemoryPool { public: - CUtlScratchMemoryPool() : m_pFirstBlock(NULL), m_nBlockSize(0), m_bSearchAllBlocks(false) {} - CUtlScratchMemoryPool(int nBlockSize, void *pExternalMem, bool bSearchAllBlocks) : - m_pFirstBlock(NULL), m_nBlockSize(nBlockSize), m_bSearchAllBlocks(bSearchAllBlocks) - { - Init(nBlockSize, pExternalMem, bSearchAllBlocks); - } + DLL_CLASS_IMPORT CUtlScratchMemoryPool(); - ~CUtlScratchMemoryPool() - { - // FreeAll(); - } + // Creates a scratch memory pool with set blocksize, already allocated memory chunk could be provided via pExternalMem, where nAllocatedBlockSize + // is a size of an allocated memory, passing the memory of size less than sizeof(MemoryBlock_t) bytes (required for the header) might lead to OOB access. + // If bSearchAllBlocks is true, it would search all the blocks to find free memory to use, alternatively it would allocate new block if + // the current one can't fit the required memory. + DLL_CLASS_IMPORT CUtlScratchMemoryPool( uint32 nBlockSize, uint32 nAllocatedBlockSize = 0, void *pExternalMem = NULL, bool bSearchAllBlocks = true ); + DLL_CLASS_IMPORT ~CUtlScratchMemoryPool(); - void Init(int nBlockSize, void *pExternalMem, bool bSearchAllBlocks) - { - Assert(nBlockSize > sizeof(MemoryBlock_t)); + // Initializes scratch memory pool with set blocksize, already allocated memory chunk could be provided via pExternalMem, where nAllocatedBlockSize + // is a size of an allocated memory, passing the memory of size less than sizeof(MemoryBlock_t) bytes (required for the header) might lead to OOB access. + // If bSearchAllBlocks is true, it would search all the blocks to find free memory to use, alternatively it would allocate new block if + // the current one can't fit the required memory. + DLL_CLASS_IMPORT void Init( uint32 nBlockSize, uint32 nAllocatedBlockSize = 0, void *pExternalMem = NULL, bool bSearchAllBlocks = true ); - if(pExternalMem != NULL) - { - m_pFirstBlock = (MemoryBlock_t *)pExternalMem; + // Returns info about currently active chunk of memory + DLL_CLASS_IMPORT UtlScratchMemoryPoolMark_t GetCurrentAllocPoint() const; - m_pFirstBlock->m_pNext = NULL; - m_pFirstBlock->m_nBytesFree = nBlockSize - 16; - m_pFirstBlock->m_bSkipDeallocation = true; - } - } + // Allocates a memory within the current chunk, if it fits, or creates a new one instead (would search other chunks if m_bSearchAllBlocks == true) + DLL_CLASS_IMPORT void *AllocAligned( int nSizeInBytes, int nAlignment ); - UtlScratchMemoryPoolMark_t GetCurrentAllocPoint() const - { - UtlScratchMemoryPoolMark_t result{}; - result.m_pBlock = m_pFirstBlock; + // Counts the overall allocated size of all the chunks within this memory pool + DLL_CLASS_IMPORT size_t AllocSize() const; + // Counts the overall amount of chunks allocated within this memory pool + DLL_CLASS_IMPORT size_t AllocationCount() const; + // Counts the overall free memory available across all the allocated chunks within this memory pool + DLL_CLASS_IMPORT size_t TotalMemFree() const; - if(m_pFirstBlock) - result.m_nBytesFree = m_pFirstBlock->m_nBytesFree; - else - result.m_nBytesFree = 0; - - return result; - } + // Frees all the allocated chunks, leaving only one active chunk + DLL_CLASS_IMPORT void FreeAll(); + // Frees all the allocated chunks that lead to the mark, would result in a crash if the mark doesn't point to any of the chunks within this memory pool + DLL_CLASS_IMPORT void FreeToAllocPoint( UtlScratchMemoryPoolMark_t mark ); - // GAMMACASE: Not finished functions: - // void *AddNewBlock(int nSizeInBytes); - // void *AllocAligned(int nSizeInBytes, int nAlignment); - // void FreeToAllocPoint(UtlScratchMemoryPoolMark_t mark); - // void FreeAll(); +protected: + // Allocates new chunk of memory, if nSizeInBytes > (m_nBlockSize / 2) the allocated chunk would be allocated as is without free memory in it (even if it exceeds the m_nBlockSize). + DLL_CLASS_IMPORT void *AddNewBlock( int nSizeInBytes ); private: - struct MemoryBlock_t + struct ALIGN16 MemoryBlock_t { MemoryBlock_t *m_pNext; - int m_nBytesFree; - bool m_bSkipDeallocation; - }; + uint32 m_nBytesFree; + uint32 m_nBlockSize; + uint32 m_nAllocSize; + } ALIGN16_POST; MemoryBlock_t *m_pFirstBlock; - int m_nBlockSize; + uint32 m_nBlockSize; bool m_bSearchAllBlocks; }; @@ -78,7 +71,7 @@ template class CUtlScratchMemoryPoolFixedGrowable : public CUtlScratchMemoryPool { public: - CUtlScratchMemoryPoolFixedGrowable(bool bSearchAllBlocks) : CUtlScratchMemoryPool(SIZE, &m_initialAllocationMemory, bSearchAllBlocks) { } + CUtlScratchMemoryPoolFixedGrowable( bool bSearchAllBlocks = true ) : CUtlScratchMemoryPool( SIZE, SIZE, &m_initialAllocationMemory, bSearchAllBlocks ) {} private: unsigned char m_initialAllocationMemory[SIZE]; diff --git a/public/variant.h b/public/variant.h index bc1f7871..73f25a8a 100644 --- a/public/variant.h +++ b/public/variant.h @@ -42,12 +42,7 @@ public: static void *Allocate(int nSize) { - // GAMMACASE: Remove #if condition once CUtlScratchMemoryPool is finished. -#if defined(UTLSCRATCHMEMORYPOOL_FINISHED) - return sm_pMemoryPool.AllocAligned(nSize, 8 * (nSize >= 16) + 8); -#else - return NULL; -#endif + return sm_pMemoryPool->AllocAligned(nSize, 8 * (nSize >= 16) + 8); } static void Activate(CUtlScratchMemoryPool *pMemoryPool, bool bEnable)