//===---- SimpleRemoteEPC.h - Simple remote executor control ----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Simple remote executor process control. // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H #define LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FunctionExtras.h" #include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h" #include "llvm/ExecutionEngine/Orc/EPCGenericJITLinkMemoryManager.h" #include "llvm/ExecutionEngine/Orc/EPCGenericMemoryAccess.h" #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h" #include "llvm/Support/Error.h" #include "llvm/Support/MSVCErrorWorkarounds.h" #include namespace llvm { namespace orc { class SimpleRemoteEPC : public ExecutorProcessControl, public SimpleRemoteEPCTransportClient { public: /// A setup object containing callbacks to construct a memory manager and /// memory access object. Both are optional. If not specified, /// EPCGenericJITLinkMemoryManager and EPCGenericMemoryAccess will be used. struct Setup { using CreateMemoryManagerFn = Expected>( SimpleRemoteEPC &); using CreateMemoryAccessFn = Expected>(SimpleRemoteEPC &); unique_function CreateMemoryManager; unique_function CreateMemoryAccess; }; /// Create a SimpleRemoteEPC using the given transport type and args. template static Expected> Create(std::unique_ptr D, Setup S, TransportTCtorArgTs &&...TransportTCtorArgs) { std::unique_ptr SREPC( new SimpleRemoteEPC(std::make_shared(), std::move(D))); auto T = TransportT::Create( *SREPC, std::forward(TransportTCtorArgs)...); if (!T) return T.takeError(); SREPC->T = std::move(*T); if (auto Err = SREPC->setup(std::move(S))) return joinErrors(std::move(Err), SREPC->disconnect()); return std::move(SREPC); } SimpleRemoteEPC(const SimpleRemoteEPC &) = delete; SimpleRemoteEPC &operator=(const SimpleRemoteEPC &) = delete; SimpleRemoteEPC(SimpleRemoteEPC &&) = delete; SimpleRemoteEPC &operator=(SimpleRemoteEPC &&) = delete; ~SimpleRemoteEPC(); Expected loadDylib(const char *DylibPath) override; Expected> lookupSymbols(ArrayRef Request) override; Expected runAsMain(ExecutorAddr MainFnAddr, ArrayRef Args) override; Expected runAsVoidFunction(ExecutorAddr VoidFnAddr) override; Expected runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override; void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef ArgBuffer) override; Error disconnect() override; Expected handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes) override; void handleDisconnect(Error Err) override; private: SimpleRemoteEPC(std::shared_ptr SSP, std::unique_ptr D) : ExecutorProcessControl(std::move(SSP), std::move(D)) {} static Expected> createDefaultMemoryManager(SimpleRemoteEPC &SREPC); static Expected> createDefaultMemoryAccess(SimpleRemoteEPC &SREPC); Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, ArrayRef ArgBytes); Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes); Error setup(Setup S); Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes); void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes); Error handleHangup(SimpleRemoteEPCArgBytesVector ArgBytes); uint64_t getNextSeqNo() { return NextSeqNo++; } void releaseSeqNo(uint64_t SeqNo) {} using PendingCallWrapperResultsMap = DenseMap; std::mutex SimpleRemoteEPCMutex; std::condition_variable DisconnectCV; bool Disconnected = false; Error DisconnectErr = Error::success(); std::unique_ptr T; std::unique_ptr OwnedMemMgr; std::unique_ptr OwnedMemAccess; std::unique_ptr DylibMgr; ExecutorAddr RunAsMainAddr; ExecutorAddr RunAsVoidFunctionAddr; ExecutorAddr RunAsIntFunctionAddr; uint64_t NextSeqNo = 0; PendingCallWrapperResultsMap PendingCallWrapperResults; }; } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H