//===---- 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/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/MSVCErrorWorkarounds.h" #include namespace llvm { namespace orc { class LLVM_ABI SimpleRemoteEPC : public ExecutorProcessControl, public SimpleRemoteEPCTransportClient { public: /// Create a SimpleRemoteEPC using the given transport type and args. template static Expected> Create(std::unique_ptr D, 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()) 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() 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; Expected> createDefaultMemoryManager() override; Expected> createDefaultDylibMgr() override; Expected> createDefaultMemoryAccess() override; Error disconnect() override; Expected handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, shared::WrapperFunctionBuffer 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); Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, ArrayRef ArgBytes); Error handleSetup(uint64_t SeqNo, ExecutorAddr TagAddr, shared::WrapperFunctionBuffer ArgBytes); Error setup(); Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr, shared::WrapperFunctionBuffer ArgBytes); void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr, shared::WrapperFunctionBuffer ArgBytes); Error handleHangup(shared::WrapperFunctionBuffer 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; ExecutorAddr RunAsMainAddr; ExecutorAddr RunAsVoidFunctionAddr; ExecutorAddr RunAsIntFunctionAddr; uint64_t NextSeqNo = 0; PendingCallWrapperResultsMap PendingCallWrapperResults; }; } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_SIMPLEREMOTEEPC_H