// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include template NzMemoryPool::NzMemoryPool(unsigned int count) : m_freeCount(count), m_previous(nullptr), m_size(count) { m_pool.reset(new nzUInt8[blockSize * count]); m_freeList.reset(new void*[count]); // Remplissage de la free list for (unsigned int i = 0; i < count; ++i) m_freeList[i] = &m_pool[blockSize * (count-i-1)]; } template NzMemoryPool::NzMemoryPool(NzMemoryPool* pool) : NzMemoryPool(pool->m_size) { m_previous = pool; } template template T* NzMemoryPool::Allocate() { static_assert(sizeof(T) <= blockSize, "This type is too large for this memory pool"); return static_cast(Allocate(sizeof(T))); } template void* NzMemoryPool::Allocate(unsigned int size) { if (size <= blockSize) { if (m_freeCount > 0) return m_freeList[--m_freeCount]; else if (canGrow) { if (!m_next) m_next.reset(new NzMemoryPool(this)); return m_next->Allocate(size); } } return NzOperatorNew(size); } template void NzMemoryPool::Free(void* ptr) { if (ptr) { // Le pointer nous appartient-il ? nzUInt8* freePtr = static_cast(ptr); nzUInt8* poolPtr = m_pool.get(); if (freePtr >= poolPtr && freePtr < poolPtr + blockSize*m_size) { #if NAZARA_CORE_SAFE if ((freePtr - poolPtr) % blockSize != 0) { throw std::runtime_error("Pointer does not belong to memory pool"); return; } #endif m_freeList[m_freeCount++] = ptr; // Si nous sommes vide et l'extension d'un autre pool, on se suicide if (m_freeCount == m_size && m_previous && !m_next) { m_previous->m_next.release(); delete this; // Suicide } } else { if (m_next) m_next->Free(ptr); else NzOperatorDelete(ptr); } } } template unsigned int NzMemoryPool::GetFreeBlocks() const { return m_freeCount; } template unsigned int NzMemoryPool::GetSize() const { return m_size; } #include