123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===---- 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 <future>
- 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<std::unique_ptr<jitlink::JITLinkMemoryManager>>(
- SimpleRemoteEPC &);
- using CreateMemoryAccessFn =
- Expected<std::unique_ptr<MemoryAccess>>(SimpleRemoteEPC &);
- unique_function<CreateMemoryManagerFn> CreateMemoryManager;
- unique_function<CreateMemoryAccessFn> CreateMemoryAccess;
- };
- /// Create a SimpleRemoteEPC using the given transport type and args.
- template <typename TransportT, typename... TransportTCtorArgTs>
- static Expected<std::unique_ptr<SimpleRemoteEPC>>
- Create(std::unique_ptr<TaskDispatcher> D, Setup S,
- TransportTCtorArgTs &&...TransportTCtorArgs) {
- std::unique_ptr<SimpleRemoteEPC> SREPC(
- new SimpleRemoteEPC(std::make_shared<SymbolStringPool>(),
- std::move(D)));
- auto T = TransportT::Create(
- *SREPC, std::forward<TransportTCtorArgTs>(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<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
- Expected<std::vector<tpctypes::LookupResult>>
- lookupSymbols(ArrayRef<LookupRequest> Request) override;
- Expected<int32_t> runAsMain(ExecutorAddr MainFnAddr,
- ArrayRef<std::string> Args) override;
- Expected<int32_t> runAsVoidFunction(ExecutorAddr VoidFnAddr) override;
- Expected<int32_t> runAsIntFunction(ExecutorAddr IntFnAddr, int Arg) override;
- void callWrapperAsync(ExecutorAddr WrapperFnAddr,
- IncomingWFRHandler OnComplete,
- ArrayRef<char> ArgBuffer) override;
- Error disconnect() override;
- Expected<HandleMessageAction>
- handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) override;
- void handleDisconnect(Error Err) override;
- private:
- SimpleRemoteEPC(std::shared_ptr<SymbolStringPool> SSP,
- std::unique_ptr<TaskDispatcher> D)
- : ExecutorProcessControl(std::move(SSP), std::move(D)) {}
- static Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
- createDefaultMemoryManager(SimpleRemoteEPC &SREPC);
- static Expected<std::unique_ptr<MemoryAccess>>
- createDefaultMemoryAccess(SimpleRemoteEPC &SREPC);
- Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddr TagAddr, ArrayRef<char> 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<uint64_t, IncomingWFRHandler>;
- std::mutex SimpleRemoteEPCMutex;
- std::condition_variable DisconnectCV;
- bool Disconnected = false;
- Error DisconnectErr = Error::success();
- std::unique_ptr<SimpleRemoteEPCTransport> T;
- std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
- std::unique_ptr<MemoryAccess> OwnedMemAccess;
- std::unique_ptr<EPCGenericDylibManager> 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|