mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 02:38:07 +08:00
[orc-rt] Rename SimpleNativeMemoryMap finalize & deallocate. NFCI. (#163114)
This commit renames the "finalize" operation to "initialize", and "deallocate" to "deinitialize". The new names are chosen to better fit the point of view of the ORC-runtime and executor-process: After memory is *reserved* it can be *initialized* with some content, and *deinitialized* to return that memory to the reserved region. This seems more understandable to me than the original scheme, which named these operations after the controller-side JITLinkMemoryManager operations that they partially implemented. I.e. SimpleNativeMemoryMap::finalize implemented the final step of JITLinkMemoryManager::finalize, initializing the memory in the executor; and SimpleNativeMemoryMap::deallocate implemented the final step of JITLinkMemoryManager::deallocate, running dealloc actions and releasing the finalized region. The proper way to think of the relationship between these operations now is that: 1. The final step of finalization is to initialize the memory in the executor. 2. The final step of deallocation is to deinitialize the memory in the executor.
This commit is contained in:
@@ -31,13 +31,13 @@ namespace orc_rt {
|
||||
///
|
||||
/// Intances can:
|
||||
/// 1. Reserve address space.
|
||||
/// 2. Finalize memory regions within reserved memory (copying content,
|
||||
/// 2. Initialize memory regions within reserved memory (copying content,
|
||||
/// applying permissions, running finalize actions, and recording
|
||||
/// deallocate actions).
|
||||
/// 3. Deallocate memory regions within reserved memory (running
|
||||
/// 3. Deinitialize memory regions within reserved memory (running
|
||||
/// deallocate actions and making memory available for future
|
||||
/// finalize calls (if the system permits this).
|
||||
/// 4. Release address space, deallocating any not-yet-deallocated finalized
|
||||
/// initialize calls (if the system permits this).
|
||||
/// 4. Release address space, deinitializing any remaining initialized
|
||||
/// regions, and returning the address space to the system for reuse (if
|
||||
/// the system permits).
|
||||
class SimpleNativeMemoryMap : public ResourceManager {
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
void releaseMultiple(OnReleaseCompleteFn &&OnComplete,
|
||||
std::vector<void *> Addrs);
|
||||
|
||||
struct FinalizeRequest {
|
||||
struct InitializeRequest {
|
||||
struct Segment {
|
||||
AllocGroup AG;
|
||||
char *Address = nullptr;
|
||||
@@ -72,19 +72,19 @@ public:
|
||||
|
||||
/// Writes content into the requested ranges, applies permissions, and
|
||||
/// performs allocation actions.
|
||||
using OnFinalizeCompleteFn = move_only_function<void(Expected<void *>)>;
|
||||
void finalize(OnFinalizeCompleteFn &&OnComplete, FinalizeRequest FR);
|
||||
using OnInitializeCompleteFn = move_only_function<void(Expected<void *>)>;
|
||||
void initialize(OnInitializeCompleteFn &&OnComplete, InitializeRequest FR);
|
||||
|
||||
/// Runs deallocation actions and resets memory permissions for the requested
|
||||
/// memory.
|
||||
using OnDeallocateCompleteFn = move_only_function<void(Error)>;
|
||||
void deallocate(OnDeallocateCompleteFn &&OnComplete, void *Base);
|
||||
using OnDeinitializeCompleteFn = move_only_function<void(Error)>;
|
||||
void deinitialize(OnDeinitializeCompleteFn &&OnComplete, void *Base);
|
||||
|
||||
/// Convenience method to deallocate multiple regions with one call. This can
|
||||
/// be used to save on interprocess communication at the cost of less
|
||||
/// Convenience method to deinitialize multiple regions with one call. This
|
||||
/// can be used to save on interprocess communication at the cost of less
|
||||
/// expressive errors.
|
||||
void deallocateMultiple(OnDeallocateCompleteFn &&OnComplete,
|
||||
std::vector<void *> Bases);
|
||||
void deinitializeMultiple(OnDeinitializeCompleteFn &&OnComplete,
|
||||
std::vector<void *> Bases);
|
||||
|
||||
void detach(ResourceManager::OnCompleteFn OnComplete) override;
|
||||
void shutdown(ResourceManager::OnCompleteFn OnComplete) override;
|
||||
@@ -98,8 +98,9 @@ private:
|
||||
|
||||
void releaseNext(OnReleaseCompleteFn &&OnComplete, std::vector<void *> Addrs,
|
||||
bool AnyError, Error LastErr);
|
||||
void deallocateNext(OnDeallocateCompleteFn &&OnComplete,
|
||||
std::vector<void *> Bases, bool AnyError, Error LastErr);
|
||||
void deinitializeNext(OnDeinitializeCompleteFn &&OnComplete,
|
||||
std::vector<void *> Bases, bool AnyError,
|
||||
Error LastErr);
|
||||
void shutdownNext(OnCompleteFn OnComplete, std::vector<void *> Bases);
|
||||
Error makeBadSlabError(void *Base, const char *Op);
|
||||
SlabInfo *findSlabInfoFor(void *Base);
|
||||
@@ -121,12 +122,12 @@ orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef Session, void *CallCtx,
|
||||
orc_rt_WrapperFunctionReturn Return, orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_finalize_sps_wrapper(
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper(
|
||||
orc_rt_SessionRef Session, void *CallCtx,
|
||||
orc_rt_WrapperFunctionReturn Return, orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_deallocateMultiple_sps_wrapper(
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef Session, void *CallCtx,
|
||||
orc_rt_WrapperFunctionReturn Return, orc_rt_WrapperFunctionBuffer ArgBytes);
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
//
|
||||
// SimpleNativeMemoryMap and related APIs.
|
||||
//
|
||||
// TODO: We don't reset / uncommit pages on deallocate, or on failure during
|
||||
// finalize. We should do that to reduce memory pressure.
|
||||
// TODO: We don't reset / uncommit pages on deinitialize, or on failure during
|
||||
// initialize. We should do that to reduce memory pressure.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -29,14 +29,16 @@ namespace orc_rt {
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapSegment,
|
||||
SimpleNativeMemoryMap::FinalizeRequest::Segment> {
|
||||
class SPSSerializationTraits<
|
||||
SPSSimpleNativeMemoryMapSegment,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment> {
|
||||
using SPSType =
|
||||
SPSTuple<SPSAllocGroup, SPSExecutorAddr, uint64_t, SPSSequence<char>>;
|
||||
|
||||
public:
|
||||
static bool deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::FinalizeRequest::Segment &S) {
|
||||
static bool
|
||||
deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::InitializeRequest::Segment &S) {
|
||||
AllocGroup AG;
|
||||
ExecutorAddr Address;
|
||||
uint64_t Size;
|
||||
@@ -50,17 +52,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct SPSSimpleNativeMemoryMapFinalizeRequest;
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapFinalizeRequest,
|
||||
SimpleNativeMemoryMap::FinalizeRequest> {
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
SimpleNativeMemoryMap::InitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static bool deserialize(SPSInputBuffer &IB,
|
||||
SimpleNativeMemoryMap::FinalizeRequest &FR) {
|
||||
SimpleNativeMemoryMap::InitializeRequest &FR) {
|
||||
return SPSType::AsArgList::deserialize(IB, FR.Segments, FR.AAPs);
|
||||
}
|
||||
};
|
||||
@@ -121,13 +123,13 @@ void SimpleNativeMemoryMap::releaseMultiple(OnReleaseCompleteFn &&OnComplete,
|
||||
releaseNext(std::move(OnComplete), std::move(Addrs), false, Error::success());
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::finalize(OnFinalizeCompleteFn &&OnComplete,
|
||||
FinalizeRequest FR) {
|
||||
void SimpleNativeMemoryMap::initialize(OnInitializeCompleteFn &&OnComplete,
|
||||
InitializeRequest FR) {
|
||||
|
||||
void *Base = nullptr;
|
||||
|
||||
// TODO: Record finalize segments for release.
|
||||
// std::vector<std::pair<void*, size_t>> FinalizeSegments;
|
||||
// TODO: Record initialize segments for release.
|
||||
// std::vector<std::pair<void*, size_t>> InitializeSegments;
|
||||
|
||||
// Check segment validity before proceeding.
|
||||
for (auto &S : FR.Segments) {
|
||||
@@ -166,9 +168,10 @@ void SimpleNativeMemoryMap::finalize(OnFinalizeCompleteFn &&OnComplete,
|
||||
}
|
||||
|
||||
if (!Base)
|
||||
return OnComplete(make_error<StringError>(
|
||||
"SimpleNativeMemoryMap finalize error: finalization requires at least "
|
||||
"one standard-lifetime segment"));
|
||||
return OnComplete(
|
||||
make_error<StringError>("SimpleNativeMemoryMap initialize error: "
|
||||
"finalization requires at least "
|
||||
"one standard-lifetime segment"));
|
||||
|
||||
auto DeallocActions = runFinalizeActions(std::move(FR.AAPs));
|
||||
if (!DeallocActions)
|
||||
@@ -182,8 +185,8 @@ void SimpleNativeMemoryMap::finalize(OnFinalizeCompleteFn &&OnComplete,
|
||||
OnComplete(Base);
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::deallocate(OnDeallocateCompleteFn &&OnComplete,
|
||||
void *Base) {
|
||||
void SimpleNativeMemoryMap::deinitialize(OnDeinitializeCompleteFn &&OnComplete,
|
||||
void *Base) {
|
||||
std::vector<AllocAction> DAAs;
|
||||
|
||||
{
|
||||
@@ -191,16 +194,17 @@ void SimpleNativeMemoryMap::deallocate(OnDeallocateCompleteFn &&OnComplete,
|
||||
auto *SI = findSlabInfoFor(Base);
|
||||
if (!SI) {
|
||||
Lock.unlock();
|
||||
return OnComplete(makeBadSlabError(Base, "finalize"));
|
||||
return OnComplete(makeBadSlabError(Base, "deinitialize"));
|
||||
}
|
||||
|
||||
auto I = SI->DeallocActions.find(Base);
|
||||
if (I == SI->DeallocActions.end()) {
|
||||
Lock.unlock();
|
||||
std::ostringstream ErrMsg;
|
||||
ErrMsg << "SimpleNativeMemoryMap deallocate error: no deallocate actions "
|
||||
"registered for segment base address "
|
||||
<< Base;
|
||||
ErrMsg
|
||||
<< "SimpleNativeMemoryMap deinitialize error: no deallocate actions "
|
||||
"registered for segment base address "
|
||||
<< Base;
|
||||
return OnComplete(make_error<StringError>(ErrMsg.str()));
|
||||
}
|
||||
|
||||
@@ -212,10 +216,10 @@ void SimpleNativeMemoryMap::deallocate(OnDeallocateCompleteFn &&OnComplete,
|
||||
OnComplete(Error::success());
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::deallocateMultiple(
|
||||
OnDeallocateCompleteFn &&OnComplete, std::vector<void *> Bases) {
|
||||
deallocateNext(std::move(OnComplete), std::move(Bases), false,
|
||||
Error::success());
|
||||
void SimpleNativeMemoryMap::deinitializeMultiple(
|
||||
OnDeinitializeCompleteFn &&OnComplete, std::vector<void *> Bases) {
|
||||
deinitializeNext(std::move(OnComplete), std::move(Bases), false,
|
||||
Error::success());
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::detach(ResourceManager::OnCompleteFn OnComplete) {
|
||||
@@ -268,9 +272,9 @@ void SimpleNativeMemoryMap::releaseNext(OnReleaseCompleteFn &&OnComplete,
|
||||
NextAddr);
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::deallocateNext(OnDeallocateCompleteFn &&OnComplete,
|
||||
std::vector<void *> Addrs,
|
||||
bool AnyError, Error LastErr) {
|
||||
void SimpleNativeMemoryMap::deinitializeNext(
|
||||
OnDeinitializeCompleteFn &&OnComplete, std::vector<void *> Addrs,
|
||||
bool AnyError, Error LastErr) {
|
||||
// TODO: Log error?
|
||||
if (LastErr) {
|
||||
consumeError(std::move(LastErr));
|
||||
@@ -282,17 +286,17 @@ void SimpleNativeMemoryMap::deallocateNext(OnDeallocateCompleteFn &&OnComplete,
|
||||
return OnComplete(Error::success());
|
||||
|
||||
return OnComplete(
|
||||
make_error<StringError>("Failed to deallocate some addresses"));
|
||||
make_error<StringError>("Failed to deinitialize some addresses"));
|
||||
}
|
||||
|
||||
void *NextAddr = Addrs.back();
|
||||
Addrs.pop_back();
|
||||
|
||||
deallocate(
|
||||
deinitialize(
|
||||
[this, OnComplete = std::move(OnComplete), AnyError = AnyError,
|
||||
Addrs = std::move(Addrs)](Error Err) mutable {
|
||||
deallocateNext(std::move(OnComplete), std::move(Addrs), AnyError,
|
||||
std::move(Err));
|
||||
deinitializeNext(std::move(OnComplete), std::move(Addrs), AnyError,
|
||||
std::move(Err));
|
||||
},
|
||||
NextAddr);
|
||||
}
|
||||
@@ -346,15 +350,15 @@ Error SimpleNativeMemoryMap::recordDeallocActions(
|
||||
auto *SI = findSlabInfoFor(Base);
|
||||
if (!SI) {
|
||||
Lock.unlock();
|
||||
return makeBadSlabError(Base, "deallocate");
|
||||
return makeBadSlabError(Base, "deinitialize");
|
||||
}
|
||||
|
||||
auto I = SI->DeallocActions.find(Base);
|
||||
if (I != SI->DeallocActions.end()) {
|
||||
Lock.unlock();
|
||||
std::ostringstream ErrMsg;
|
||||
ErrMsg << "SimpleNativeMemoryMap finalize error: segment base address "
|
||||
"reused in subsequent finalize call";
|
||||
ErrMsg << "SimpleNativeMemoryMap initialize error: segment base address "
|
||||
"reused in subsequent initialize call";
|
||||
return make_error<StringError>(ErrMsg.str());
|
||||
}
|
||||
|
||||
@@ -383,19 +387,19 @@ orc_rt_SimpleNativeMemoryMap_releaseMultiple_sps_wrapper(
|
||||
&SimpleNativeMemoryMap::releaseMultiple));
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_finalize_sps_wrapper(
|
||||
ORC_RT_SPS_INTERFACE void orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper(
|
||||
orc_rt_SessionRef Session, void *CallCtx,
|
||||
orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
using Sig = SPSExpected<SPSExecutorAddr>(
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapFinalizeRequest);
|
||||
SPSWrapperFunction<Sig>::handle(
|
||||
Session, CallCtx, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(&SimpleNativeMemoryMap::finalize));
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapInitializeRequest);
|
||||
SPSWrapperFunction<Sig>::handle(Session, CallCtx, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::initialize));
|
||||
}
|
||||
|
||||
ORC_RT_SPS_INTERFACE void
|
||||
orc_rt_SimpleNativeMemoryMap_deallocateMultiple_sps_wrapper(
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper(
|
||||
orc_rt_SessionRef Session, void *CallCtx,
|
||||
orc_rt_WrapperFunctionReturn Return,
|
||||
orc_rt_WrapperFunctionBuffer ArgBytes) {
|
||||
@@ -403,7 +407,7 @@ orc_rt_SimpleNativeMemoryMap_deallocateMultiple_sps_wrapper(
|
||||
SPSWrapperFunction<Sig>::handle(
|
||||
Session, CallCtx, Return, ArgBytes,
|
||||
WrapperFunction::handleWithAsyncMethod(
|
||||
&SimpleNativeMemoryMap::deallocateMultiple));
|
||||
&SimpleNativeMemoryMap::deinitializeMultiple));
|
||||
}
|
||||
|
||||
} // namespace orc_rt
|
||||
|
||||
@@ -26,14 +26,14 @@ namespace orc_rt {
|
||||
|
||||
struct SPSSimpleNativeMemoryMapSegment;
|
||||
|
||||
/// A SimpleNativeMemoryMap::FinalizeRequest::Segment plus segment content (if
|
||||
/// A SimpleNativeMemoryMap::InitializeRequest::Segment plus segment content (if
|
||||
/// segment content type is regular).
|
||||
struct TestSNMMSegment
|
||||
: public SimpleNativeMemoryMap::FinalizeRequest::Segment {
|
||||
: public SimpleNativeMemoryMap::InitializeRequest::Segment {
|
||||
|
||||
TestSNMMSegment(AllocGroup AG, char *Address, size_t Size,
|
||||
std::vector<char> C = {})
|
||||
: SimpleNativeMemoryMap::FinalizeRequest::Segment(
|
||||
: SimpleNativeMemoryMap::InitializeRequest::Segment(
|
||||
{AG, Address, Size, {}}),
|
||||
OwnedContent(std::move(C)) {
|
||||
this->Content = {OwnedContent.data(), OwnedContent.size()};
|
||||
@@ -60,25 +60,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct SPSSimpleNativeMemoryMapFinalizeRequest;
|
||||
struct SPSSimpleNativeMemoryMapInitializeRequest;
|
||||
|
||||
struct TestSNMMFinalizeRequest {
|
||||
struct TestSNMMInitializeRequest {
|
||||
std::vector<TestSNMMSegment> Segments;
|
||||
std::vector<AllocActionPair> AAPs;
|
||||
};
|
||||
|
||||
template <>
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapFinalizeRequest,
|
||||
TestSNMMFinalizeRequest> {
|
||||
class SPSSerializationTraits<SPSSimpleNativeMemoryMapInitializeRequest,
|
||||
TestSNMMInitializeRequest> {
|
||||
using SPSType = SPSTuple<SPSSequence<SPSSimpleNativeMemoryMapSegment>,
|
||||
SPSSequence<SPSAllocActionPair>>;
|
||||
|
||||
public:
|
||||
static size_t size(const TestSNMMFinalizeRequest &FR) {
|
||||
static size_t size(const TestSNMMInitializeRequest &FR) {
|
||||
return SPSType::AsArgList::size(FR.Segments, FR.AAPs);
|
||||
}
|
||||
static bool serialize(SPSOutputBuffer &OB,
|
||||
const TestSNMMFinalizeRequest &FR) {
|
||||
const TestSNMMInitializeRequest &FR) {
|
||||
return SPSType::AsArgList::serialize(OB, FR.Segments, FR.AAPs);
|
||||
}
|
||||
};
|
||||
@@ -118,24 +118,26 @@ static void snmm_releaseMultiple(OnCompleteFn &&OnComplete,
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_finalize(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
TestSNMMFinalizeRequest FR) {
|
||||
static void snmm_initialize(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
TestSNMMInitializeRequest FR) {
|
||||
using SPSSig = SPSExpected<SPSExecutorAddr>(
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapFinalizeRequest);
|
||||
SPSExecutorAddr, SPSSimpleNativeMemoryMapInitializeRequest);
|
||||
SPSWrapperFunction<SPSSig>::call(
|
||||
DirectCaller(nullptr, orc_rt_SimpleNativeMemoryMap_finalize_sps_wrapper),
|
||||
DirectCaller(nullptr,
|
||||
orc_rt_SimpleNativeMemoryMap_initialize_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, std::move(FR));
|
||||
}
|
||||
|
||||
template <typename OnCompleteFn>
|
||||
static void snmm_deallocateMultiple(OnCompleteFn &&OnComplete,
|
||||
SimpleNativeMemoryMap *Instance,
|
||||
span<void *> Base) {
|
||||
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_deallocateMultiple_sps_wrapper),
|
||||
DirectCaller(
|
||||
nullptr,
|
||||
orc_rt_SimpleNativeMemoryMap_deinitializeMultiple_sps_wrapper),
|
||||
std::forward<OnCompleteFn>(OnComplete), Instance, Base);
|
||||
}
|
||||
|
||||
@@ -180,9 +182,9 @@ read_value_sps_allocaction(const char *ArgData, size_t ArgSize) {
|
||||
TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
// Test that we can:
|
||||
// 1. reserve some address space.
|
||||
// 2. finalize a range within it as read/write, and that finalize actions
|
||||
// 2. initialize a range within it as read/write, and that finalize actions
|
||||
// are applied as expected.
|
||||
// 3. deallocate the finalized range, with deallocation actions applied as
|
||||
// 3. deinitialize the initialized range, with deallocation actions applied as
|
||||
// expected.
|
||||
// 4. release the address range.
|
||||
|
||||
@@ -191,12 +193,13 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
snmm_reserve(waitFor(ReserveAddr), SNMM.get(), 1024 * 1024 * 1024);
|
||||
void *Addr = cantFail(cantFail(ReserveAddr.get()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> FinalizeKey;
|
||||
TestSNMMFinalizeRequest FR;
|
||||
char *FinalizeBase = // Finalize addr at non-zero (64kb) offset from base.
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest FR;
|
||||
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
|
||||
uint64_t SentinelValue2 = 0; // Written in finalize, read back during dealloc.
|
||||
uint64_t SentinelValue2 =
|
||||
0; // Written in initialize, read back during dealloc.
|
||||
uint64_t SentinelValue3 = 42; // Read from zero-filled region.
|
||||
|
||||
// Build initial content vector.
|
||||
@@ -205,14 +208,14 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
memcpy(Content.data(), &SentinelValue3, sizeof(uint64_t));
|
||||
memcpy(Content.data() + sizeof(uint64_t), &SentinelValue1, sizeof(uint64_t));
|
||||
|
||||
FR.Segments.push_back({MemProt::Read | MemProt::Write, FinalizeBase,
|
||||
FR.Segments.push_back({MemProt::Read | MemProt::Write, InitializeBase,
|
||||
64 * 1024, std::move(Content)});
|
||||
|
||||
// Read initial content into Sentinel 1.
|
||||
FR.AAPs.push_back({
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue1),
|
||||
ExecutorAddr::fromPtr(FinalizeBase)),
|
||||
ExecutorAddr::fromPtr(InitializeBase)),
|
||||
{} // No dealloc action.
|
||||
});
|
||||
|
||||
@@ -220,30 +223,30 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
FR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction,
|
||||
ExecutorAddr::fromPtr(FinalizeBase) + sizeof(uint64_t),
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue2),
|
||||
ExecutorAddr::fromPtr(FinalizeBase) + sizeof(uint64_t))});
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t))});
|
||||
|
||||
// Read first 64 bits of the zero-fill region.
|
||||
FR.AAPs.push_back({
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue3),
|
||||
ExecutorAddr::fromPtr(FinalizeBase) + sizeof(uint64_t) * 2),
|
||||
ExecutorAddr::fromPtr(InitializeBase) + sizeof(uint64_t) * 2),
|
||||
{} // No dealloc action.
|
||||
});
|
||||
|
||||
snmm_finalize(waitFor(FinalizeKey), SNMM.get(), std::move(FR));
|
||||
void *FinalizeKeyAddr = cantFail(cantFail(FinalizeKey.get()));
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(FR));
|
||||
void *InitializeKeyAddr = cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
EXPECT_EQ(SentinelValue2, 0U);
|
||||
EXPECT_EQ(SentinelValue3, 0U);
|
||||
|
||||
std::future<Expected<Error>> DeallocResult;
|
||||
snmm_deallocateMultiple(waitFor(DeallocResult), SNMM.get(),
|
||||
{&FinalizeKeyAddr, 1});
|
||||
snmm_deinitializeMultiple(waitFor(DeallocResult), SNMM.get(),
|
||||
{&InitializeKeyAddr, 1});
|
||||
cantFail(cantFail(DeallocResult.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue1, 42U);
|
||||
@@ -255,33 +258,33 @@ TEST(SimpleNativeMemoryMap, FullPipelineForOneRWSegment) {
|
||||
cantFail(cantFail(ReleaseResult.get()));
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMap, ReserveFinalizeShutdown) {
|
||||
// Test that memory is deallocated in the case where we reserve and finalize
|
||||
// some memory, then just shut down the memory manager.
|
||||
TEST(SimpleNativeMemoryMap, 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()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> FinalizeKey;
|
||||
TestSNMMFinalizeRequest FR;
|
||||
char *FinalizeBase = // Finalize addr at non-zero (64kb) offset from base.
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest FR;
|
||||
char *InitializeBase = // Initialize addr at non-zero (64kb) offset from base.
|
||||
reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
FR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, FinalizeBase, 64 * 1024});
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
|
||||
FR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(FinalizeBase),
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(InitializeBase),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(FinalizeBase))});
|
||||
snmm_finalize(waitFor(FinalizeKey), SNMM.get(), std::move(FR));
|
||||
cantFail(cantFail(FinalizeKey.get()));
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(FR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
@@ -292,33 +295,33 @@ TEST(SimpleNativeMemoryMap, ReserveFinalizeShutdown) {
|
||||
EXPECT_EQ(SentinelValue, 42);
|
||||
}
|
||||
|
||||
TEST(SimpleNativeMemoryMap, ReserveFinalizeDetachShutdown) {
|
||||
// Test that memory is deallocated in the case where we reserve and finalize
|
||||
// some memory, then just shut down the memory manager.
|
||||
TEST(SimpleNativeMemoryMap, 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()));
|
||||
|
||||
std::future<Expected<Expected<void *>>> FinalizeKey;
|
||||
TestSNMMFinalizeRequest FR;
|
||||
char *FinalizeBase = // Finalize addr at non-zero (64kb) offset from base.
|
||||
std::future<Expected<Expected<void *>>> InitializeKey;
|
||||
TestSNMMInitializeRequest FR;
|
||||
char *InitializeBase = // Initialize addr at non-zero (64kb) offset from base.
|
||||
reinterpret_cast<char *>(Addr) + 64 * 1024;
|
||||
uint64_t SentinelValue = 0;
|
||||
|
||||
FR.Segments.push_back(
|
||||
{MemProt::Read | MemProt::Write, FinalizeBase, 64 * 1024});
|
||||
{MemProt::Read | MemProt::Write, InitializeBase, 64 * 1024});
|
||||
|
||||
FR.AAPs.push_back(
|
||||
{*MakeAllocAction<SPSExecutorAddr, uint64_t>::from(
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(FinalizeBase),
|
||||
write_value_sps_allocaction, ExecutorAddr::fromPtr(InitializeBase),
|
||||
uint64_t(42)),
|
||||
*MakeAllocAction<SPSExecutorAddr, SPSExecutorAddr>::from(
|
||||
read_value_sps_allocaction, ExecutorAddr::fromPtr(&SentinelValue),
|
||||
ExecutorAddr::fromPtr(FinalizeBase))});
|
||||
snmm_finalize(waitFor(FinalizeKey), SNMM.get(), std::move(FR));
|
||||
cantFail(cantFail(FinalizeKey.get()));
|
||||
ExecutorAddr::fromPtr(InitializeBase))});
|
||||
snmm_initialize(waitFor(InitializeKey), SNMM.get(), std::move(FR));
|
||||
cantFail(cantFail(InitializeKey.get()));
|
||||
|
||||
EXPECT_EQ(SentinelValue, 0U);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user