123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===---- SimpleRemoteEPCServer.h - EPC over abstract channel ---*- 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
- //
- //===----------------------------------------------------------------------===//
- //
- // EPC over simple abstract channel.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
- #define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/FunctionExtras.h"
- #include "llvm/Config/llvm-config.h"
- #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
- #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
- #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
- #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
- #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
- #include "llvm/Support/DynamicLibrary.h"
- #include "llvm/Support/Error.h"
- #include <condition_variable>
- #include <future>
- #include <memory>
- #include <mutex>
- namespace llvm {
- namespace orc {
- /// A simple EPC server implementation.
- class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
- public:
- using ReportErrorFunction = unique_function<void(Error)>;
- /// Dispatches calls to runWrapper.
- class Dispatcher {
- public:
- virtual ~Dispatcher();
- virtual void dispatch(unique_function<void()> Work) = 0;
- virtual void shutdown() = 0;
- };
- #if LLVM_ENABLE_THREADS
- class ThreadDispatcher : public Dispatcher {
- public:
- void dispatch(unique_function<void()> Work) override;
- void shutdown() override;
- private:
- std::mutex DispatchMutex;
- bool Running = true;
- size_t Outstanding = 0;
- std::condition_variable OutstandingCV;
- };
- #endif
- class Setup {
- friend class SimpleRemoteEPCServer;
- public:
- SimpleRemoteEPCServer &server() { return S; }
- StringMap<ExecutorAddr> &bootstrapSymbols() { return BootstrapSymbols; }
- std::vector<std::unique_ptr<ExecutorBootstrapService>> &services() {
- return Services;
- }
- void setDispatcher(std::unique_ptr<Dispatcher> D) { S.D = std::move(D); }
- void setErrorReporter(unique_function<void(Error)> ReportError) {
- S.ReportError = std::move(ReportError);
- }
- private:
- Setup(SimpleRemoteEPCServer &S) : S(S) {}
- SimpleRemoteEPCServer &S;
- StringMap<ExecutorAddr> BootstrapSymbols;
- std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
- };
- static StringMap<ExecutorAddr> defaultBootstrapSymbols();
- template <typename TransportT, typename... TransportTCtorArgTs>
- static Expected<std::unique_ptr<SimpleRemoteEPCServer>>
- Create(unique_function<Error(Setup &S)> SetupFunction,
- TransportTCtorArgTs &&...TransportTCtorArgs) {
- auto Server = std::make_unique<SimpleRemoteEPCServer>();
- Setup S(*Server);
- if (auto Err = SetupFunction(S))
- return std::move(Err);
- // Set ReportError up-front so that it can be used if construction
- // process fails.
- if (!Server->ReportError)
- Server->ReportError = [](Error Err) {
- logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
- };
- // Attempt to create transport.
- auto T = TransportT::Create(
- *Server, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
- if (!T)
- return T.takeError();
- Server->T = std::move(*T);
- if (auto Err = Server->T->start())
- return std::move(Err);
- // If transport creation succeeds then start up services.
- Server->Services = std::move(S.services());
- Server->Services.push_back(
- std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
- for (auto &Service : Server->Services)
- Service->addBootstrapSymbols(S.bootstrapSymbols());
- if (auto Err = Server->sendSetupMessage(std::move(S.BootstrapSymbols)))
- return std::move(Err);
- return std::move(Server);
- }
- /// Set an error reporter for this server.
- void setErrorReporter(ReportErrorFunction ReportError) {
- this->ReportError = std::move(ReportError);
- }
- /// Call to handle an incoming message.
- ///
- /// Returns 'Disconnect' if the message is a 'detach' message from the remote
- /// otherwise returns 'Continue'. If the server has moved to an error state,
- /// returns an error, which should be reported and treated as a 'Disconnect'.
- Expected<HandleMessageAction>
- handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes) override;
- Error waitForDisconnect();
- void handleDisconnect(Error Err) override;
- private:
- Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
- ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
- Error sendSetupMessage(StringMap<ExecutorAddr> BootstrapSymbols);
- Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
- void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
- SimpleRemoteEPCArgBytesVector ArgBytes);
- shared::WrapperFunctionResult
- doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
- static shared::CWrapperFunctionResult jitDispatchEntry(void *DispatchCtx,
- const void *FnTag,
- const char *ArgData,
- size_t ArgSize);
- uint64_t getNextSeqNo() { return NextSeqNo++; }
- void releaseSeqNo(uint64_t) {}
- using PendingJITDispatchResultsMap =
- DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
- std::mutex ServerStateMutex;
- std::condition_variable ShutdownCV;
- enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
- Error ShutdownErr = Error::success();
- std::unique_ptr<SimpleRemoteEPCTransport> T;
- std::unique_ptr<Dispatcher> D;
- std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
- ReportErrorFunction ReportError;
- uint64_t NextSeqNo = 0;
- PendingJITDispatchResultsMap PendingJITDispatchResults;
- std::vector<sys::DynamicLibrary> Dylibs;
- };
- } // end namespace orc
- } // end namespace llvm
- #endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|