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