Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===--- SimpleRemoteEPCUtils.h - Utils for Simple Remote EPC ---*- 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. // Message definitions and other utilities for SimpleRemoteEPC and
  10. // SimpleRemoteEPCServer.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
  15. #define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
  16.  
  17. #include "llvm/ADT/ArrayRef.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/ADT/StringMap.h"
  20. #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
  21. #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
  22. #include "llvm/Support/Error.h"
  23.  
  24. #include <atomic>
  25. #include <mutex>
  26. #include <string>
  27. #include <thread>
  28.  
  29. namespace llvm {
  30. namespace orc {
  31.  
  32. namespace SimpleRemoteEPCDefaultBootstrapSymbolNames {
  33. extern const char *ExecutorSessionObjectName;
  34. extern const char *DispatchFnName;
  35. } // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
  36.  
  37. enum class SimpleRemoteEPCOpcode : uint8_t {
  38.   Setup,
  39.   Hangup,
  40.   Result,
  41.   CallWrapper,
  42.   LastOpC = CallWrapper
  43. };
  44.  
  45. struct SimpleRemoteEPCExecutorInfo {
  46.   std::string TargetTriple;
  47.   uint64_t PageSize;
  48.   StringMap<ExecutorAddr> BootstrapSymbols;
  49. };
  50.  
  51. using SimpleRemoteEPCArgBytesVector = SmallVector<char, 128>;
  52.  
  53. class SimpleRemoteEPCTransportClient {
  54. public:
  55.   enum HandleMessageAction { ContinueSession, EndSession };
  56.  
  57.   virtual ~SimpleRemoteEPCTransportClient();
  58.  
  59.   /// Handle receipt of a message.
  60.   ///
  61.   /// Returns an Error if the message cannot be handled, 'EndSession' if the
  62.   /// client will not accept any further messages, and 'ContinueSession'
  63.   /// otherwise.
  64.   virtual Expected<HandleMessageAction>
  65.   handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
  66.                 SimpleRemoteEPCArgBytesVector ArgBytes) = 0;
  67.  
  68.   /// Handle a disconnection from the underlying transport. No further messages
  69.   /// should be sent to handleMessage after this is called.
  70.   /// Err may contain an Error value indicating unexpected disconnection. This
  71.   /// allows clients to log such errors, but no attempt should be made at
  72.   /// recovery (which should be handled inside the transport class, if it is
  73.   /// supported at all).
  74.   virtual void handleDisconnect(Error Err) = 0;
  75. };
  76.  
  77. class SimpleRemoteEPCTransport {
  78. public:
  79.   virtual ~SimpleRemoteEPCTransport();
  80.  
  81.   /// Called during setup of the client to indicate that the client is ready
  82.   /// to receive messages.
  83.   ///
  84.   /// Transport objects should not access the client until this method is
  85.   /// called.
  86.   virtual Error start() = 0;
  87.  
  88.   /// Send a SimpleRemoteEPC message.
  89.   ///
  90.   /// This function may be called concurrently. Subclasses should implement
  91.   /// locking if required for the underlying transport.
  92.   virtual Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
  93.                             ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) = 0;
  94.  
  95.   /// Trigger disconnection from the transport. The implementation should
  96.   /// respond by calling handleDisconnect on the client once disconnection
  97.   /// is complete. May be called more than once and from different threads.
  98.   virtual void disconnect() = 0;
  99. };
  100.  
  101. /// Uses read/write on FileDescriptors for transport.
  102. class FDSimpleRemoteEPCTransport : public SimpleRemoteEPCTransport {
  103. public:
  104.   /// Create a FDSimpleRemoteEPCTransport using the given FDs for
  105.   /// reading (InFD) and writing (OutFD).
  106.   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
  107.   Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD);
  108.  
  109.   /// Create a FDSimpleRemoteEPCTransport using the given FD for both
  110.   /// reading and writing.
  111.   static Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>>
  112.   Create(SimpleRemoteEPCTransportClient &C, int FD) {
  113.     return Create(C, FD, FD);
  114.   }
  115.  
  116.   ~FDSimpleRemoteEPCTransport() override;
  117.  
  118.   Error start() override;
  119.  
  120.   Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
  121.                     ExecutorAddr TagAddr, ArrayRef<char> ArgBytes) override;
  122.  
  123.   void disconnect() override;
  124.  
  125. private:
  126.   FDSimpleRemoteEPCTransport(SimpleRemoteEPCTransportClient &C, int InFD,
  127.                              int OutFD)
  128.       : C(C), InFD(InFD), OutFD(OutFD) {}
  129.  
  130.   Error readBytes(char *Dst, size_t Size, bool *IsEOF = nullptr);
  131.   int writeBytes(const char *Src, size_t Size);
  132.   void listenLoop();
  133.  
  134.   std::mutex M;
  135.   SimpleRemoteEPCTransportClient &C;
  136.   std::thread ListenerThread;
  137.   int InFD, OutFD;
  138.   std::atomic<bool> Disconnected{false};
  139. };
  140.  
  141. struct RemoteSymbolLookupSetElement {
  142.   std::string Name;
  143.   bool Required;
  144. };
  145.  
  146. using RemoteSymbolLookupSet = std::vector<RemoteSymbolLookupSetElement>;
  147.  
  148. struct RemoteSymbolLookup {
  149.   uint64_t H;
  150.   RemoteSymbolLookupSet Symbols;
  151. };
  152.  
  153. namespace shared {
  154.  
  155. using SPSRemoteSymbolLookupSetElement = SPSTuple<SPSString, bool>;
  156.  
  157. using SPSRemoteSymbolLookupSet = SPSSequence<SPSRemoteSymbolLookupSetElement>;
  158.  
  159. using SPSRemoteSymbolLookup = SPSTuple<uint64_t, SPSRemoteSymbolLookupSet>;
  160.  
  161. /// Tuple containing target triple, page size, and bootstrap symbols.
  162. using SPSSimpleRemoteEPCExecutorInfo =
  163.     SPSTuple<SPSString, uint64_t,
  164.              SPSSequence<SPSTuple<SPSString, SPSExecutorAddr>>>;
  165.  
  166. template <>
  167. class SPSSerializationTraits<SPSRemoteSymbolLookupSetElement,
  168.                              RemoteSymbolLookupSetElement> {
  169. public:
  170.   static size_t size(const RemoteSymbolLookupSetElement &V) {
  171.     return SPSArgList<SPSString, bool>::size(V.Name, V.Required);
  172.   }
  173.  
  174.   static size_t serialize(SPSOutputBuffer &OB,
  175.                           const RemoteSymbolLookupSetElement &V) {
  176.     return SPSArgList<SPSString, bool>::serialize(OB, V.Name, V.Required);
  177.   }
  178.  
  179.   static size_t deserialize(SPSInputBuffer &IB,
  180.                             RemoteSymbolLookupSetElement &V) {
  181.     return SPSArgList<SPSString, bool>::deserialize(IB, V.Name, V.Required);
  182.   }
  183. };
  184.  
  185. template <>
  186. class SPSSerializationTraits<SPSRemoteSymbolLookup, RemoteSymbolLookup> {
  187. public:
  188.   static size_t size(const RemoteSymbolLookup &V) {
  189.     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::size(V.H, V.Symbols);
  190.   }
  191.  
  192.   static size_t serialize(SPSOutputBuffer &OB, const RemoteSymbolLookup &V) {
  193.     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::serialize(OB, V.H,
  194.                                                                      V.Symbols);
  195.   }
  196.  
  197.   static size_t deserialize(SPSInputBuffer &IB, RemoteSymbolLookup &V) {
  198.     return SPSArgList<uint64_t, SPSRemoteSymbolLookupSet>::deserialize(
  199.         IB, V.H, V.Symbols);
  200.   }
  201. };
  202.  
  203. template <>
  204. class SPSSerializationTraits<SPSSimpleRemoteEPCExecutorInfo,
  205.                              SimpleRemoteEPCExecutorInfo> {
  206. public:
  207.   static size_t size(const SimpleRemoteEPCExecutorInfo &SI) {
  208.     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::size(
  209.         SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
  210.   }
  211.  
  212.   static bool serialize(SPSOutputBuffer &OB,
  213.                         const SimpleRemoteEPCExecutorInfo &SI) {
  214.     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::serialize(
  215.         OB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
  216.   }
  217.  
  218.   static bool deserialize(SPSInputBuffer &IB, SimpleRemoteEPCExecutorInfo &SI) {
  219.     return SPSSimpleRemoteEPCExecutorInfo::AsArgList ::deserialize(
  220.         IB, SI.TargetTriple, SI.PageSize, SI.BootstrapSymbols);
  221.   }
  222. };
  223.  
  224. using SPSLoadDylibSignature = SPSExpected<SPSExecutorAddr>(SPSExecutorAddr,
  225.                                                            SPSString, uint64_t);
  226.  
  227. using SPSLookupSymbolsSignature =
  228.     SPSExpected<SPSSequence<SPSSequence<SPSExecutorAddr>>>(
  229.         SPSExecutorAddr, SPSSequence<SPSRemoteSymbolLookup>);
  230.  
  231. } // end namespace shared
  232. } // end namespace orc
  233. } // end namespace llvm
  234.  
  235. #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEREMOTEEPCUTILS_H
  236.