[orc-rt] Rename "ResourceManager" to "Service". NFCI. (#186639)
The name "Service" better reflects the general purpose of this class: It provides *something* (often resource management) to the Session, is owned by the Session, and receives notifications from the Session when the controller detaches / is detached, and when the Session is shut down. An example of a non-resource-managing Service (to be added in an upcoming patch) is a detach / shutdown notification service: Clients can add this service to register arbitrary callbacks to be run on detach / shutdown. The advantage of this over the current Session detach / shutdown callback system is that clients can control both the order of the callbacks, and their order relative to notification of other services.
This commit is contained in:
parent
3fea2f6165
commit
96e7fc2c9a
@ -21,8 +21,8 @@ process.
|
||||
### Session
|
||||
|
||||
The Session object is the root object for a JIT'd program. It owns the
|
||||
ResourceManager instances that manage resources supporting JIT'd code (e.g.
|
||||
JIT'd memory, unwind info registrations, dynamic library handles, etc.).
|
||||
Service instances that manage services and resources supporting JIT'd code
|
||||
(e.g. JIT'd memory, unwind info registrations, dynamic library handles, etc.).
|
||||
|
||||
The Session object must be constructed prior to adding any JIT'd code, and must
|
||||
outlive execution of any JIT'd code.
|
||||
@ -50,16 +50,17 @@ ControllerAccess objects may be detached before the session ends, at which point
|
||||
JIT'd code may continue executing, but will receive no further calls from the
|
||||
controller and can make no further calls to the controller.
|
||||
|
||||
### ResourceManager
|
||||
### Service
|
||||
|
||||
`ResourceManager` is an interface for classes that manage resources that support
|
||||
a JIT'd program, for example memory or loaded dylib handles. It provides two
|
||||
operations: `detach` and `shutdown`. The `shutdown` operation will be called at
|
||||
`Session` destruction time. The `detach` operation may be called if the
|
||||
controller detaches: since this means that no further requests for resource
|
||||
allocation or release will occur prior to the end of the Session
|
||||
ResourceManagers may implement this operation to abandon any fine-grained
|
||||
tracking or pre-reserved resources (e.g. address space).
|
||||
`Service` is an interface for classes that provide services to the Session.
|
||||
E.g. memory managers, or dynamic library loaders.
|
||||
|
||||
The `Service` interface provides two operations: `detach` and `shutdown`. The
|
||||
`shutdown` operation will be called at `Session` destruction time. The `detach`
|
||||
operation will be called if the controller detaches. Since this means that no
|
||||
further requests for service will be made by the controller, Services may
|
||||
implement this operation to abandon any fine-grained book-keeping that is
|
||||
needed to provide ongoing services to the controller.
|
||||
|
||||
### TaskDispatcher
|
||||
|
||||
|
||||
@ -14,9 +14,9 @@ set(ORC_RT_HEADERS
|
||||
orc-rt/Math.h
|
||||
orc-rt/MemoryFlags.h
|
||||
orc-rt/QueueingTaskDispatcher.h
|
||||
orc-rt/ResourceManager.h
|
||||
orc-rt/RTTI.h
|
||||
orc-rt/ScopeExit.h
|
||||
orc-rt/Service.h
|
||||
orc-rt/Session.h
|
||||
orc-rt/SimpleNativeMemoryMap.h
|
||||
orc-rt/SimplePackedSerialization.h
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//===- ResourceManager.h -- Interface for JIT resource managers -*- C++ -*-===//
|
||||
//===-------- Service.h - Interface for Session Services --------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -6,39 +6,42 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// ResourceManager class and related APIs.
|
||||
// Service class and related APIs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ORC_RT_RESOURCEMANAGER_H
|
||||
#define ORC_RT_RESOURCEMANAGER_H
|
||||
#ifndef ORC_RT_SERVICE_H
|
||||
#define ORC_RT_SERVICE_H
|
||||
|
||||
#include "orc-rt/Error.h"
|
||||
#include "orc-rt/move_only_function.h"
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
/// A ResourceManager manages resources (e.g. JIT'd memory) to support a JIT
|
||||
/// session.
|
||||
class ResourceManager {
|
||||
/// A Service typically manages some resource(s) or performs some actions on
|
||||
/// behalf of a Session. E.g. a Memory Manager service.
|
||||
/// Services are owned by the Session and notified when the controller
|
||||
/// detaches, and when the Session shuts down.
|
||||
class Service {
|
||||
public:
|
||||
using OnCompleteFn = move_only_function<void(Error)>;
|
||||
|
||||
virtual ~ResourceManager();
|
||||
virtual ~Service();
|
||||
|
||||
/// The onDetach method will be called if the controller disconnects from the
|
||||
/// session without shutting the session down.
|
||||
///
|
||||
/// Since no further requests for allocation will be made, the ResourceManager
|
||||
/// may discard any book-keeping data-structures used to support allocation.
|
||||
/// E.g. a JIT memory manager may discard its free-list, since no further
|
||||
/// JIT'd allocations will happen.
|
||||
/// Since no further requests to the Service will be made, the Service may
|
||||
/// discard any book-keeping data-structures that are only needed to serve
|
||||
/// ongoing requests. E.g. a JIT memory manager may discard its free-list,
|
||||
/// since no further JIT'd allocations will happen.
|
||||
virtual void onDetach(OnCompleteFn OnComplete) = 0;
|
||||
|
||||
/// The onShutdown operation will be called at the end of the session.
|
||||
/// The ResourceManager should release all held resources.
|
||||
///
|
||||
/// The Service should release any held resources.
|
||||
virtual void onShutdown(OnCompleteFn OnComplete) = 0;
|
||||
};
|
||||
} // namespace orc_rt
|
||||
|
||||
#endif // ORC_RT_RESOURCEMANAGER_H
|
||||
#endif // ORC_RT_SERVICE_H
|
||||
@ -14,7 +14,7 @@
|
||||
#define ORC_RT_SESSION_H
|
||||
|
||||
#include "orc-rt/Error.h"
|
||||
#include "orc-rt/ResourceManager.h"
|
||||
#include "orc-rt/Service.h"
|
||||
#include "orc-rt/TaskDispatcher.h"
|
||||
#include "orc-rt/WrapperFunction.h"
|
||||
#include "orc-rt/move_only_function.h"
|
||||
@ -142,8 +142,8 @@ public:
|
||||
/// Initiate session shutdown and block until complete.
|
||||
void waitForShutdown();
|
||||
|
||||
/// Add a ResourceManager to the session.
|
||||
void addResourceManager(std::unique_ptr<ResourceManager> RM);
|
||||
/// Add a Service to the session.
|
||||
void addService(std::unique_ptr<Service> Srv);
|
||||
|
||||
/// Set the ControllerAccess object.
|
||||
void setController(std::shared_ptr<ControllerAccess> CA);
|
||||
@ -163,7 +163,7 @@ public:
|
||||
private:
|
||||
struct ShutdownInfo {
|
||||
bool Complete = false;
|
||||
std::vector<std::unique_ptr<ResourceManager>> ResourceMgrs;
|
||||
std::vector<std::unique_ptr<Service>> Services;
|
||||
std::vector<OnShutdownCompleteFn> OnCompletes;
|
||||
};
|
||||
|
||||
@ -190,7 +190,7 @@ private:
|
||||
ErrorReporterFn ReportError;
|
||||
|
||||
std::mutex M;
|
||||
std::vector<std::unique_ptr<ResourceManager>> ResourceMgrs;
|
||||
std::vector<std::unique_ptr<Service>> Services;
|
||||
std::unique_ptr<ShutdownInfo> SI;
|
||||
};
|
||||
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
#include "orc-rt/AllocAction.h"
|
||||
#include "orc-rt/Error.h"
|
||||
#include "orc-rt/MemoryFlags.h"
|
||||
#include "orc-rt/ResourceManager.h"
|
||||
#include "orc-rt/SPSWrapperFunction.h"
|
||||
#include "orc-rt/Service.h"
|
||||
#include "orc-rt/move_only_function.h"
|
||||
|
||||
#include <map>
|
||||
@ -40,7 +40,7 @@ namespace orc_rt {
|
||||
/// 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 {
|
||||
class SimpleNativeMemoryMap : public Service {
|
||||
public:
|
||||
/// Reserves a slab of contiguous address space for allocation.
|
||||
///
|
||||
@ -86,8 +86,8 @@ public:
|
||||
void deinitializeMultiple(OnDeinitializeCompleteFn &&OnComplete,
|
||||
std::vector<void *> Bases);
|
||||
|
||||
void onDetach(ResourceManager::OnCompleteFn OnComplete) override;
|
||||
void onShutdown(ResourceManager::OnCompleteFn OnComplete) override;
|
||||
void onDetach(Service::OnCompleteFn OnComplete) override;
|
||||
void onShutdown(Service::OnCompleteFn OnComplete) override;
|
||||
|
||||
private:
|
||||
struct SlabInfo {
|
||||
|
||||
@ -2,8 +2,8 @@ set(files
|
||||
AllocAction.cpp
|
||||
Error.cpp
|
||||
QueueingTaskDispatcher.cpp
|
||||
ResourceManager.cpp
|
||||
RTTI.cpp
|
||||
Service.cpp
|
||||
Session.cpp
|
||||
SimpleNativeMemoryMap.cpp
|
||||
TaskDispatcher.cpp
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//===- ResourceManager.cpp ------------------------------------------------===//
|
||||
//===- Service.cpp --------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
@ -6,14 +6,14 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Contains the implementation of APIs in the orc-rt/ResourceManager.h header.
|
||||
// Contains the implementation of APIs in the orc-rt/Service.h header.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "orc-rt/ResourceManager.h"
|
||||
#include "orc-rt/Service.h"
|
||||
|
||||
namespace orc_rt {
|
||||
|
||||
ResourceManager::~ResourceManager() = default;
|
||||
Service::~Service() = default;
|
||||
|
||||
} // namespace orc_rt
|
||||
@ -40,7 +40,7 @@ void Session::shutdown(OnShutdownCompleteFn OnShutdownComplete) {
|
||||
// callbacks, then call shutdownNext below (outside the lock).
|
||||
SI = std::make_unique<ShutdownInfo>();
|
||||
SI->OnCompletes.push_back(std::move(OnShutdownComplete));
|
||||
std::swap(SI->ResourceMgrs, ResourceMgrs);
|
||||
std::swap(SI->Services, Services);
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,10 +63,10 @@ void Session::waitForShutdown() {
|
||||
F.get();
|
||||
}
|
||||
|
||||
void Session::addResourceManager(std::unique_ptr<ResourceManager> RM) {
|
||||
void Session::addService(std::unique_ptr<Service> Srv) {
|
||||
std::scoped_lock<std::mutex> Lock(M);
|
||||
assert(!SI && "addResourceManager called after shutdown");
|
||||
ResourceMgrs.push_back(std::move(RM));
|
||||
assert(!SI && "addService called after shutdown");
|
||||
Services.push_back(std::move(Srv));
|
||||
}
|
||||
|
||||
void Session::setController(std::shared_ptr<ControllerAccess> CA) {
|
||||
@ -88,13 +88,13 @@ void Session::shutdownNext(Error Err) {
|
||||
if (Err)
|
||||
reportError(std::move(Err));
|
||||
|
||||
if (SI->ResourceMgrs.empty())
|
||||
if (SI->Services.empty())
|
||||
return shutdownComplete();
|
||||
|
||||
// Get the next ResourceManager to shut down.
|
||||
auto NextRM = std::move(SI->ResourceMgrs.back());
|
||||
SI->ResourceMgrs.pop_back();
|
||||
NextRM->onShutdown([this](Error Err) { shutdownNext(std::move(Err)); });
|
||||
// Get the next Service to shut down.
|
||||
auto NextSrv = std::move(SI->Services.back());
|
||||
SI->Services.pop_back();
|
||||
NextSrv->onShutdown([this](Error Err) { shutdownNext(std::move(Err)); });
|
||||
}
|
||||
|
||||
void Session::shutdownComplete() {
|
||||
|
||||
@ -222,14 +222,13 @@ void SimpleNativeMemoryMap::deinitializeMultiple(
|
||||
Error::success());
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::onDetach(ResourceManager::OnCompleteFn OnComplete) {
|
||||
void SimpleNativeMemoryMap::onDetach(Service::OnCompleteFn OnComplete) {
|
||||
// Detach is a noop for now: we just retain all actions to run at shutdown
|
||||
// time.
|
||||
OnComplete(Error::success());
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::onShutdown(
|
||||
ResourceManager::OnCompleteFn OnComplete) {
|
||||
void SimpleNativeMemoryMap::onShutdown(Service::OnCompleteFn OnComplete) {
|
||||
// TODO: Establish a clear order to run deallocate actions across slabs,
|
||||
// object boundaries.
|
||||
|
||||
@ -302,8 +301,8 @@ void SimpleNativeMemoryMap::deinitializeNext(
|
||||
NextAddr);
|
||||
}
|
||||
|
||||
void SimpleNativeMemoryMap::shutdownNext(
|
||||
ResourceManager::OnCompleteFn OnComplete, std::vector<void *> Bases) {
|
||||
void SimpleNativeMemoryMap::shutdownNext(Service::OnCompleteFn OnComplete,
|
||||
std::vector<void *> Bases) {
|
||||
if (Bases.empty())
|
||||
return OnComplete(Error::success());
|
||||
|
||||
|
||||
@ -26,15 +26,15 @@ using namespace orc_rt;
|
||||
using ::testing::Eq;
|
||||
using ::testing::Optional;
|
||||
|
||||
class MockResourceManager : public ResourceManager {
|
||||
class MockService : public Service {
|
||||
public:
|
||||
enum class Op { Detach, Shutdown };
|
||||
|
||||
static Error alwaysSucceed(Op) { return Error::success(); }
|
||||
|
||||
MockResourceManager(std::optional<size_t> &DetachOpIdx,
|
||||
std::optional<size_t> &ShutdownOpIdx, size_t &OpIdx,
|
||||
move_only_function<Error(Op)> GenResult = alwaysSucceed)
|
||||
MockService(std::optional<size_t> &DetachOpIdx,
|
||||
std::optional<size_t> &ShutdownOpIdx, size_t &OpIdx,
|
||||
move_only_function<Error(Op)> GenResult = alwaysSucceed)
|
||||
: DetachOpIdx(DetachOpIdx), ShutdownOpIdx(ShutdownOpIdx), OpIdx(OpIdx),
|
||||
GenResult(std::move(GenResult)) {}
|
||||
|
||||
@ -292,15 +292,15 @@ TEST(SessionTest, DispatchTask) {
|
||||
EXPECT_EQ(X, 1);
|
||||
}
|
||||
|
||||
TEST(SessionTest, SingleResourceManager) {
|
||||
TEST(SessionTest, SingleService) {
|
||||
size_t OpIdx = 0;
|
||||
std::optional<size_t> DetachOpIdx;
|
||||
std::optional<size_t> ShutdownOpIdx;
|
||||
|
||||
{
|
||||
Session S(std::make_unique<NoDispatcher>(), noErrors);
|
||||
S.addResourceManager(std::make_unique<MockResourceManager>(
|
||||
DetachOpIdx, ShutdownOpIdx, OpIdx));
|
||||
S.addService(
|
||||
std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
|
||||
}
|
||||
|
||||
EXPECT_EQ(OpIdx, 1U);
|
||||
@ -308,7 +308,7 @@ TEST(SessionTest, SingleResourceManager) {
|
||||
EXPECT_THAT(ShutdownOpIdx, Optional(Eq(0)));
|
||||
}
|
||||
|
||||
TEST(SessionTest, MultipleResourceManagers) {
|
||||
TEST(SessionTest, MultipleServices) {
|
||||
size_t OpIdx = 0;
|
||||
std::optional<size_t> DetachOpIdx[3];
|
||||
std::optional<size_t> ShutdownOpIdx[3];
|
||||
@ -316,8 +316,8 @@ TEST(SessionTest, MultipleResourceManagers) {
|
||||
{
|
||||
Session S(std::make_unique<NoDispatcher>(), noErrors);
|
||||
for (size_t I = 0; I != 3; ++I)
|
||||
S.addResourceManager(std::make_unique<MockResourceManager>(
|
||||
DetachOpIdx[I], ShutdownOpIdx[I], OpIdx));
|
||||
S.addService(std::make_unique<MockService>(DetachOpIdx[I],
|
||||
ShutdownOpIdx[I], OpIdx));
|
||||
}
|
||||
|
||||
EXPECT_EQ(OpIdx, 3U);
|
||||
@ -330,7 +330,7 @@ TEST(SessionTest, MultipleResourceManagers) {
|
||||
|
||||
TEST(SessionTest, ExpectedShutdownSequence) {
|
||||
// Check that Session shutdown results in...
|
||||
// 1. ResourceManagers being shut down.
|
||||
// 1. Services being shut down.
|
||||
// 2. The TaskDispatcher being shut down.
|
||||
// 3. A call to OnShutdownComplete.
|
||||
|
||||
@ -350,8 +350,8 @@ TEST(SessionTest, ExpectedShutdownSequence) {
|
||||
DispatcherShutDown = true;
|
||||
}),
|
||||
noErrors);
|
||||
S.addResourceManager(
|
||||
std::make_unique<MockResourceManager>(DetachOpIdx, ShutdownOpIdx, OpIdx));
|
||||
S.addService(
|
||||
std::make_unique<MockService>(DetachOpIdx, ShutdownOpIdx, OpIdx));
|
||||
|
||||
S.shutdown([&]() {
|
||||
EXPECT_TRUE(DispatcherShutDown);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user