Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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(std::move(Err), 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 | Expected<std::vector<tpctypes::LookupResult>> |
||
75 | lookupSymbols(ArrayRef<LookupRequest> Request) 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 |