1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

common/memory: add check-callback to getPath() to select desired path

This is a workaround until we have a better heuristic (maybe shortest
path?) to choose between multiple paths in the graph. Since the (abstract)
graph has no idea about memory translations, getPath() may even yield
paths that are no valid translation because a pair of inbound/outbound
edges must not neccessarily share a common address window, but from the
perspective of the abstract graph present a valid path.
The callback function is used by the MemoryManager to verify if a path
candidate represents a valid translation.
This commit is contained in:
Daniel Krebs 2018-05-15 12:13:51 +02:00
parent 29709aed7a
commit 105f47d2d0
4 changed files with 60 additions and 6 deletions

View file

@ -212,9 +212,17 @@ public:
vertexGetEdges(VertexIdentifier vertexId) const
{ return getVertex(vertexId)->edges; }
using check_path_fn = std::function<bool(const Path&)>;
static bool
checkPath(const Path&)
{ return true; }
bool getPath(VertexIdentifier fromVertexId,
VertexIdentifier toVertexId,
Path& path)
Path& path,
check_path_fn pathCheckFunc = checkPath)
{
if(fromVertexId == toVertexId) {
// arrived at the destination
@ -244,7 +252,8 @@ public:
path.push_back(edgeId);
// recursive, depth-first search
if(getPath(edgeOfFromVertex->to, toVertexId, path)) {
if(getPath(edgeOfFromVertex->to, toVertexId, path, pathCheckFunc) and
pathCheckFunc(path)) {
// path found, we're done
return true;
} else {

View file

@ -3,6 +3,7 @@
#include <cstdint>
#include <string>
#include <map>
#include <stdexcept>
#include <unistd.h>
#include "log.hpp"
@ -73,7 +74,12 @@ private:
// This is a singleton, so private constructor ...
MemoryManager() :
memoryGraph("MemoryGraph"),
logger(loggerGetOrCreate("MemoryManager")) {}
logger(loggerGetOrCreate("MemoryManager"))
{
pathCheckFunc = [&](const MemoryGraph::Path& path) {
return this->pathCheck(path);
};
}
// ... and no copying or assigning
MemoryManager(const MemoryManager&) = delete;
@ -144,6 +150,8 @@ public:
using AddressSpaceId = MemoryGraph::VertexIdentifier;
using MappingId = MemoryGraph::EdgeIdentifier;
struct InvalidTranslation : public std::exception {};
/// Get singleton instance
static MemoryManager&
get();
@ -210,6 +218,8 @@ private:
getTranslationFromMapping(const Mapping& mapping)
{ return MemoryTranslation(mapping.src, mapping.dest, mapping.size); }
bool
pathCheck(const MemoryGraph::Path& path);
private:
/// Directed graph that stores address spaces and memory mappings
@ -221,6 +231,8 @@ private:
/// Logger for universal access in this class
SpdLogger logger;
MemoryGraph::check_path_fn pathCheckFunc;
/// Static pointer to global instance, because this is a singleton
static MemoryManager* instance;
};

View file

@ -10,6 +10,15 @@ namespace utils {
std::vector<std::string>
tokenize(std::string s, std::string delimiter);
template<typename T>
void
assertExcept(bool condition, const T& exception)
{
if(not condition)
throw exception;
}
} // namespace utils
} // namespace villas

View file

@ -2,8 +2,11 @@
#include <limits>
#include <cstdint>
#include <villas/utils.hpp>
#include "memory_manager.hpp"
using namespace villas::utils;
namespace villas {
MemoryManager*
@ -76,7 +79,8 @@ MemoryManager::getTranslation(MemoryManager::AddressSpaceId fromAddrSpaceId,
{
// find a path through the memory graph
MemoryGraph::Path path;
if(not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, path)) {
if(not memoryGraph.getPath(fromAddrSpaceId, toAddrSpaceId, path, pathCheckFunc)) {
auto fromAddrSpace = memoryGraph.getVertex(fromAddrSpaceId);
auto toAddrSpace = memoryGraph.getVertex(toAddrSpaceId);
@ -98,6 +102,26 @@ MemoryManager::getTranslation(MemoryManager::AddressSpaceId fromAddrSpaceId,
return translation;
}
bool
MemoryManager::pathCheck(const MemoryGraph::Path& path)
{
// start with an identity mapping
MemoryTranslation translation(0, 0, SIZE_MAX);
// Try to add all mappings together to a common translation. If this fails
// there is a non-overlapping window
for(auto& mappingId : path) {
auto mapping = memoryGraph.getEdge(mappingId);
try {
translation += getTranslationFromMapping(*mapping);
} catch(const InvalidTranslation&) {
return false;
}
}
return true;
}
uintptr_t
MemoryTranslation::getLocalAddr(uintptr_t addrInForeignAddrSpace) const
{
@ -125,8 +149,8 @@ MemoryTranslation::operator+=(const MemoryTranslation& other)
const uintptr_t other_src_high = other.src + other.size;
// make sure there is a common memory area
assert(other.src < this_dst_high);
assert(this->dst < other_src_high);
assertExcept(other.src < this_dst_high, MemoryManager::InvalidTranslation());
assertExcept(this->dst < other_src_high, MemoryManager::InvalidTranslation());
const uintptr_t hi = std::max(this_dst_high, other_src_high);
const uintptr_t lo = std::min(this->dst, other.src);