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 /// Create a SimpleRemoteEPC using the given transport type and args. 35 template <typename TransportT, typename... TransportTCtorArgTs> 36 static Expected<std::unique_ptr<SimpleRemoteEPC>> Create(std::unique_ptr<TaskDispatcher> D,TransportTCtorArgTs &&...TransportTCtorArgs)37 Create(std::unique_ptr<TaskDispatcher> D, 38 TransportTCtorArgTs &&...TransportTCtorArgs) { 39 std::unique_ptr<SimpleRemoteEPC> SREPC( 40 new SimpleRemoteEPC(std::make_shared<SymbolStringPool>(), 41 std::move(D))); 42 auto T = TransportT::Create( 43 *SREPC, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...); 44 if (!T) 45 return T.takeError(); 46 SREPC->T = std::move(*T); 47 if (auto Err = SREPC->setup()) 48 return joinErrors(std::move(Err), SREPC->disconnect()); 49 return std::move(SREPC); 50 } 51 52 SimpleRemoteEPC(const SimpleRemoteEPC &) = delete; 53 SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete; 54 SimpleRemoteEPC(SimpleRemoteEPC &&) = delete; 55 SimpleRemoteEPC &operator=(SimpleRemoteEPC &&) = delete; 56 ~SimpleRemoteEPC(); 57 58 Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override; 59 60 Expected<std::vector<tpctypes::LookupResult>> 61 lookupSymbols(ArrayRef<LookupRequest> Request) override; 62 63 Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr, 64 ArrayRef<std::string> Args) override; 65 66 void callWrapperAsync(ExecutorAddr WrapperFnAddr, 67 IncomingWFRHandler OnComplete, 68 ArrayRef<char> ArgBuffer) override; 69 70 Error disconnect() override; 71 72 Expected<HandleMessageAction> 73 handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, 74 SimpleRemoteEPCArgBytesVector ArgBytes) override; 75 76 void handleDisconnect(Error Err) override; 77 78 protected: 79 virtual Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>> 80 createMemoryManager(); 81 virtual Expected<std::unique_ptr<MemoryAccess>> createMemoryAccess(); 82 83 private: SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,std::unique_ptr<TaskDispatcher> D)84 SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP, 85 std::unique_ptr<TaskDispatcher> D) 86 : ExecutorProcessControl(std::move(SSP), std::move(D)) {} 87 88 Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, 89 ExecutorAddr TagAddr, ArrayRef<char> ArgBytes); 90 91 Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, 92 SimpleRemoteEPCArgBytesVector ArgBytes); 93 Error setup(); 94 95 Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, 96 SimpleRemoteEPCArgBytesVector ArgBytes); 97 void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr, 98 SimpleRemoteEPCArgBytesVector ArgBytes); 99 Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes); 100 getNextSeqNo()101 uint64_t getNextSeqNo() { return NextSeqNo++; } releaseSeqNo(uint64_t SeqNo)102 void releaseSeqNo(uint64_t SeqNo) {} 103 104 using PendingCallWrapperResultsMap = 105 DenseMap<uint64_t, IncomingWFRHandler>; 106 107 std::mutex SimpleRemoteEPCMutex; 108 std::condition_variable DisconnectCV; 109 bool Disconnected = false; 110 Error DisconnectErr = Error::success(); 111 112 std::unique_ptr<SimpleRemoteEPCTransport> T; 113 std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr; 114 std::unique_ptr<MemoryAccess> OwnedMemAccess; 115 116 std::unique_ptr<EPCGenericDylibManager> DylibMgr; 117 ExecutorAddr RunAsMainAddr; 118 119 uint64_t NextSeqNo = 0; 120 PendingCallWrapperResultsMap PendingCallWrapperResults; 121 }; 122 123 } // end namespace orc 124 } // end namespace llvm 125 126 #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H 127