1 //===---- SimpleRemoteEPC.h - Simple remote executor control ----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Simple remote executor process control.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
14 #define LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H
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"
31 class SimpleRemoteEPC : public ExecutorProcessControl,
32 public SimpleRemoteEPCTransportClient {
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.
38 using CreateMemoryManagerFn =
39 Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>(
41 using CreateMemoryAccessFn =
42 Expected<std::unique_ptr<MemoryAccess>>(SimpleRemoteEPC &);
44 unique_function<CreateMemoryManagerFn> CreateMemoryManager;
45 unique_function<CreateMemoryAccessFn> CreateMemoryAccess;
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>(),
56 auto T = TransportT::Create(
57 *SREPC, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
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);
66 SimpleRemoteEPC(const SimpleRemoteEPC &) = delete;
67 SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete;
68 SimpleRemoteEPC(SimpleRemoteEPC &&) = delete;
69 SimpleRemoteEPC &operator=(SimpleRemoteEPC &&) = delete;
72 Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
74 Expected<std::vector<tpctypes::LookupResult>>
75 lookupSymbols(ArrayRef<LookupRequest> Request) override;
77 Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
78 ArrayRef<std::string> Args) override;
80 void callWrapperAsync(ExecutorAddr WrapperFnAddr,
81 IncomingWFRHandler OnComplete,
82 ArrayRef<char> ArgBuffer) override;
84 Error disconnect() override;
86 Expected<HandleMessageAction>
87 handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
88 SimpleRemoteEPCArgBytesVector ArgBytes) override;
90 void handleDisconnect(Error Err) override;
93 SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,
94 std::unique_ptr<TaskDispatcher> D)
95 : ExecutorProcessControl(std::move(SSP), std::move(D)) {}
97 static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
98 createDefaultMemoryManager(SimpleRemoteEPC &SREPC);
99 static Expected<std::unique_ptr<MemoryAccess>>
100 createDefaultMemoryAccess(SimpleRemoteEPC &SREPC);
102 Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
103 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
105 Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr,
106 SimpleRemoteEPCArgBytesVector ArgBytes);
107 Error setup(Setup S);
109 Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
110 SimpleRemoteEPCArgBytesVector ArgBytes);
111 void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
112 SimpleRemoteEPCArgBytesVector ArgBytes);
113 Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes);
115 uint64_t getNextSeqNo() { return NextSeqNo++; }
116 void releaseSeqNo(uint64_t SeqNo) {}
118 using PendingCallWrapperResultsMap =
119 DenseMap<uint64_t, IncomingWFRHandler>;
121 std::mutex SimpleRemoteEPCMutex;
122 std::condition_variable DisconnectCV;
123 bool Disconnected = false;
124 Error DisconnectErr = Error::success();
126 std::unique_ptr<SimpleRemoteEPCTransport> T;
127 std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
128 std::unique_ptr<MemoryAccess> OwnedMemAccess;
130 std::unique_ptr<EPCGenericDylibManager> DylibMgr;
131 ExecutorAddr RunAsMainAddr;
133 uint64_t NextSeqNo = 0;
134 PendingCallWrapperResultsMap PendingCallWrapperResults;
137 } // end namespace orc
138 } // end namespace llvm
140 #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H