Files
compute-runtime/shared/source/memory_manager/internal_allocation_storage.cpp
Maciej Plewka 54eee2a88b Fix multi thread usage of external host alloc
With this commit OpenCL will track if external host memory is used from
few threads and will secure to update task count in all threads before
destroing allocation.

Resolves: NEO-6807

Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
2022-04-26 15:31:24 +02:00

83 lines
3.5 KiB
C++

/*
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/memory_manager/internal_allocation_storage.h"
#include "shared/source/command_stream/command_stream_receiver.h"
#include "shared/source/memory_manager/host_ptr_manager.h"
#include "shared/source/os_interface/os_context.h"
namespace NEO {
InternalAllocationStorage::InternalAllocationStorage(CommandStreamReceiver &commandStreamReceiver)
: commandStreamReceiver(commandStreamReceiver),
temporaryAllocations(TEMPORARY_ALLOCATION),
allocationsForReuse(REUSABLE_ALLOCATION){};
void InternalAllocationStorage::storeAllocation(std::unique_ptr<GraphicsAllocation> &&gfxAllocation, uint32_t allocationUsage) {
uint32_t taskCount = gfxAllocation->getTaskCount(commandStreamReceiver.getOsContext().getContextId());
if (allocationUsage == REUSABLE_ALLOCATION) {
taskCount = commandStreamReceiver.peekTaskCount();
}
storeAllocationWithTaskCount(std::move(gfxAllocation), allocationUsage, taskCount);
}
void InternalAllocationStorage::storeAllocationWithTaskCount(std::unique_ptr<GraphicsAllocation> &&gfxAllocation, uint32_t allocationUsage, uint32_t taskCount) {
if (allocationUsage == REUSABLE_ALLOCATION) {
if (DebugManager.flags.DisableResourceRecycling.get()) {
commandStreamReceiver.getMemoryManager()->freeGraphicsMemory(gfxAllocation.release());
return;
}
}
auto &allocationsList = (allocationUsage == TEMPORARY_ALLOCATION) ? temporaryAllocations : allocationsForReuse;
gfxAllocation->updateTaskCount(taskCount, commandStreamReceiver.getOsContext().getContextId());
allocationsList.pushTailOne(*gfxAllocation.release());
}
void InternalAllocationStorage::cleanAllocationList(uint32_t waitTaskCount, uint32_t allocationUsage) {
freeAllocationsList(waitTaskCount, (allocationUsage == TEMPORARY_ALLOCATION) ? temporaryAllocations : allocationsForReuse);
}
void InternalAllocationStorage::freeAllocationsList(uint32_t waitTaskCount, AllocationsList &allocationsList) {
auto memoryManager = commandStreamReceiver.getMemoryManager();
auto lock = memoryManager->getHostPtrManager()->obtainOwnership();
GraphicsAllocation *curr = allocationsList.detachNodes();
IDList<GraphicsAllocation, false, true> allocationsLeft;
while (curr != nullptr) {
auto *next = curr->next;
if (curr->getTaskCount(commandStreamReceiver.getOsContext().getContextId()) <= waitTaskCount && curr->hostPtrTaskCountAssignment == 0) {
memoryManager->freeGraphicsMemory(curr);
} else {
allocationsLeft.pushTailOne(*curr);
}
curr = next;
}
if (allocationsLeft.peekIsEmpty() == false) {
allocationsList.splice(*allocationsLeft.detachNodes());
}
}
std::unique_ptr<GraphicsAllocation> InternalAllocationStorage::obtainReusableAllocation(size_t requiredSize, AllocationType allocationType) {
auto allocation = allocationsForReuse.detachAllocation(requiredSize, nullptr, &commandStreamReceiver, allocationType);
return allocation;
}
std::unique_ptr<GraphicsAllocation> InternalAllocationStorage::obtainTemporaryAllocationWithPtr(size_t requiredSize, const void *requiredPtr, AllocationType allocationType) {
auto allocation = temporaryAllocations.detachAllocation(requiredSize, requiredPtr, &commandStreamReceiver, allocationType);
return allocation;
}
DeviceBitfield InternalAllocationStorage::getDeviceBitfield() const {
return commandStreamReceiver.getOsContext().getDeviceBitfield();
}
} // namespace NEO