/* * Copyright (C) 2023 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "shared/source/memory_manager/memory_manager.h" #include "shared/source/utilities/buffer_pool_allocator.h" #include "shared/source/utilities/heap_allocator.h" #include namespace NEO { template AbstractBuffersPool::AbstractBuffersPool(MemoryManager *memoryManager, OnChunkFreeCallback onChunkFreeCb) : memoryManager{memoryManager}, onChunkFreeCallback{onChunkFreeCb} { static_assert(std::is_base_of_v); } template AbstractBuffersPool::AbstractBuffersPool(AbstractBuffersPool &&bufferPool) : memoryManager{bufferPool.memoryManager}, mainStorage{std::move(bufferPool.mainStorage)}, chunkAllocator{std::move(bufferPool.chunkAllocator)}, onChunkFreeCallback{bufferPool.onChunkFreeCallback} {} template void AbstractBuffersPool::tryFreeFromPoolBuffer(BufferParentType *possiblePoolBuffer, size_t offset, size_t size) { if (this->isPoolBuffer(possiblePoolBuffer)) { this->chunksToFree.push_back({offset, size}); } } template bool AbstractBuffersPool::isPoolBuffer(const BufferParentType *buffer) const { static_assert(std::is_base_of_v); return (buffer && this->mainStorage.get() == buffer); } template void AbstractBuffersPool::drain() { const auto &allocationsVec = this->getAllocationsVector(); for (auto allocation : allocationsVec) { if (allocation && this->memoryManager->allocInUse(*allocation)) { return; } } for (auto &chunk : this->chunksToFree) { this->chunkAllocator->free(chunk.first + startingOffset, chunk.second); if (static_cast(this)->onChunkFreeCallback) { (static_cast(this)->*onChunkFreeCallback)(chunk.first, chunk.second); } } this->chunksToFree.clear(); } template bool AbstractBuffersAllocator::isPoolBuffer(const BufferParentType *buffer) const { static_assert(std::is_base_of_v); for (auto &bufferPool : this->bufferPools) { if (bufferPool.isPoolBuffer(buffer)) { return true; } } return false; } template void AbstractBuffersAllocator::tryFreeFromPoolBuffer(BufferParentType *possiblePoolBuffer, size_t offset, size_t size) { this->tryFreeFromPoolBuffer(possiblePoolBuffer, offset, size, this->bufferPools); } template void AbstractBuffersAllocator::tryFreeFromPoolBuffer(BufferParentType *possiblePoolBuffer, size_t offset, size_t size, std::vector &bufferPoolsVec) { auto lock = std::unique_lock(this->mutex); for (auto &bufferPool : bufferPoolsVec) { bufferPool.tryFreeFromPoolBuffer(possiblePoolBuffer, offset, size); // NOLINT(clang-analyzer-cplusplus.NewDelete) } } template void AbstractBuffersAllocator::drain() { this->drain(this->bufferPools); } template void AbstractBuffersAllocator::drain(std::vector &bufferPoolsVec) { for (auto &bufferPool : bufferPoolsVec) { bufferPool.drain(); } } template void AbstractBuffersAllocator::addNewBufferPool(BuffersPoolType &&bufferPool) { this->addNewBufferPool(std::move(bufferPool), this->bufferPools); } template void AbstractBuffersAllocator::addNewBufferPool(BuffersPoolType &&bufferPool, std::vector &bufferPoolsVec) { if (bufferPool.mainStorage) { bufferPoolsVec.push_back(std::move(bufferPool)); } } } // namespace NEO