Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions orc-rt/include/orc-rt/SimpleNativeMemoryMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -58,7 +58,7 @@ class SimpleNativeMemoryMap : public ResourceManager {
void releaseMultiple(OnReleaseCompleteFn &&OnComplete,
std::vector<void *> Addrs);

struct FinalizeRequest {
struct InitializeRequest {
struct Segment {
AllocGroup AG;
char *Address = nullptr;
Expand All @@ -72,19 +72,19 @@ class SimpleNativeMemoryMap : public ResourceManager {

/// 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;
Expand All @@ -98,8 +98,9 @@ class SimpleNativeMemoryMap : public ResourceManager {

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);
Expand All @@ -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);

Expand Down
92 changes: 48 additions & 44 deletions orc-rt/lib/executor/SimpleNativeMemoryMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
//===----------------------------------------------------------------------===//

Expand All @@ -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;
Expand All @@ -50,17 +52,17 @@ class SPSSerializationTraits<SPSSimpleNativeMemoryMapSegment,
}
};

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);
}
};
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
Expand All @@ -182,25 +185,26 @@ 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;

{
std::unique_lock<std::mutex> Lock(M);
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()));
}

Expand All @@ -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) {
Expand Down Expand Up @@ -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));
Expand All @@ -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);
}
Expand Down Expand Up @@ -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());
}

Expand Down Expand Up @@ -383,27 +387,27 @@ 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) {
using Sig = SPSError(SPSExecutorAddr, SPSSequence<SPSExecutorAddr>);
SPSWrapperFunction<Sig>::handle(
Session, CallCtx, Return, ArgBytes,
WrapperFunction::handleWithAsyncMethod(
&SimpleNativeMemoryMap::deallocateMultiple));
&SimpleNativeMemoryMap::deinitializeMultiple));
}

} // namespace orc_rt
Loading
Loading