SimpleRemoteEPCUtils.h 8.0 KB

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