LLVM: lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15#include "llvm/Config/llvm-config.h"

17

18#if !defined(_MSC_VER) && !defined(__MINGW32__)

19#include <unistd.h>

20#else

21#include <io.h>

22#endif

23

24namespace {

25

26struct FDMsgHeader {

27 static constexpr unsigned MsgSizeOffset = 0;

28 static constexpr unsigned OpCOffset = MsgSizeOffset + sizeof(uint64_t);

29 static constexpr unsigned SeqNoOffset = OpCOffset + sizeof(uint64_t);

30 static constexpr unsigned TagAddrOffset = SeqNoOffset + sizeof(uint64_t);

31 static constexpr unsigned Size = TagAddrOffset + sizeof(uint64_t);

32};

33

34}

35

36namespace llvm {

37namespace orc {

39

41 "__llvm_orc_SimpleRemoteEPC_dispatch_ctx";

42const char *DispatchFnName = "__llvm_orc_SimpleRemoteEPC_dispatch_fn";

43

44}

45

48

51 int OutFD) {

52#if LLVM_ENABLE_THREADS

53 if (InFD == -1)

57 if (OutFD == -1)

61 std::unique_ptr FDT(

62 new FDSimpleRemoteEPCTransport(C, InFD, OutFD));

63 return std::move(FDT);

64#else

66 "thread support, but llvm was built with "

67 "LLVM_ENABLE_THREADS=Off",

69#endif

70}

71

73#if LLVM_ENABLE_THREADS

74 ListenerThread.join();

75#endif

76}

77

79#if LLVM_ENABLE_THREADS

80 ListenerThread = std::thread([this]() { listenLoop(); });

82#endif

83 llvm_unreachable("Should not be called with LLVM_ENABLE_THREADS=Off");

84}

85

90 char HeaderBuffer[FDMsgHeader::Size];

91

93 FDMsgHeader::Size + ArgBytes.size();

99

100 std::lock_guardstd::mutex Lock(M);

101 if (Disconnected)

104 if (int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size))

105 return errorCodeToError(std::error_code(ErrNo, std::generic_category()));

106 if (int ErrNo = writeBytes(ArgBytes.data(), ArgBytes.size()))

107 return errorCodeToError(std::error_code(ErrNo, std::generic_category()));

109}

110

112 if (Disconnected)

113 return;

114

115 Disconnected = true;

116 bool CloseOutFD = InFD != OutFD;

117

118

119 while (close(InFD) == -1) {

120 if (errno == EBADF)

121 break;

122 }

123

124

125 if (CloseOutFD) {

126 while (close(OutFD) == -1) {

127 if (errno == EBADF)

128 break;

129 }

130 }

131}

132

137

138Error FDSimpleRemoteEPCTransport::readBytes(char *Dst, size_t Size,

139 bool *IsEOF) {

140 assert((Size == 0 || Dst) && "Attempt to read into null.");

141 ssize_t Completed = 0;

142 while (Completed < static_cast<ssize_t>(Size)) {

143 ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed);

144 if (Read <= 0) {

145 auto ErrNo = errno;

146 if (Read == 0) {

147 if (Completed == 0 && IsEOF) {

148 *IsEOF = true;

150 } else

152 } else if (ErrNo == EAGAIN || ErrNo == EINTR)

153 continue;

154 else {

155 std::lock_guardstd::mutex Lock(M);

156 if (Disconnected && IsEOF) {

157 *IsEOF = true;

159 }

161 std::error_code(ErrNo, std::generic_category()));

162 }

163 }

164 Completed += Read;

165 }

167}

168

169int FDSimpleRemoteEPCTransport::writeBytes(const char *Src, size_t Size) {

170 assert((Size == 0 || Src) && "Attempt to append from null.");

171 ssize_t Completed = 0;

172 while (Completed < static_cast<ssize_t>(Size)) {

173 ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed);

174 if (Written < 0) {

175 auto ErrNo = errno;

176 if (ErrNo == EAGAIN || ErrNo == EINTR)

177 continue;

178 else

179 return ErrNo;

180 }

181 Completed += Written;

182 }

183 return 0;

184}

185

186void FDSimpleRemoteEPCTransport::listenLoop() {

188 do {

189

190 char HeaderBuffer[FDMsgHeader::Size];

191

192 {

193 bool IsEOF = false;

194 if (auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) {

195 Err = joinErrors(std::move(Err), std::move(Err2));

196 break;

197 }

198 if (IsEOF)

199 break;

200 }

201

202

203 uint64_t MsgSize;

205 uint64_t SeqNo;

206 ExecutorAddr TagAddr;

207

208 MsgSize =

212 SeqNo =

214 TagAddr.setValue(

216

217 if (MsgSize < FDMsgHeader::Size) {

221 break;

222 }

223

224

226 ArgBytes.resize(MsgSize - FDMsgHeader::Size);

227 if (auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) {

228 Err = joinErrors(std::move(Err), std::move(Err2));

229 break;

230 }

231

232 if (auto Action = C.handleMessage(OpC, SeqNo, TagAddr, ArgBytes)) {

234 break;

235 } else {

236 Err = joinErrors(std::move(Err), Action.takeError());

237 break;

238 }

239 } while (true);

240

241

242

244

245

246 C.handleDisconnect(std::move(Err));

247}

248

249}

250}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

Represents an address in the executor process.

uint64_t getValue() const

void disconnect() override

Trigger disconnection from the transport.

Definition SimpleRemoteEPCUtils.cpp:111

static Expected< std::unique_ptr< FDSimpleRemoteEPCTransport > > Create(SimpleRemoteEPCTransportClient &C, int InFD, int OutFD)

Create a FDSimpleRemoteEPCTransport using the given FDs for reading (InFD) and writing (OutFD).

Definition SimpleRemoteEPCUtils.cpp:50

Error start() override

Called during setup of the client to indicate that the client is ready to receive messages.

Definition SimpleRemoteEPCUtils.cpp:78

Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, ArrayRef< char > ArgBytes) override

Send a SimpleRemoteEPC message.

Definition SimpleRemoteEPCUtils.cpp:86

~FDSimpleRemoteEPCTransport() override

Definition SimpleRemoteEPCUtils.cpp:72

virtual ~SimpleRemoteEPCTransportClient()

virtual ~SimpleRemoteEPCTransport()

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

LLVM_ABI const char * DispatchFnName

Definition SimpleRemoteEPCUtils.cpp:42

LLVM_ABI const char * ExecutorSessionObjectName

Definition SimpleRemoteEPCUtils.cpp:40

SmallVector< char, 128 > SimpleRemoteEPCArgBytesVector

static Error makeUnexpectedEOFError()

Definition SimpleRemoteEPCUtils.cpp:133

detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

Error joinErrors(Error E1, Error E2)

Concatenate errors.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.