[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:
Lang Hames 2026-03-15 14:37:48 +11:00 committed by GitHub
parent 3fea2f6165
commit 96e7fc2c9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 70 additions and 67 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
};

View File

@ -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 {

View File

@ -2,8 +2,8 @@ set(files
AllocAction.cpp
Error.cpp
QueueingTaskDispatcher.cpp
ResourceManager.cpp
RTTI.cpp
Service.cpp
Session.cpp
SimpleNativeMemoryMap.cpp
TaskDispatcher.cpp

View File

@ -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

View File

@ -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() {

View File

@ -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());

View File

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