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 |