xref: /freebsd/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===---- SimpleRemoteEPC.h - Simple remote executor control ----*- 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 // Simple remote executor process control.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
14 #define LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
15 
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/FunctionExtras.h"
18 #include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
19 #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h"
20 #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h"
21 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
22 #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/Error.h"
25 #include "llvm/Support/MSVCErrorWorkarounds.h"
26 
27 #include <future>
28 
29 namespace llvm {
30 namespace orc {
31 
32 class LLVM_ABI SimpleRemoteEPC : public ExecutorProcessControl,
33                                  public SimpleRemoteEPCTransportClient,
34                                  private DylibManager {
35 public:
36   /// A setup object containing callbacks to construct a memory manager and
37   /// memory access object. Both are optional. If not specified,
38   /// EPCGenericJITLinkMemoryManager and EPCGenericMemoryAccess will be used.
39   struct Setup {
40     using CreateMemoryManagerFn =
41         Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>(
42             SimpleRemoteEPC &);
43     using CreateMemoryAccessFn =
44         Expected<std::unique_ptr<MemoryAccess>>(SimpleRemoteEPC &);
45 
46     unique_function<CreateMemoryManagerFn> CreateMemoryManager;
47     unique_function<CreateMemoryAccessFn> CreateMemoryAccess;
48   };
49 
50   /// Create a SimpleRemoteEPC using the given transport type and args.
51   template <typename TransportT, typename... TransportTCtorArgTs>
52   static Expected<std::unique_ptr<SimpleRemoteEPC>>
Create(std::unique_ptr<TaskDispatcher> D,Setup S,TransportTCtorArgTs &&...TransportTCtorArgs)53   Create(std::unique_ptr<TaskDispatcher> D, Setup S,
54          TransportTCtorArgTs &&...TransportTCtorArgs) {
55     std::unique_ptr<SimpleRemoteEPC> SREPC(
56         new SimpleRemoteEPC(std::make_shared<SymbolStringPool>(),
57                             std::move(D)));
58     auto T = TransportT::Create(
59         *SREPC, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
60     if (!T)
61       return T.takeError();
62     SREPC->T = std::move(*T);
63     if (auto Err = SREPC->setup(std::move(S)))
64       return joinErrors(std::move(Err), SREPC->disconnect());
65     return std::move(SREPC);
66   }
67 
68   SimpleRemoteEPC(const SimpleRemoteEPC &) = delete;
69   SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete;
70   SimpleRemoteEPC(SimpleRemoteEPC &&) = delete;
71   SimpleRemoteEPC &operator=(SimpleRemoteEPC &&) = delete;
72   ~SimpleRemoteEPC();
73 
74   Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
75                               ArrayRef<std::string> Args) override;
76 
77   Expected<int32_t> runAsVoidFunction(ExecutorAddr VoidFnAddr) override;
78 
79   Expected<int32_t> runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override;
80 
81   void callWrapperAsync(ExecutorAddr WrapperFnAddr,
82                         IncomingWFRHandler OnComplete,
83                         ArrayRef<char> ArgBuffer) override;
84 
85   Error disconnect() override;
86 
87   Expected<HandleMessageAction>
88   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
89                 SimpleRemoteEPCArgBytesVector ArgBytes) override;
90 
91   void handleDisconnect(Error Err) override;
92 
93 private:
SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,std::unique_ptr<TaskDispatcher> D)94   SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,
95                   std::unique_ptr<TaskDispatcher> D)
96       : ExecutorProcessControl(std::move(SSP), std::move(D)) {
97     this->DylibMgr = this;
98   }
99 
100   static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
101   createDefaultMemoryManager(SimpleRemoteEPC &SREPC);
102   static Expected<std::unique_ptr<MemoryAccess>>
103   createDefaultMemoryAccess(SimpleRemoteEPC &SREPC);
104 
105   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
106                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
107 
108   Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
109                     SimpleRemoteEPCArgBytesVector ArgBytes);
110   Error setup(Setup S);
111 
112   Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
113                      SimpleRemoteEPCArgBytesVector ArgBytes);
114   void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
115                          SimpleRemoteEPCArgBytesVector ArgBytes);
116   Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes);
117 
getNextSeqNo()118   uint64_t getNextSeqNo() { return NextSeqNo++; }
releaseSeqNo(uint64_t SeqNo)119   void releaseSeqNo(uint64_t SeqNo) {}
120 
121   Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
122 
123   void lookupSymbolsAsync(ArrayRef<LookupRequest> Request,
124                           SymbolLookupCompleteFn F) override;
125 
126   using PendingCallWrapperResultsMap =
127     DenseMap<uint64_t, IncomingWFRHandler>;
128 
129   std::mutex SimpleRemoteEPCMutex;
130   std::condition_variable DisconnectCV;
131   bool Disconnected = false;
132   Error DisconnectErr = Error::success();
133 
134   std::unique_ptr<SimpleRemoteEPCTransport> T;
135   std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
136   std::unique_ptr<MemoryAccess> OwnedMemAccess;
137 
138   std::unique_ptr<EPCGenericDylibManager> EPCDylibMgr;
139   ExecutorAddr RunAsMainAddr;
140   ExecutorAddr RunAsVoidFunctionAddr;
141   ExecutorAddr RunAsIntFunctionAddr;
142 
143   uint64_t NextSeqNo = 0;
144   PendingCallWrapperResultsMap PendingCallWrapperResults;
145 };
146 
147 } // end namespace orc
148 } // end namespace llvm
149 
150 #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
151