LLVM 22.0.0git
SimpleRemoteEPCServer.h
Go to the documentation of this file.
1//===---- SimpleRemoteEPCServer.h - EPC over abstract channel ---*- 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// EPC over simple abstract channel.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
14#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
15
16#include "llvm/ADT/DenseMap.h"
18#include "llvm/Config/llvm-config.h"
26#include "llvm/Support/Error.h"
27
28#include <condition_variable>
29#include <future>
30#include <memory>
31#include <mutex>
32
33namespace llvm {
34namespace orc {
35
36/// A simple EPC server implementation.
38public:
40
41 /// Dispatches calls to runWrapper.
43 public:
44 virtual ~Dispatcher();
45 virtual void dispatch(unique_function<void()> Work) = 0;
46 virtual void shutdown() = 0;
47 };
48
49#if LLVM_ENABLE_THREADS
50 class LLVM_ABI ThreadDispatcher : public Dispatcher {
51 public:
52 void dispatch(unique_function<void()> Work) override;
53 void shutdown() override;
54
55 private:
56 std::mutex DispatchMutex;
57 bool Running = true;
58 size_t Outstanding = 0;
59 std::condition_variable OutstandingCV;
60 };
61#endif
62
63 class Setup {
65
66 public:
68 StringMap<std::vector<char>> &bootstrapMap() { return BootstrapMap; }
69 template <typename T, typename SPSTagT>
70 void setBootstrapMapValue(std::string Key, const T &Value) {
71 std::vector<char> Buffer;
73 shared::SPSOutputBuffer OB(Buffer.data(), Buffer.size());
75 (void)Success;
76 assert(Success && "Bootstrap map value serialization failed");
77 BootstrapMap[std::move(Key)] = std::move(Buffer);
78 }
79 StringMap<ExecutorAddr> &bootstrapSymbols() { return BootstrapSymbols; }
80 std::vector<std::unique_ptr<ExecutorBootstrapService>> &services() {
81 return Services;
82 }
83 void setDispatcher(std::unique_ptr<Dispatcher> D) { S.D = std::move(D); }
84 void setErrorReporter(unique_function<void(Error)> ReportError) {
85 S.ReportError = std::move(ReportError);
86 }
87
88 private:
89 Setup(SimpleRemoteEPCServer &S) : S(S) {}
91 StringMap<std::vector<char>> BootstrapMap;
92 StringMap<ExecutorAddr> BootstrapSymbols;
93 std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
94 };
95
96 static StringMap<ExecutorAddr> defaultBootstrapSymbols();
97
98 template <typename TransportT, typename... TransportTCtorArgTs>
100 Create(unique_function<Error(Setup &S)> SetupFunction,
101 TransportTCtorArgTs &&...TransportTCtorArgs) {
102 auto Server = std::make_unique<SimpleRemoteEPCServer>();
103 Setup S(*Server);
104 if (auto Err = SetupFunction(S))
105 return std::move(Err);
106
107 // Set ReportError up-front so that it can be used if construction
108 // process fails.
109 if (!Server->ReportError)
110 Server->ReportError = [](Error Err) {
111 logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
112 };
113
114 // Attempt to create transport.
115 auto T = TransportT::Create(
116 *Server, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
117 if (!T)
118 return T.takeError();
119 Server->T = std::move(*T);
120 if (auto Err = Server->T->start())
121 return std::move(Err);
122
123 // If transport creation succeeds then start up services.
124 Server->Services = std::move(S.services());
125 Server->Services.push_back(
126 std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
127 for (auto &Service : Server->Services)
128 Service->addBootstrapSymbols(S.bootstrapSymbols());
129
130 if (auto Err = Server->sendSetupMessage(std::move(S.BootstrapMap),
131 std::move(S.BootstrapSymbols)))
132 return std::move(Err);
133 return std::move(Server);
134 }
135
136 /// Set an error reporter for this server.
138 this->ReportError = std::move(ReportError);
139 }
140
141 /// Call to handle an incoming message.
142 ///
143 /// Returns 'Disconnect' if the message is a 'detach' message from the remote
144 /// otherwise returns 'Continue'. If the server has moved to an error state,
145 /// returns an error, which should be reported and treated as a 'Disconnect'.
147 handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
148 SimpleRemoteEPCArgBytesVector ArgBytes) override;
149
150 Error waitForDisconnect();
151
152 void handleDisconnect(Error Err) override;
153
154private:
155 Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
156 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
157
158 Error sendSetupMessage(StringMap<std::vector<char>> BootstrapMap,
159 StringMap<ExecutorAddr> BootstrapSymbols);
160
161 Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
163 void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
165
167 doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
168
169 static shared::CWrapperFunctionResult jitDispatchEntry(void *DispatchCtx,
170 const void *FnTag,
171 const char *ArgData,
172 size_t ArgSize);
173
174 uint64_t getNextSeqNo() { return NextSeqNo++; }
175 void releaseSeqNo(uint64_t) {}
176
177 using PendingJITDispatchResultsMap =
178 DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
179
180 std::mutex ServerStateMutex;
181 std::condition_variable ShutdownCV;
182 enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
183 Error ShutdownErr = Error::success();
184 std::unique_ptr<SimpleRemoteEPCTransport> T;
185 std::unique_ptr<Dispatcher> D;
186 std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
187 ReportErrorFunction ReportError;
188
189 uint64_t NextSeqNo = 0;
190 PendingJITDispatchResultsMap PendingJITDispatchResults;
191 std::vector<sys::DynamicLibrary> Dylibs;
192};
193
194} // end namespace orc
195} // end namespace llvm
196
197#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
#define T
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
Tagged union holding either a T or a Error.
Definition: Error.h:485
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:133
LLVM Value Representation.
Definition: Value.h:75
Represents an address in the executor process.
virtual void dispatch(unique_function< void()> Work)=0
void setDispatcher(std::unique_ptr< Dispatcher > D)
std::vector< std::unique_ptr< ExecutorBootstrapService > > & services()
void setErrorReporter(unique_function< void(Error)> ReportError)
void setBootstrapMapValue(std::string Key, const T &Value)
StringMap< std::vector< char > > & bootstrapMap()
StringMap< ExecutorAddr > & bootstrapSymbols()
A simple EPC server implementation.
void setErrorReporter(ReportErrorFunction ReportError)
Set an error reporter for this server.
static Expected< std::unique_ptr< SimpleRemoteEPCServer > > Create(unique_function< Error(Setup &S)> SetupFunction, TransportTCtorArgTs &&...TransportTCtorArgs)
A utility class for serializing to a blob from a variadic list.
Output char buffer with overflow check.
C++ wrapper function result: Same as CWrapperFunctionResult but auto-releases memory.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
Definition: Error.cpp:65
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.