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