Files
compute-runtime/shared/source/utilities/sorted_vector.h
Dominik Dabek af1620a308 fix(ocl): allocation info from pool svm ptr
Fix querying allocation info from pooled svm ptr.
Handle requested allocation alignment.
Refactor sorted vector usage.
Do not associate device with host pool allocation.

Related-To: NEO-9700

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
2024-01-05 15:20:01 +01:00

107 lines
3.2 KiB
C++

/*
* Copyright (C) 2018-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/helpers/debug_helpers.h"
#include <algorithm>
#include <limits>
#include <memory>
#include <utility>
#include <vector>
namespace NEO {
template <typename ValueType>
class BaseSortedPointerWithValueVector {
public:
using PointerPair = std::pair<const void *, std::unique_ptr<ValueType>>;
using Container = std::vector<PointerPair>;
BaseSortedPointerWithValueVector() = default;
bool comparePointers(size_t allowedOffset, const void *ptr, const void *otherPtr) {
return ptr == otherPtr || (allowedOffset > 0u && (otherPtr < ptr &&
(reinterpret_cast<uintptr_t>(ptr) < (reinterpret_cast<uintptr_t>(otherPtr) + allowedOffset))));
}
size_t getAllocationSize(const std::unique_ptr<ValueType> &data) {
return data->size;
}
void insert(const void *ptr, const ValueType &value) {
allocations.push_back(std::make_pair(ptr, std::make_unique<ValueType>(value)));
for (size_t i = allocations.size() - 1; i > 0; --i) {
if (allocations[i].first < allocations[i - 1].first) {
std::iter_swap(allocations.begin() + i, allocations.begin() + i - 1);
} else {
break;
}
}
}
void remove(const void *ptr) {
auto removeIt = std::remove_if(allocations.begin(), allocations.end(), [&ptr](const PointerPair &other) {
return ptr == other.first;
});
allocations.erase(removeIt);
}
typename Container::iterator getImpl(const void *ptr, bool allowOffset) {
if (allocations.size() == 0) {
return allocations.end();
}
if (nullptr == ptr) {
return allocations.end();
}
DEBUG_BREAK_IF(allocations.size() > static_cast<size_t>(std::numeric_limits<int>::max()));
int begin = 0;
int end = static_cast<int>(allocations.size() - 1);
while (end >= begin) {
int currentPos = (begin + end) / 2;
const auto &allocation = allocations[currentPos];
const size_t allowedOffset = allowOffset ? getAllocationSize(allocation.second) : 0u;
if (comparePointers(allowedOffset, ptr, allocation.first)) {
return allocations.begin() + currentPos;
} else if (ptr < allocation.first) {
end = currentPos - 1;
continue;
} else {
begin = currentPos + 1;
continue;
}
}
return allocations.end();
}
std::unique_ptr<ValueType> extract(const void *ptr) {
std::unique_ptr<ValueType> retVal{};
auto it = getImpl(ptr, false);
if (it != allocations.end()) {
retVal.swap(it->second);
allocations.erase(it);
}
return retVal;
}
ValueType *get(const void *ptr) {
auto it = getImpl(ptr, true);
if (it != allocations.end()) {
return it->second.get();
}
return nullptr;
}
size_t getNumAllocs() const { return allocations.size(); }
Container allocations;
};
} // namespace NEO