[orc-rt] Move SPS controller interface funcs into their own headers. (#186991)
This provides clean separation between the ORC runtime code that implements runtime functionality and the wrapper functions that permit this code to be called from the controller via the ExecutorProcessControl API. Separating the controller interface from the implementation functions should allow clients to introduce alternative serialization schemes if they want (e.g. JSON). In particular, this commit adds a new orc-rt/include/orc-rt/sps-ci directory and moves SimpleNativeMemoryMap SPS controller interface into a new header in that directory. This commit also splits the implementation and testing of the SPS controller interface for SimpleNativeMemoryMap into separate files.
This commit is contained in:
parent
e904d559c5
commit
612d80348f
@ -23,6 +23,8 @@ set(ORC_RT_HEADERS
|
||||
orc-rt/SimpleNativeMemoryMap.h
|
||||
orc-rt/SimplePackedSerialization.h
|
||||
orc-rt/SPSAllocAction.h
|
||||
orc-rt/sps-ci/AllSPSCI.h
|
||||
orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h
|
||||
orc-rt/SPSMemoryFlags.h
|
||||
orc-rt/SPSWrapperFunction.h
|
||||
orc-rt/SPSWrapperFunctionBuffer.h
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#define ORC_RT_SYMTAB_PAIR(sym) {{#sym}, reinterpret_cast<const void *>(&sym)}
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
/// A symbol table defining the interface exposed by the ORC runtime to the
|
||||
|
||||
@ -18,7 +18,12 @@
|
||||
#include "orc-rt/SimplePackedSerialization.h"
|
||||
#include "orc-rt/WrapperFunction.h"
|
||||
|
||||
#define ORC_RT_SPS_INTERFACE ORC_RT_INTERFACE
|
||||
#define ORC_RT_SPS_WRAPPER(Name, SPSSig, Handle) \
|
||||
static void Name(orc_rt_SessionRef S, uint64_t CallId, \
|
||||
orc_rt_WrapperFunctionReturn Return, \
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) { \
|
||||
SPSWrapperFunction<SPSSig>::handle(S, CallId, Return, ArgBytes, Handle); \
|
||||
}
|
||||
|
||||
namespace orc_rt {
|
||||
namespace detail {
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "orc-rt/AllocAction.h"
|
||||
#include "orc-rt/Error.h"
|
||||
#include "orc-rt/MemoryFlags.h"
|
||||
#include "orc-rt/SPSWrapperFunction.h"
|
||||
#include "orc-rt/Service.h"
|
||||
#include "orc-rt/move_only_function.h"
|
||||
|
||||
@ -113,22 +112,4 @@ private:
|
||||
|
||||
} // namespace orc_rt
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
#endif // ORC_RT_SIMPLENATIVEMEMORYMAP_H
|
||||
|
||||
26
orc-rt/include/orc-rt/sps-ci/AllSPSCI.h
Normal file
26
orc-rt/include/orc-rt/sps-ci/AllSPSCI.h
Normal file
@ -0,0 +1,26 @@
|
||||
//===- AllSPSCI.h -- All SPS Controller Interface registrations -*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Convenience header that includes all SPS Controller Interface headers and
|
||||
// declares addAll.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ORC_RT_SPS_CI_ALLSPSCI_H
|
||||
#define ORC_RT_SPS_CI_ALLSPSCI_H
|
||||
|
||||
#include "orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h"
|
||||
|
||||
namespace orc_rt::sps_ci {
|
||||
|
||||
/// Add all SPS interfaces to the controller interface.
|
||||
Error addAll(ControllerInterface &CI);
|
||||
|
||||
} // namespace orc_rt::sps_ci
|
||||
|
||||
#endif // ORC_RT_SPS_CI_ALLSPSCI_H
|
||||
25
orc-rt/include/orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h
Normal file
25
orc-rt/include/orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h
Normal file
@ -0,0 +1,25 @@
|
||||
//===------- SimpleNativeMemoryMapSPSCI.h -- SNMM SPS CI --------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SPS Controller Interface registration for SimpleNativeMemoryMap.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ORC_RT_SPS_CI_SIMPLENATIVEMEMORYMAPSPSCI_H
|
||||
#define ORC_RT_SPS_CI_SIMPLENATIVEMEMORYMAPSPSCI_H
|
||||
|
||||
#include "orc-rt/ControllerInterface.h"
|
||||
|
||||
namespace orc_rt::sps_ci {
|
||||
|
||||
/// Add the SimpleNativeMemoryMap SPS interface to the controller interface.
|
||||
Error addSimpleNativeMemoryMap(ControllerInterface &CI);
|
||||
|
||||
} // namespace orc_rt::sps_ci
|
||||
|
||||
#endif // ORC_RT_SPS_CI_SIMPLENATIVEMEMORYMAPSPSCI_H
|
||||
@ -9,6 +9,8 @@ set(files
|
||||
SimpleNativeMemoryMap.cpp
|
||||
TaskDispatcher.cpp
|
||||
ThreadPoolTaskDispatcher.cpp
|
||||
sps-ci/AllSPSCI.cpp
|
||||
sps-ci/SimpleNativeMemoryMapSPSCI.cpp
|
||||
)
|
||||
|
||||
add_library(orc-rt-executor STATIC ${files})
|
||||
|
||||
@ -14,8 +14,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "orc-rt/SimpleNativeMemoryMap.h"
|
||||
#include "orc-rt/SPSAllocAction.h"
|
||||
#include "orc-rt/SPSMemoryFlags.h"
|
||||
#include <sstream>
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__)
|
||||
@ -26,47 +24,6 @@
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<
|
||||
SPSSimpleNativeMemoryMapSegment,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment> {
|
||||
using SPSType =
|
||||
SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
|
||||
|
||||
public:
|
||||
static bool
|
||||
deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment &S) {
|
||||
AllocGroup AG;
|
||||
ExecutorAddr Address;
|
||||
uint64_t Size;
|
||||
span<const char> Content;
|
||||
if (!SPSType::AsArgList::deserialize(IB, AG, Address, Size, Content))
|
||||
return false;
|
||||
if (Size > std::numeric_limits<size_t>::max())
|
||||
return false;
|
||||
S = {AG, Address.toPtr<char *>(), static_cast<size_t>(Size), Content};
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
SimpleNativeMemoryMap::InitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static bool deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::InitializeRequest &FR) {
|
||||
return SPSType::AsArgList::deserialize(IB, FR.Segments, FR.AAPs);
|
||||
}
|
||||
};
|
||||
|
||||
void SimpleNativeMemoryMap::reserve(OnReserveCompleteFn &&OnComplete,
|
||||
size_t Size) {
|
||||
// FIXME: Get page size from session object.
|
||||
@ -366,44 +323,4 @@ Error SimpleNativeMemoryMap::recordDeallocActions(
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
using Sig = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSSize);
|
||||
SPSWrapperFunction<Sig>::handle(
|
||||
S, CallId, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(&SimpleNativeMemoryMap::reserve));
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
using Sig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<Sig>::handle(S, CallId, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::releaseMultiple));
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
using Sig = SPSExpected<SPSExecutorAddr>(
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapInitializeRequest);
|
||||
SPSWrapperFunction<Sig>::handle(S, CallId, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::initialize));
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef S, uint64_t CallId, orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
using Sig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<Sig>::handle(
|
||||
S, CallId, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::deinitializeMultiple));
|
||||
}
|
||||
|
||||
} // namespace orc_rt
|
||||
|
||||
28
orc-rt/lib/executor/sps-ci/AllSPSCI.cpp
Normal file
28
orc-rt/lib/executor/sps-ci/AllSPSCI.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
//===- AllSPSCI.cpp -------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implementation of sps_ci::addAll.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "orc-rt/sps-ci/AllSPSCI.h"
|
||||
|
||||
namespace orc_rt::sps_ci {
|
||||
|
||||
Error addAll(ControllerInterface &CI) {
|
||||
using AdderFn = Error (*)(ControllerInterface &);
|
||||
AdderFn Adders[] = {addSimpleNativeMemoryMap};
|
||||
|
||||
for (auto *Adder : Adders)
|
||||
if (auto Err = Adder(CI))
|
||||
return Err;
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
} // namespace orc_rt::sps_ci
|
||||
101
orc-rt/lib/executor/sps-ci/SimpleNativeMemoryMapSPSCI.cpp
Normal file
101
orc-rt/lib/executor/sps-ci/SimpleNativeMemoryMapSPSCI.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
//===- SimpleNativeMemoryMapSPSCI.cpp -------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// SPS Controller Interface implementation for SimpleNativeMemoryMap.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h"
|
||||
|
||||
#include "orc-rt/SPSAllocAction.h"
|
||||
#include "orc-rt/SPSMemoryFlags.h"
|
||||
#include "orc-rt/SPSWrapperFunction.h"
|
||||
#include "orc-rt/SimpleNativeMemoryMap.h"
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<
|
||||
SPSSimpleNativeMemoryMapSegment,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment> {
|
||||
using SPSType =
|
||||
SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
|
||||
|
||||
public:
|
||||
static bool
|
||||
deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment &S) {
|
||||
AllocGroup AG;
|
||||
ExecutorAddr Address;
|
||||
uint64_t Size;
|
||||
span<const char> Content;
|
||||
if (!SPSType::AsArgList::deserialize(IB, AG, Address, Size, Content))
|
||||
return false;
|
||||
if (Size > std::numeric_limits<size_t>::max())
|
||||
return false;
|
||||
S = {AG, Address.toPtr<char *>(), static_cast<size_t>(Size), Content};
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
SimpleNativeMemoryMap::InitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static bool deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::InitializeRequest &FR) {
|
||||
return SPSType::AsArgList::deserialize(IB, FR.Segments, FR.AAPs);
|
||||
}
|
||||
};
|
||||
|
||||
namespace sps_ci {
|
||||
|
||||
ORC_RT_SPS_WRAPPER(
|
||||
orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper,
|
||||
SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSSize),
|
||||
WrapperFunction::handleWithAsyncMethod(&SimpleNativeMemoryMap::reserve))
|
||||
|
||||
ORC_RT_SPS_WRAPPER(orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper,
|
||||
SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>),
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::releaseMultiple))
|
||||
|
||||
ORC_RT_SPS_WRAPPER(
|
||||
orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper,
|
||||
SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
|
||||
SPSSimpleNativeMemoryMapInitializeRequest),
|
||||
WrapperFunction::handleWithAsyncMethod(&SimpleNativeMemoryMap::initialize))
|
||||
|
||||
ORC_RT_SPS_WRAPPER(
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper,
|
||||
SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>),
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::deinitializeMultiple))
|
||||
|
||||
static std::pair<const char *, const void *>
|
||||
orc_rt_SimpleNativeMemoryMap_sps_interface[] = {
|
||||
ORC_RT_SYMTAB_PAIR(orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper),
|
||||
ORC_RT_SYMTAB_PAIR(
|
||||
orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper),
|
||||
ORC_RT_SYMTAB_PAIR(orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper),
|
||||
ORC_RT_SYMTAB_PAIR(
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper)};
|
||||
|
||||
Error addSimpleNativeMemoryMap(ControllerInterface &CI) {
|
||||
return CI.addSymbolsUnique(orc_rt_SimpleNativeMemoryMap_sps_interface);
|
||||
}
|
||||
|
||||
} // namespace sps_ci
|
||||
} // namespace orc_rt
|
||||
@ -31,6 +31,7 @@ add_orc_rt_unittest(CoreTests
|
||||
ScopeExitTest.cpp
|
||||
SessionTest.cpp
|
||||
SimpleNativeMemoryMapTest.cpp
|
||||
SimpleNativeMemoryMapSPSCITest.cpp
|
||||
SimplePackedSerializationTest.cpp
|
||||
SPSAllocActionTest.cpp
|
||||
SPSMemoryFlagsTest.cpp
|
||||
@ -43,6 +44,7 @@ add_orc_rt_unittest(CoreTests
|
||||
iterator_range-test.cpp
|
||||
move_only_function-test.cpp
|
||||
span-test.cpp
|
||||
|
||||
DISABLE_LLVM_LINK_LLVM_DYLIB
|
||||
)
|
||||
target_compile_options(CoreTests PRIVATE ${ORC_RT_COMPILE_FLAGS})
|
||||
|
||||
@ -9,7 +9,10 @@
|
||||
#ifndef ORC_RT_UNITTEST_COMMONTESTUTILS_H
|
||||
#define ORC_RT_UNITTEST_COMMONTESTUTILS_H
|
||||
|
||||
#include "orc-rt/move_only_function.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <future>
|
||||
|
||||
template <size_t Idx = 0> class OpCounter {
|
||||
public:
|
||||
@ -64,4 +67,17 @@ template <size_t Idx> size_t OpCounter<Idx>::MoveConstructions = 0;
|
||||
template <size_t Idx> size_t OpCounter<Idx>::MoveAssignments = 0;
|
||||
template <size_t Idx> size_t OpCounter<Idx>::Destructions = 0;
|
||||
|
||||
template <typename T>
|
||||
orc_rt::move_only_function<void(T)> waitFor(std::future<T> &F) {
|
||||
std::promise<T> P;
|
||||
F = P.get_future();
|
||||
return [P = std::move(P)](T Val) mutable { P.set_value(std::move(Val)); };
|
||||
}
|
||||
|
||||
inline orc_rt::move_only_function<void()> waitFor(std::future<void> &F) {
|
||||
std::promise<void> P;
|
||||
F = P.get_future();
|
||||
return [P = std::move(P)]() mutable { P.set_value(); };
|
||||
}
|
||||
|
||||
#endif // ORC_RT_UNITTEST_COMMONTESTUTILS_H
|
||||
|
||||
319
orc-rt/unittests/SimpleNativeMemoryMapSPSCITest.cpp
Normal file
319
orc-rt/unittests/SimpleNativeMemoryMapSPSCITest.cpp
Normal file
@ -0,0 +1,319 @@
|
||||
//===- SimpleNativeMemoryMapSPSControllerInterfaceTest.cpp ----------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Tests for SimpleNativeMemoryMap's SPS Controller Interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "orc-rt/sps-ci/SimpleNativeMemoryMapSPSCI.h"
|
||||
#include "orc-rt/SPSAllocAction.h"
|
||||
#include "orc-rt/SPSMemoryFlags.h"
|
||||
#include "orc-rt/SPSWrapperFunction.h"
|
||||
#include "orc-rt/SimpleNativeMemoryMap.h"
|
||||
|
||||
#include "AllocActionTestUtils.h"
|
||||
#include "CommonTestUtils.h"
|
||||
#include "DirectCaller.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace orc_rt;
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
/// A SimpleNativeMemoryMap::InitializeRequest::Segment plus segment content (if
|
||||
/// segment content type is regular).
|
||||
struct TestSNMMSegment
|
||||
: public SimpleNativeMemoryMap::InitializeRequest::Segment {
|
||||
|
||||
TestSNMMSegment(AllocGroup AG, char *Address, size_t Size,
|
||||
std::vector<char> C = {})
|
||||
: SimpleNativeMemoryMap::InitializeRequest::Segment(
|
||||
{AG, Address, Size, {}}),
|
||||
OwnedContent(std::move(C)) {
|
||||
this->Content = {OwnedContent.data(), OwnedContent.size()};
|
||||
}
|
||||
|
||||
std::vector<char> OwnedContent;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapSegment, TestSNMMSegment> {
|
||||
using SPSType =
|
||||
SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
|
||||
|
||||
public:
|
||||
static size_t size(const TestSNMMSegment &S) {
|
||||
return SPSType::AsArgList::size(S.AG, ExecutorAddr::fromPtr(S.Address),
|
||||
static_cast<uint64_t>(S.Size), S.Content);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB, const TestSNMMSegment &S) {
|
||||
return SPSType::AsArgList::serialize(
|
||||
OB, S.AG, ExecutorAddr::fromPtr(S.Address),
|
||||
static_cast<uint64_t>(S.Size), S.Content);
|
||||
}
|
||||
};
|
||||
|
||||
struct TestSNMMInitializeRequest {
|
||||
std::vector<TestSNMMSegment> Segments;
|
||||
std::vector<AllocActionPair> AAPs;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
TestSNMMInitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static size_t size(const TestSNMMInitializeRequest &IR) {
|
||||
return SPSType::AsArgList::size(IR.Segments, IR.AAPs);
|
||||
}
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const TestSNMMInitializeRequest &IR) {
|
||||
return SPSType::AsArgList::serialize(OB, IR.Segments, IR.AAPs);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace orc_rt
|
||||
|
||||
// Write the given value to the address pointed to by P.
|
||||
static orc_rt_WrapperFunctionBuffer
|
||||
write_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
return SPSAllocActionFunction<SPSExecutorAddr, uint64_t>::handle(
|
||||
ArgData, ArgSize,
|
||||
[](ExecutorAddr P, uint64_t Val) {
|
||||
*P.toPtr<uint64_t *>() = Val;
|
||||
return WrapperFunctionBuffer();
|
||||
})
|
||||
.release();
|
||||
}
|
||||
|
||||
// Read the uint64_t value at Src and write it to Dst.
|
||||
static orc_rt_WrapperFunctionBuffer
|
||||
read_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
return SPSAllocActionFunction<SPSExecutorAddr, SPSExecutorAddr>::handle(
|
||||
ArgData, ArgSize,
|
||||
[](ExecutorAddr Dst, ExecutorAddr Src) {
|
||||
*Dst.toPtr<uint64_t *>() = *Src.toPtr<uint64_t *>();
|
||||
return WrapperFunctionBuffer();
|
||||
})
|
||||
.release();
|
||||
}
|
||||
|
||||
class SimpleNativeMemoryMapSPSCITest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
cantFail(sps_ci::addSimpleNativeMemoryMap(CI));
|
||||
SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
if (SNMM) {
|
||||
std::future<void> F;
|
||||
SNMM->onShutdown(waitFor(F));
|
||||
F.get();
|
||||
}
|
||||
}
|
||||
|
||||
DirectCaller caller(const char *Name) {
|
||||
return DirectCaller(nullptr, reinterpret_cast<orc_rt_WrapperFunction>(
|
||||
const_cast<void *>(CI.at(Name))));
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
void spsReserve(OnCompleteFn &&OnComplete, size_t Size) {
|
||||
using SPSSig = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSSize);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
caller("orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper"),
|
||||
std::forward<OnCompleteFn>(OnComplete), SNMM.get(), Size);
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
void spsReleaseMultiple(OnCompleteFn &&OnComplete, span<void *> Addrs) {
|
||||
using SPSSig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
caller("orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper"),
|
||||
std::forward<OnCompleteFn>(OnComplete), SNMM.get(), Addrs);
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
void spsInitialize(OnCompleteFn &&OnComplete, TestSNMMInitializeRequest IR) {
|
||||
using SPSSig = SPSExpected<SPSExecutorAddr>(
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapInitializeRequest);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
caller("orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper"),
|
||||
std::forward<OnCompleteFn>(OnComplete), SNMM.get(), std::move(IR));
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
void spsDeinitializeMultiple(OnCompleteFn &&OnComplete, span<void *> Bases) {
|
||||
using SPSSig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
caller("orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper"),
|
||||
std::forward<OnCompleteFn>(OnComplete), SNMM.get(), Bases);
|
||||
}
|
||||
|
||||
ControllerInterface CI;
|
||||
std::unique_ptr<SimpleNativeMemoryMap> SNMM;
|
||||
};
|
||||
|
||||
TEST_F(SimpleNativeMemoryMapSPSCITest, Registration) {
|
||||
EXPECT_TRUE(CI.count("orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper"));
|
||||
EXPECT_TRUE(
|
||||
CI.count("orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper"));
|
||||
EXPECT_TRUE(CI.count("orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper"));
|
||||
EXPECT_TRUE(CI.count(
|
||||
"orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper"));
|
||||
}
|
||||
|
||||
TEST_F(SimpleNativeMemoryMapSPSCITest, ReserveAndRelease) {
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
spsReserve(waitFor(ReserveAddr), 1024 * 1024 * 1024);
|
||||
auto *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Error>> ReleaseResult;
|
||||
spsReleaseMultiple(waitFor(ReleaseResult), {&Addr, 1});
|
||||
cantFail(cantFail(ReleaseResult.get()));
|
||||
}
|
||||
|
||||
TEST_F(SimpleNativeMemoryMapSPSCITest, FullPipelineForOneRWSegment) {
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
spsReserve(waitFor(ReserveAddr), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue1 = 0;
|
||||
uint64_t SentinelValue2 = 0;
|
||||
uint64_t SentinelValue3 = 42;
|
||||
|
||||
std::vector<char> Content;
|
||||
Content.resize(sizeof(uint64_t) * 2);
|
||||
memcpy(Content.data(), &SentinelValue3, sizeof(uint64_t));
|
||||
memcpy(Content.data() + sizeof(uint64_t), &SentinelValue1, sizeof(uint64_t));
|
||||
|
||||
IR.Segments.push_back({MemProt::Read | MemProt::Write, InitializeBase,
|
||||
64 * 1024, std::move(Content)});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue1),
|
||||
ExecutorAddr::fromPtr(InitializeBase)),
|
||||
{}});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction,
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue2),
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t))});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue3),
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t) * 2),
|
||||
{}});
|
||||
|
||||
spsInitialize(waitFor(InitializeKey), std::move(IR));
|
||||
void *InitializeKeyAddr = cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
EXPECT_EQ(SentinelValue2, 0U);
|
||||
EXPECT_EQ(SentinelValue3, 0U);
|
||||
|
||||
std::future<Expected<Error>> DeallocResult;
|
||||
spsDeinitializeMultiple(waitFor(DeallocResult), {&InitializeKeyAddr, 1});
|
||||
cantFail(cantFail(DeallocResult.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
EXPECT_EQ(SentinelValue2, 42U);
|
||||
EXPECT_EQ(SentinelValue3, 0U);
|
||||
|
||||
std::future<Expected<Error>> ReleaseResult;
|
||||
spsReleaseMultiple(waitFor(ReleaseResult), {&Addr, 1});
|
||||
cantFail(cantFail(ReleaseResult.get()));
|
||||
}
|
||||
|
||||
TEST_F(SimpleNativeMemoryMapSPSCITest, ReserveInitializeShutdown) {
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
spsReserve(waitFor(ReserveAddr), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
IR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(InitializeBase),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
spsInitialize(waitFor(InitializeKey), std::move(IR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
std::future<void> ShutdownResult;
|
||||
SNMM->onShutdown(waitFor(ShutdownResult));
|
||||
ShutdownResult.get();
|
||||
SNMM.reset();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 42);
|
||||
}
|
||||
|
||||
TEST_F(SimpleNativeMemoryMapSPSCITest, ReserveInitializeDetachShutdown) {
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
spsReserve(waitFor(ReserveAddr), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
IR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(InitializeBase),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
spsInitialize(waitFor(InitializeKey), std::move(IR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
std::future<void> DetachResult;
|
||||
SNMM->onDetach(waitFor(DetachResult));
|
||||
DetachResult.get();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0);
|
||||
|
||||
std::future<void> ShutdownResult;
|
||||
SNMM->onShutdown(waitFor(ShutdownResult));
|
||||
ShutdownResult.get();
|
||||
SNMM.reset();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 42);
|
||||
}
|
||||
@ -12,154 +12,15 @@
|
||||
|
||||
#include "orc-rt/SimpleNativeMemoryMap.h"
|
||||
#include "orc-rt/SPSAllocAction.h"
|
||||
#include "orc-rt/SPSMemoryFlags.h"
|
||||
|
||||
#include "AllocActionTestUtils.h"
|
||||
#include "DirectCaller.h"
|
||||
#include "CommonTestUtils.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <future>
|
||||
#include <cstring>
|
||||
|
||||
using namespace orc_rt;
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
|
||||
/// A SimpleNativeMemoryMap::InitializeRequest::Segment plus segment content (if
|
||||
/// segment content type is regular).
|
||||
struct TestSNMMSegment
|
||||
: public SimpleNativeMemoryMap::InitializeRequest::Segment {
|
||||
|
||||
TestSNMMSegment(AllocGroup AG, char *Address, size_t Size,
|
||||
std::vector<char> C = {})
|
||||
: SimpleNativeMemoryMap::InitializeRequest::Segment(
|
||||
{AG, Address, Size, {}}),
|
||||
OwnedContent(std::move(C)) {
|
||||
this->Content = {OwnedContent.data(), OwnedContent.size()};
|
||||
}
|
||||
|
||||
std::vector<char> OwnedContent;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapSegment, TestSNMMSegment> {
|
||||
using SPSType =
|
||||
SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
|
||||
|
||||
public:
|
||||
static size_t size(const TestSNMMSegment &S) {
|
||||
return SPSType::AsArgList::size(S.AG, ExecutorAddr::fromPtr(S.Address),
|
||||
static_cast<uint64_t>(S.Size), S.Content);
|
||||
}
|
||||
|
||||
static bool serialize(SPSOutputBuffer &OB, const TestSNMMSegment &S) {
|
||||
return SPSType::AsArgList::serialize(
|
||||
OB, S.AG, ExecutorAddr::fromPtr(S.Address),
|
||||
static_cast<uint64_t>(S.Size), S.Content);
|
||||
}
|
||||
};
|
||||
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
struct TestSNMMInitializeRequest {
|
||||
std::vector<TestSNMMSegment> Segments;
|
||||
std::vector<AllocActionPair> AAPs;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
TestSNMMInitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static size_t size(const TestSNMMInitializeRequest &IR) {
|
||||
return SPSType::AsArgList::size(IR.Segments, IR.AAPs);
|
||||
}
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const TestSNMMInitializeRequest &IR) {
|
||||
return SPSType::AsArgList::serialize(OB, IR.Segments, IR.AAPs);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace orc_rt
|
||||
|
||||
template <typename T> move_only_function<void(T)> waitFor(std::future<T> &F) {
|
||||
std::promise<T> P;
|
||||
F = P.get_future();
|
||||
return [P = std::move(P)](T Val) mutable { P.set_value(std::move(Val)); };
|
||||
}
|
||||
|
||||
move_only_function<void()> waitFor(std::future<void> &F) {
|
||||
std::promise<void> P;
|
||||
F = P.get_future();
|
||||
return [P = std::move(P)]() mutable { P.set_value(); };
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMapTest, CreateAndDestroy) {
|
||||
// Test that we can create and destroy a SimpleNativeMemoryMap instance as
|
||||
// expected.
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_reserve(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance, size_t Size) {
|
||||
using SPSSig = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr, SPSSize);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
DirectCaller(nullptr, orc_rt_SimpleNativeMemoryMap_reserve_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, Size);
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_releaseMultiple(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
span<void *> Addr) {
|
||||
using SPSSig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
DirectCaller(nullptr,
|
||||
orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, Addr);
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_initialize(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
TestSNMMInitializeRequest IR) {
|
||||
using SPSSig = SPSExpected<SPSExecutorAddr>(
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapInitializeRequest);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
DirectCaller(nullptr,
|
||||
orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, std::move(IR));
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_deinitializeMultiple(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
span<void *> Base) {
|
||||
using SPSSig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
DirectCaller(
|
||||
nullptr,
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, Base);
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMapTest, ReserveAndRelease) {
|
||||
// Test that we can reserve and release a slab of address space as expected,
|
||||
// without finalizing any memory within it.
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
snmm_reserve(waitFor(ReserveAddr), SNMM.get(), 1024 * 1024 * 1024);
|
||||
auto Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Error>> ReleaseResult;
|
||||
snmm_releaseMultiple(waitFor(ReleaseResult), SNMM.get(), {&Addr, 1});
|
||||
cantFail(cantFail(ReleaseResult.get()));
|
||||
}
|
||||
|
||||
// Write the given value to the address pointed to by P.
|
||||
static orc_rt_WrapperFunctionBuffer
|
||||
write_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
@ -173,7 +34,6 @@ write_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
}
|
||||
|
||||
// Read the uint64_t value at Src and write it to Dst.
|
||||
// Increments int via pointer.
|
||||
static orc_rt_WrapperFunctionBuffer
|
||||
read_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
return SPSAllocActionFunction<SPSExecutorAddr, SPSExecutorAddr>::handle(
|
||||
@ -185,7 +45,27 @@ read_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
.release();
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
TEST(SimpleNativeMemoryMapTest, CreateAndDestroy) {
|
||||
// Test that we can create and destroy a SimpleNativeMemoryMap instance as
|
||||
// expected.
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMapTest, ReserveAndRelease) {
|
||||
// Test that we can reserve and release a slab of address space as expected,
|
||||
// without finalizing any memory within it.
|
||||
SimpleNativeMemoryMap SNMM;
|
||||
|
||||
std::future<Expected<void *>> ReserveResult;
|
||||
SNMM.reserve(waitFor(ReserveResult), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(ReserveResult.get());
|
||||
|
||||
std::future<Error> ReleaseResult;
|
||||
SNMM.releaseMultiple(waitFor(ReleaseResult), {Addr});
|
||||
cantFail(ReleaseResult.get());
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMapTest, FullPipelineForOneRWSegment) {
|
||||
// Test that we can:
|
||||
// 1. reserve some address space.
|
||||
// 2. initialize a range within it as read/write, and that finalize actions
|
||||
@ -194,13 +74,12 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
// expected.
|
||||
// 4. release the address range.
|
||||
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
snmm_reserve(waitFor(ReserveAddr), SNMM.get(), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
SimpleNativeMemoryMap SNMM;
|
||||
|
||||
std::future<Expected<void *>> ReserveResult;
|
||||
SNMM.reserve(waitFor(ReserveResult), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(ReserveResult.get());
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = // Initialize addr at non-zero (64kb) offset from base.
|
||||
reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue1 = 0; // Read from pre-filled content
|
||||
@ -214,8 +93,11 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
memcpy(Content.data(), &SentinelValue3, sizeof(uint64_t));
|
||||
memcpy(Content.data() + sizeof(uint64_t), &SentinelValue1, sizeof(uint64_t));
|
||||
|
||||
IR.Segments.push_back({MemProt::Read | MemProt::Write, InitializeBase,
|
||||
64 * 1024, std::move(Content)});
|
||||
SimpleNativeMemoryMap::InitializeRequest IR;
|
||||
IR.Segments.push_back({MemProt::Read | MemProt::Write,
|
||||
InitializeBase,
|
||||
64 * 1024,
|
||||
{Content.data(), Content.size()}});
|
||||
|
||||
// Read initial content into Sentinel 1.
|
||||
IR.AAPs.push_back({
|
||||
@ -243,44 +125,44 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
{} // No dealloc action.
|
||||
});
|
||||
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(IR));
|
||||
void *InitializeKeyAddr = cantFail(cantFail(InitializeKey.get()));
|
||||
std::future<Expected<void *>> InitializeResult;
|
||||
SNMM.initialize(waitFor(InitializeResult), std::move(IR));
|
||||
void *InitializeKeyAddr = cantFail(InitializeResult.get());
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
EXPECT_EQ(SentinelValue2, 0U);
|
||||
EXPECT_EQ(SentinelValue3, 0U);
|
||||
|
||||
std::future<Expected<Error>> DeallocResult;
|
||||
snmm_deinitializeMultiple(waitFor(DeallocResult), SNMM.get(),
|
||||
{&InitializeKeyAddr, 1});
|
||||
cantFail(cantFail(DeallocResult.get()));
|
||||
std::future<Error> DeallocResult;
|
||||
SNMM.deinitializeMultiple(waitFor(DeallocResult), {InitializeKeyAddr});
|
||||
cantFail(DeallocResult.get());
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
EXPECT_EQ(SentinelValue2, 42U);
|
||||
EXPECT_EQ(SentinelValue3, 0U);
|
||||
|
||||
std::future<Expected<Error>> ReleaseResult;
|
||||
snmm_releaseMultiple(waitFor(ReleaseResult), SNMM.get(), {&Addr, 1});
|
||||
cantFail(cantFail(ReleaseResult.get()));
|
||||
std::future<Error> ReleaseResult;
|
||||
SNMM.releaseMultiple(waitFor(ReleaseResult), {Addr});
|
||||
cantFail(ReleaseResult.get());
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMap, ReserveInitializeShutdown) {
|
||||
TEST(SimpleNativeMemoryMapTest, ReserveInitializeShutdown) {
|
||||
// Test that memory is deinitialized in the case where we reserve and
|
||||
// initialize some memory, then just shut down the memory manager.
|
||||
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
snmm_reserve(waitFor(ReserveAddr), SNMM.get(), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
SimpleNativeMemoryMap SNMM;
|
||||
|
||||
std::future<Expected<void *>> ReserveResult;
|
||||
SNMM.reserve(waitFor(ReserveResult), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(ReserveResult.get());
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = // Initialize addr at non-zero (64kb) offset from base.
|
||||
reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
SimpleNativeMemoryMap::InitializeRequest IR;
|
||||
IR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024, {}});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
@ -289,35 +171,37 @@ TEST(SimpleNativeMemoryMap, ReserveInitializeShutdown) {
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(IR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
std::future<Expected<void *>> InitializeResult;
|
||||
SNMM.initialize(waitFor(InitializeResult), std::move(IR));
|
||||
cantFail(InitializeResult.get());
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
std::future<void> ShutdownResult;
|
||||
SNMM->onShutdown(waitFor(ShutdownResult));
|
||||
SNMM.onShutdown(waitFor(ShutdownResult));
|
||||
ShutdownResult.get();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 42);
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMap, ReserveInitializeDetachShutdown) {
|
||||
TEST(SimpleNativeMemoryMapTest, ReserveInitializeDetachShutdown) {
|
||||
// Test that memory is deinitialized in the case where we reserve and
|
||||
// initialize some memory, then just shut down the memory manager.
|
||||
|
||||
auto SNMM = std::make_unique<SimpleNativeMemoryMap>();
|
||||
std::future<Expected<Expected<void *>>> ReserveAddr;
|
||||
snmm_reserve(waitFor(ReserveAddr), SNMM.get(), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
SimpleNativeMemoryMap SNMM;
|
||||
|
||||
std::future<Expected<void *>> ReserveResult;
|
||||
SNMM.reserve(waitFor(ReserveResult), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(ReserveResult.get());
|
||||
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest IR;
|
||||
char *InitializeBase = // Initialize addr at non-zero (64kb) offset from base.
|
||||
reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
SimpleNativeMemoryMap::InitializeRequest IR;
|
||||
IR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024, {}});
|
||||
|
||||
IR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
@ -326,19 +210,21 @@ TEST(SimpleNativeMemoryMap, ReserveInitializeDetachShutdown) {
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(IR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
std::future<Expected<void *>> InitializeResult;
|
||||
SNMM.initialize(waitFor(InitializeResult), std::move(IR));
|
||||
cantFail(InitializeResult.get());
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
std::future<void> DetachResult;
|
||||
SNMM->onDetach(waitFor(DetachResult));
|
||||
SNMM.onDetach(waitFor(DetachResult));
|
||||
DetachResult.get();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0);
|
||||
|
||||
std::future<void> ShutdownResult;
|
||||
SNMM->onShutdown(waitFor(ShutdownResult));
|
||||
SNMM.onShutdown(waitFor(ShutdownResult));
|
||||
ShutdownResult.get();
|
||||
|
||||
EXPECT_EQ(SentinelValue, 42);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user