Skip to content

Commit ab71381

Browse files
authored
[orc-rt] Add Session class. (#162590)
An orc-rt Session contains a JIT'd program, managing resources and communicating with a remote JIT-controller instance (expected to be an orc::ExecutionSession, though this is not required).
1 parent 2b14a8d commit ab71381

File tree

6 files changed

+242
-0
lines changed

6 files changed

+242
-0
lines changed

orc-rt/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ set(ORC_RT_HEADERS
1515
orc-rt/ResourceManager.h
1616
orc-rt/RTTI.h
1717
orc-rt/ScopeExit.h
18+
orc-rt/Session.h
1819
orc-rt/SimpleNativeMemoryMap.h
1920
orc-rt/SimplePackedSerialization.h
2021
orc-rt/SPSAllocAction.h

orc-rt/include/orc-rt/Session.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===-------- Session.h - Session class and related APIs -------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Session class and related APIs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef ORC_RT_SESSION_H
14+
#define ORC_RT_SESSION_H
15+
16+
#include "orc-rt/Error.h"
17+
#include "orc-rt/ResourceManager.h"
18+
#include "orc-rt/move_only_function.h"
19+
20+
#include <vector>
21+
22+
namespace orc_rt {
23+
24+
/// Represents an ORC executor Session.
25+
class Session {
26+
public:
27+
using ErrorReporterFn = move_only_function<void(Error)>;
28+
using OnShutdownCompleteFn = move_only_function<void()>;
29+
30+
/// Create a session object. The ReportError function will be called to
31+
/// report errors generated while serving JIT'd code, e.g. if a memory
32+
/// management request cannot be fulfilled. (Error's within the JIT'd
33+
/// program are not generally visible to ORC-RT, but can optionally be
34+
/// reported by calling orc_rc_Session_reportError function.
35+
///
36+
/// Note that entry into the reporter is not synchronized: it may be
37+
/// called from multiple threads concurrently.
38+
Session(ErrorReporterFn ReportError) : ReportError(std::move(ReportError)) {}
39+
40+
// Sessions are not copyable or moveable.
41+
Session(const Session &) = delete;
42+
Session &operator=(const Session &) = delete;
43+
44+
~Session();
45+
46+
/// Report an error via the ErrorReporter function.
47+
void reportError(Error Err) { ReportError(std::move(Err)); }
48+
49+
/// Initiate session shutdown.
50+
///
51+
/// Runs shutdown on registered resources in reverse order.
52+
void shutdown(OnShutdownCompleteFn OnComplete);
53+
54+
/// Initiate session shutdown and block until complete.
55+
void waitForShutdown();
56+
57+
/// Add a ResourceManager to the session.
58+
void addResourceManager(std::unique_ptr<ResourceManager> RM) {
59+
std::scoped_lock<std::mutex> Lock(M);
60+
ResourceMgrs.push_back(std::move(RM));
61+
}
62+
63+
private:
64+
void shutdownNext(OnShutdownCompleteFn OnShutdownComplete, Error Err,
65+
std::vector<std::unique_ptr<ResourceManager>> RemainingRMs);
66+
67+
std::mutex M;
68+
ErrorReporterFn ReportError;
69+
std::vector<std::unique_ptr<ResourceManager>> ResourceMgrs;
70+
};
71+
72+
} // namespace orc_rt
73+
74+
#endif // ORC_RT_SESSION_H

orc-rt/lib/executor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set(files
33
AllocAction.cpp
44
ResourceManager.cpp
55
RTTI.cpp
6+
Session.cpp
67
SimpleNativeMemoryMap.cpp
78
)
89

orc-rt/lib/executor/Session.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//===- Session.cpp --------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Contains the implementation of the Session class and related APIs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "orc-rt/Session.h"
14+
15+
#include <future>
16+
17+
namespace orc_rt {
18+
19+
Session::~Session() { waitForShutdown(); }
20+
21+
void Session::shutdown(OnShutdownCompleteFn OnShutdownComplete) {
22+
std::vector<std::unique_ptr<ResourceManager>> ToShutdown;
23+
24+
{
25+
std::scoped_lock<std::mutex> Lock(M);
26+
std::swap(ResourceMgrs, ToShutdown);
27+
}
28+
29+
shutdownNext(std::move(OnShutdownComplete), Error::success(),
30+
std::move(ToShutdown));
31+
}
32+
33+
void Session::waitForShutdown() {
34+
std::promise<void> P;
35+
auto F = P.get_future();
36+
37+
shutdown([P = std::move(P)]() mutable { P.set_value(); });
38+
39+
F.wait();
40+
}
41+
42+
void Session::shutdownNext(
43+
OnShutdownCompleteFn OnComplete, Error Err,
44+
std::vector<std::unique_ptr<ResourceManager>> RemainingRMs) {
45+
if (Err)
46+
reportError(std::move(Err));
47+
48+
if (RemainingRMs.empty())
49+
return OnComplete();
50+
51+
auto NextRM = std::move(RemainingRMs.back());
52+
RemainingRMs.pop_back();
53+
NextRM->shutdown([this, RemainingRMs = std::move(RemainingRMs),
54+
OnComplete = std::move(OnComplete)](Error Err) mutable {
55+
shutdownNext(std::move(OnComplete), std::move(Err),
56+
std::move(RemainingRMs));
57+
});
58+
}
59+
60+
} // namespace orc_rt

orc-rt/unittests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_orc_rt_unittest(CoreTests
2323
MemoryFlagsTest.cpp
2424
RTTITest.cpp
2525
ScopeExitTest.cpp
26+
SessionTest.cpp
2627
SimpleNativeMemoryMapTest.cpp
2728
SimplePackedSerializationTest.cpp
2829
SPSAllocActionTest.cpp

orc-rt/unittests/SessionTest.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
//===- SessionTest.cpp ----------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Tests for orc-rt's Session.h APIs.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "orc-rt/Session.h"
14+
#include "gmock/gmock.h"
15+
#include "gtest/gtest.h"
16+
17+
#include <optional>
18+
19+
using namespace orc_rt;
20+
using ::testing::Eq;
21+
using ::testing::Optional;
22+
23+
class MockResourceManager : public ResourceManager {
24+
public:
25+
enum class Op { Detach, Shutdown };
26+
27+
static Error alwaysSucceed(Op) { return Error::success(); }
28+
29+
MockResourceManager(std::optional<size_t> &DetachOpIdx,
30+
std::optional<size_t> &ShutdownOpIdx, size_t &OpIdx,
31+
move_only_function<Error(Op)> GenResult = alwaysSucceed)
32+
: DetachOpIdx(DetachOpIdx), ShutdownOpIdx(ShutdownOpIdx), OpIdx(OpIdx),
33+
GenResult(std::move(GenResult)) {}
34+
35+
void detach(OnCompleteFn OnComplete) override {
36+
DetachOpIdx = OpIdx++;
37+
OnComplete(GenResult(Op::Detach));
38+
}
39+
40+
void shutdown(OnCompleteFn OnComplete) override {
41+
ShutdownOpIdx = OpIdx++;
42+
OnComplete(GenResult(Op::Shutdown));
43+
}
44+
45+
private:
46+
std::optional<size_t> &DetachOpIdx;
47+
std::optional<size_t> &ShutdownOpIdx;
48+
size_t &OpIdx;
49+
move_only_function<Error(Op)> GenResult;
50+
};
51+
52+
// Non-overloaded version of cantFail: allows easy construction of
53+
// move_only_functions<void(Error)>s.
54+
static void noErrors(Error Err) { cantFail(std::move(Err)); }
55+
56+
TEST(SessionTest, TrivialConstructionAndDestruction) { Session S(noErrors); }
57+
58+
TEST(SessionTest, ReportError) {
59+
Error E = Error::success();
60+
cantFail(std::move(E)); // Force error into checked state.
61+
62+
Session S([&](Error Err) { E = std::move(Err); });
63+
S.reportError(make_error<StringError>("foo"));
64+
65+
if (E)
66+
EXPECT_EQ(toString(std::move(E)), "foo");
67+
else
68+
ADD_FAILURE() << "Missing error value";
69+
}
70+
71+
TEST(SessionTest, SingleResourceManager) {
72+
size_t OpIdx = 0;
73+
std::optional<size_t> DetachOpIdx;
74+
std::optional<size_t> ShutdownOpIdx;
75+
76+
{
77+
Session S(noErrors);
78+
S.addResourceManager(std::make_unique<MockResourceManager>(
79+
DetachOpIdx, ShutdownOpIdx, OpIdx));
80+
}
81+
82+
EXPECT_EQ(OpIdx, 1U);
83+
EXPECT_EQ(DetachOpIdx, std::nullopt);
84+
EXPECT_THAT(ShutdownOpIdx, Optional(Eq(0)));
85+
}
86+
87+
TEST(SessionTest, MultipleResourceManagers) {
88+
size_t OpIdx = 0;
89+
std::optional<size_t> DetachOpIdx[3];
90+
std::optional<size_t> ShutdownOpIdx[3];
91+
92+
{
93+
Session S(noErrors);
94+
for (size_t I = 0; I != 3; ++I)
95+
S.addResourceManager(std::make_unique<MockResourceManager>(
96+
DetachOpIdx[I], ShutdownOpIdx[I], OpIdx));
97+
}
98+
99+
EXPECT_EQ(OpIdx, 3U);
100+
// Expect shutdown in reverse order.
101+
for (size_t I = 0; I != 3; ++I) {
102+
EXPECT_EQ(DetachOpIdx[I], std::nullopt);
103+
EXPECT_THAT(ShutdownOpIdx[I], Optional(Eq(2 - I)));
104+
}
105+
}

0 commit comments

Comments
 (0)