]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/SimpleRemoteEPCServer.h
zfs: merge openzfs/zfs@6c3c5fcfb (zfs-2.1-release) into stable/13
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / ExecutionEngine / Orc / TargetProcess / SimpleRemoteEPCServer.h
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"
17 #include "llvm/ADT/FunctionExtras.h"
18 #include "llvm/Config/llvm-config.h"
19 #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
20 #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
21 #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
22 #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
23 #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
24 #include "llvm/Support/DynamicLibrary.h"
25 #include "llvm/Support/Error.h"
26
27 #include <condition_variable>
28 #include <future>
29 #include <memory>
30 #include <mutex>
31
32 namespace llvm {
33 namespace orc {
34
35 /// A simple EPC server implementation.
36 class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
37 public:
38   using ReportErrorFunction = unique_function<void(Error)>;
39
40   /// Dispatches calls to runWrapper.
41   class Dispatcher {
42   public:
43     virtual ~Dispatcher();
44     virtual void dispatch(unique_function<void()> Work) = 0;
45     virtual void shutdown() = 0;
46   };
47
48 #if LLVM_ENABLE_THREADS
49   class ThreadDispatcher : public Dispatcher {
50   public:
51     void dispatch(unique_function<void()> Work) override;
52     void shutdown() override;
53
54   private:
55     std::mutex DispatchMutex;
56     bool Running = true;
57     size_t Outstanding = 0;
58     std::condition_variable OutstandingCV;
59   };
60 #endif
61
62   class Setup {
63     friend class SimpleRemoteEPCServer;
64
65   public:
66     SimpleRemoteEPCServer &server() { return S; }
67     StringMap<ExecutorAddr> &bootstrapSymbols() { return BootstrapSymbols; }
68     std::vector<std::unique_ptr<ExecutorBootstrapService>> &services() {
69       return Services;
70     }
71     void setDispatcher(std::unique_ptr<Dispatcher> D) { S.D = std::move(D); }
72     void setErrorReporter(unique_function<void(Error)> ReportError) {
73       S.ReportError = std::move(ReportError);
74     }
75
76   private:
77     Setup(SimpleRemoteEPCServer &S) : S(S) {}
78     SimpleRemoteEPCServer &S;
79     StringMap<ExecutorAddr> BootstrapSymbols;
80     std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
81   };
82
83   static StringMap<ExecutorAddr> defaultBootstrapSymbols();
84
85   template <typename TransportT, typename... TransportTCtorArgTs>
86   static Expected<std::unique_ptr<SimpleRemoteEPCServer>>
87   Create(unique_function<Error(Setup &S)> SetupFunction,
88          TransportTCtorArgTs &&...TransportTCtorArgs) {
89     auto Server = std::make_unique<SimpleRemoteEPCServer>();
90     Setup S(*Server);
91     if (auto Err = SetupFunction(S))
92       return std::move(Err);
93
94     // Set ReportError up-front so that it can be used if construction
95     // process fails.
96     if (!Server->ReportError)
97       Server->ReportError = [](Error Err) {
98         logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
99       };
100
101     // Attempt to create transport.
102     auto T = TransportT::Create(
103         *Server, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
104     if (!T)
105       return T.takeError();
106     Server->T = std::move(*T);
107     if (auto Err = Server->T->start())
108       return std::move(Err);
109
110     // If transport creation succeeds then start up services.
111     Server->Services = std::move(S.services());
112     Server->Services.push_back(
113         std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
114     for (auto &Service : Server->Services)
115       Service->addBootstrapSymbols(S.bootstrapSymbols());
116
117     if (auto Err = Server->sendSetupMessage(std::move(S.BootstrapSymbols)))
118       return std::move(Err);
119     return std::move(Server);
120   }
121
122   /// Set an error reporter for this server.
123   void setErrorReporter(ReportErrorFunction ReportError) {
124     this->ReportError = std::move(ReportError);
125   }
126
127   /// Call to handle an incoming message.
128   ///
129   /// Returns 'Disconnect' if the message is a 'detach' message from the remote
130   /// otherwise returns 'Continue'. If the server has moved to an error state,
131   /// returns an error, which should be reported and treated as a 'Disconnect'.
132   Expected<HandleMessageAction>
133   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
134                 SimpleRemoteEPCArgBytesVector ArgBytes) override;
135
136   Error waitForDisconnect();
137
138   void handleDisconnect(Error Err) override;
139
140 private:
141   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
142                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
143
144   Error sendSetupMessage(StringMap<ExecutorAddr> BootstrapSymbols);
145
146   Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
147                      SimpleRemoteEPCArgBytesVector ArgBytes);
148   void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
149                          SimpleRemoteEPCArgBytesVector ArgBytes);
150
151   shared::WrapperFunctionResult
152   doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
153
154   static shared::CWrapperFunctionResult jitDispatchEntry(void *DispatchCtx,
155                                                          const void *FnTag,
156                                                          const char *ArgData,
157                                                          size_t ArgSize);
158
159   uint64_t getNextSeqNo() { return NextSeqNo++; }
160   void releaseSeqNo(uint64_t) {}
161
162   using PendingJITDispatchResultsMap =
163       DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
164
165   std::mutex ServerStateMutex;
166   std::condition_variable ShutdownCV;
167   enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
168   Error ShutdownErr = Error::success();
169   std::unique_ptr<SimpleRemoteEPCTransport> T;
170   std::unique_ptr<Dispatcher> D;
171   std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
172   ReportErrorFunction ReportError;
173
174   uint64_t NextSeqNo = 0;
175   PendingJITDispatchResultsMap PendingJITDispatchResults;
176   std::vector<sys::DynamicLibrary> Dylibs;
177 };
178
179 } // end namespace orc
180 } // end namespace llvm
181
182 #endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H