Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===---- SimpleRemoteEPCServer.h - EPC over abstract channel ---*- 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. // EPC over simple abstract channel.
  10. //
  11. //===----------------------------------------------------------------------===//
  12.  
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
  14. #define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
  15.  
  16. #include "llvm/ADT/DenseMap.h"
  17. #include "llvm/ADT/FunctionExtras.h"
  18. #include "llvm/Config/llvm-config.h"
  19. #include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
  20. #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
  21. #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
  22. #include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
  23. #include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
  24. #include "llvm/Support/DynamicLibrary.h"
  25. #include "llvm/Support/Error.h"
  26.  
  27. #include <condition_variable>
  28. #include <future>
  29. #include <memory>
  30. #include <mutex>
  31.  
  32. namespace llvm {
  33. namespace orc {
  34.  
  35. /// A simple EPC server implementation.
  36. class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
  37. public:
  38.   using ReportErrorFunction = unique_function<void(Error)>;
  39.  
  40.   /// Dispatches calls to runWrapper.
  41.   class Dispatcher {
  42.   public:
  43.     virtual ~Dispatcher();
  44.     virtual void dispatch(unique_function<void()> Work) = 0;
  45.     virtual void shutdown() = 0;
  46.   };
  47.  
  48. #if LLVM_ENABLE_THREADS
  49.   class ThreadDispatcher : public Dispatcher {
  50.   public:
  51.     void dispatch(unique_function<void()> Work) override;
  52.     void shutdown() override;
  53.  
  54.   private:
  55.     std::mutex DispatchMutex;
  56.     bool Running = true;
  57.     size_t Outstanding = 0;
  58.     std::condition_variable OutstandingCV;
  59.   };
  60. #endif
  61.  
  62.   class Setup {
  63.     friend class SimpleRemoteEPCServer;
  64.  
  65.   public:
  66.     SimpleRemoteEPCServer &server() { return S; }
  67.     StringMap<ExecutorAddr> &bootstrapSymbols() { return BootstrapSymbols; }
  68.     std::vector<std::unique_ptr<ExecutorBootstrapService>> &services() {
  69.       return Services;
  70.     }
  71.     void setDispatcher(std::unique_ptr<Dispatcher> D) { S.D = std::move(D); }
  72.     void setErrorReporter(unique_function<void(Error)> ReportError) {
  73.       S.ReportError = std::move(ReportError);
  74.     }
  75.  
  76.   private:
  77.     Setup(SimpleRemoteEPCServer &S) : S(S) {}
  78.     SimpleRemoteEPCServer &S;
  79.     StringMap<ExecutorAddr> BootstrapSymbols;
  80.     std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
  81.   };
  82.  
  83.   static StringMap<ExecutorAddr> defaultBootstrapSymbols();
  84.  
  85.   template <typename TransportT, typename... TransportTCtorArgTs>
  86.   static Expected<std::unique_ptr<SimpleRemoteEPCServer>>
  87.   Create(unique_function<Error(Setup &S)> SetupFunction,
  88.          TransportTCtorArgTs &&...TransportTCtorArgs) {
  89.     auto Server = std::make_unique<SimpleRemoteEPCServer>();
  90.     Setup S(*Server);
  91.     if (auto Err = SetupFunction(S))
  92.       return std::move(Err);
  93.  
  94.     // Set ReportError up-front so that it can be used if construction
  95.     // process fails.
  96.     if (!Server->ReportError)
  97.       Server->ReportError = [](Error Err) {
  98.         logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
  99.       };
  100.  
  101.     // Attempt to create transport.
  102.     auto T = TransportT::Create(
  103.         *Server, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
  104.     if (!T)
  105.       return T.takeError();
  106.     Server->T = std::move(*T);
  107.     if (auto Err = Server->T->start())
  108.       return std::move(Err);
  109.  
  110.     // If transport creation succeeds then start up services.
  111.     Server->Services = std::move(S.services());
  112.     Server->Services.push_back(
  113.         std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
  114.     for (auto &Service : Server->Services)
  115.       Service->addBootstrapSymbols(S.bootstrapSymbols());
  116.  
  117.     if (auto Err = Server->sendSetupMessage(std::move(S.BootstrapSymbols)))
  118.       return std::move(Err);
  119.     return std::move(Server);
  120.   }
  121.  
  122.   /// Set an error reporter for this server.
  123.   void setErrorReporter(ReportErrorFunction ReportError) {
  124.     this->ReportError = std::move(ReportError);
  125.   }
  126.  
  127.   /// Call to handle an incoming message.
  128.   ///
  129.   /// Returns 'Disconnect' if the message is a 'detach' message from the remote
  130.   /// otherwise returns 'Continue'. If the server has moved to an error state,
  131.   /// returns an error, which should be reported and treated as a 'Disconnect'.
  132.   Expected<HandleMessageAction>
  133.   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
  134.                 SimpleRemoteEPCArgBytesVector ArgBytes) override;
  135.  
  136.   Error waitForDisconnect();
  137.  
  138.   void handleDisconnect(Error Err) override;
  139.  
  140. private:
  141.   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
  142.                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
  143.  
  144.   Error sendSetupMessage(StringMap<ExecutorAddr> BootstrapSymbols);
  145.  
  146.   Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
  147.                      SimpleRemoteEPCArgBytesVector ArgBytes);
  148.   void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
  149.                          SimpleRemoteEPCArgBytesVector ArgBytes);
  150.  
  151.   shared::WrapperFunctionResult
  152.   doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
  153.  
  154.   static shared::CWrapperFunctionResult jitDispatchEntry(void *DispatchCtx,
  155.                                                          const void *FnTag,
  156.                                                          const char *ArgData,
  157.                                                          size_t ArgSize);
  158.  
  159.   uint64_t getNextSeqNo() { return NextSeqNo++; }
  160.   void releaseSeqNo(uint64_t) {}
  161.  
  162.   using PendingJITDispatchResultsMap =
  163.       DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
  164.  
  165.   std::mutex ServerStateMutex;
  166.   std::condition_variable ShutdownCV;
  167.   enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
  168.   Error ShutdownErr = Error::success();
  169.   std::unique_ptr<SimpleRemoteEPCTransport> T;
  170.   std::unique_ptr<Dispatcher> D;
  171.   std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
  172.   ReportErrorFunction ReportError;
  173.  
  174.   uint64_t NextSeqNo = 0;
  175.   PendingJITDispatchResultsMap PendingJITDispatchResults;
  176.   std::vector<sys::DynamicLibrary> Dylibs;
  177. };
  178.  
  179. } // end namespace orc
  180. } // end namespace llvm
  181.  
  182. #endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
  183.