diff --git a/src/AllocationPool.h b/src/AllocationPool.h index 1b27462abc..0a529a8e37 100644 --- a/src/AllocationPool.h +++ b/src/AllocationPool.h @@ -11,18 +11,18 @@ class cAllocationPool public: class cStarvationCallbacks { - public: - virtual ~cStarvationCallbacks() {} + public: + virtual ~cStarvationCallbacks() {} - /** Is called when the reserve buffer starts to be used */ - virtual void OnStartUsingReserve() = 0; + /** Is called when the reserve buffer starts to be used */ + virtual void OnStartUsingReserve() = 0; - /** Is called once the reserve buffer has returned to normal size */ - virtual void OnEndUsingReserve() = 0; + /** Is called once the reserve buffer has returned to normal size */ + virtual void OnEndUsingReserve() = 0; - /** Is called when the allocation pool is unable to allocate memory. Will be repeatedly + /** Is called when the allocation pool is unable to allocate memory. Will be repeatedly called if it does not free sufficient memory */ - virtual void OnOutOfReserve() = 0; + virtual void OnOutOfReserve() = 0; }; virtual ~cAllocationPool() {} @@ -65,11 +65,12 @@ class cListAllocationPool: { public: - cListAllocationPool(std::unique_ptr::cStarvationCallbacks> a_Callbacks, size_t a_NumElementsInReserve): - m_NumElementsInReserve(a_NumElementsInReserve), + cListAllocationPool(std::unique_ptr::cStarvationCallbacks> a_Callbacks, size_t a_MinElementsInReserve, size_t a_MaxElementsInReserve) : + m_MinElementsInReserve(a_MinElementsInReserve), + m_MaxElementsInReserve(a_MaxElementsInReserve), m_Callbacks(std::move(a_Callbacks)) { - for (size_t i = 0; i < m_NumElementsInReserve; i++) + for (size_t i = 0; i < m_MinElementsInReserve; i++) { void * space = malloc(sizeof(T)); if (space == nullptr) @@ -86,7 +87,7 @@ class cListAllocationPool: { while (!m_FreeList.empty()) { - free (m_FreeList.front()); + free(m_FreeList.front()); m_FreeList.pop_front(); } } @@ -94,7 +95,7 @@ class cListAllocationPool: virtual T * Allocate() override { - if (m_FreeList.size() <= m_NumElementsInReserve) + if (m_FreeList.size() <= m_MinElementsInReserve) { void * space = malloc(sizeof(T)); if (space != nullptr) @@ -113,7 +114,7 @@ class cListAllocationPool: #pragma pop_macro("new") #endif } - else if (m_FreeList.size() == m_NumElementsInReserve) + else if (m_FreeList.size() == m_MinElementsInReserve) { m_Callbacks->OnStartUsingReserve(); } @@ -151,10 +152,17 @@ class cListAllocationPool: { return; } - // placement destruct. - a_ptr->~T(); + + a_ptr->~T(); // placement destruct. + + if (m_FreeList.size() >= m_MaxElementsInReserve) + { + free(a_ptr); + return; + } + m_FreeList.push_front(a_ptr); - if (m_FreeList.size() == m_NumElementsInReserve) + if (m_FreeList.size() == m_MinElementsInReserve) { m_Callbacks->OnEndUsingReserve(); } @@ -162,7 +170,9 @@ class cListAllocationPool: private: /** The minimum number of elements to keep in the free list before malloc fails */ - size_t m_NumElementsInReserve; + size_t m_MinElementsInReserve; + /** Maximum free list size before returning memory to the OS */ + size_t m_MaxElementsInReserve; std::list m_FreeList; std::unique_ptr::cStarvationCallbacks> m_Callbacks; diff --git a/src/ChunkDataCallback.h b/src/ChunkDataCallback.h index ec8e1180f4..c26ec5beb8 100644 --- a/src/ChunkDataCallback.h +++ b/src/ChunkDataCallback.h @@ -115,7 +115,7 @@ class cChunkDataCopyCollector : }; cChunkDataCopyCollector(): - m_Pool(cpp14::make_unique(), cChunkData::NumSections), // Keep 1 chunk worth of reserve + m_Pool(cpp14::make_unique(), 0, cChunkData::NumSections), // Keep 1 chunk worth of reserve m_Data(m_Pool) { } diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index 4936b11ebf..dd8f1add1d 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -39,7 +39,7 @@ cChunkMap::cChunkMap(cWorld * a_World) : m_World(a_World), m_Pool( cpp14::make_unique>( - cpp14::make_unique(), 1600u + cpp14::make_unique(), 1600u, 5000u ) ) { diff --git a/src/SetChunkData.cpp b/src/SetChunkData.cpp index 60a27d43a6..19448147ac 100644 --- a/src/SetChunkData.cpp +++ b/src/SetChunkData.cpp @@ -26,7 +26,7 @@ struct sMemCallbacks: cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) : m_ChunkX(a_ChunkX), m_ChunkZ(a_ChunkZ), - m_Pool(cpp14::make_unique(), cChunkData::NumSections), + m_Pool(cpp14::make_unique(), 0u, cChunkData::NumSections), m_ChunkData(m_Pool), m_IsLightValid(false), m_IsHeightMapValid(false),