1//===------ SimpleRemoteEPCUtils.cpp - Utils for Simple Remote EPC --------===//
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
7//===----------------------------------------------------------------------===//
9// Message definitions and other utilities for SimpleRemoteEPC and
10// SimpleRemoteEPCServer.
12//===----------------------------------------------------------------------===//
15#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_THREADS
18#if !defined(_MSC_VER) && !defined(__MINGW32__)
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);
41 "__llvm_orc_SimpleRemoteEPC_dispatch_ctx";
44}
// end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames
52#if LLVM_ENABLE_THREADS
61 std::unique_ptr<FDSimpleRemoteEPCTransport> FDT(
62 new FDSimpleRemoteEPCTransport(C, InFD, OutFD));
63 return std::move(FDT);
66 "thread support, but llvm was built with "
67 "LLVM_ENABLE_THREADS=Off",
73#if LLVM_ENABLE_THREADS
74 ListenerThread.join();
79#if LLVM_ENABLE_THREADS
80 ListenerThread = std::thread([
this]() { listenLoop(); });
90 char HeaderBuffer[FDMsgHeader::Size];
93 FDMsgHeader::Size + ArgBytes.
size();
100 std::lock_guard<std::mutex> Lock(M);
104 if (
int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size))
106 if (
int ErrNo = writeBytes(ArgBytes.
data(), ArgBytes.
size()))
113 return;
// Return if already disconnected.
116 bool CloseOutFD = InFD != OutFD;
119 while (close(InFD) == -1) {
126 while (close(OutFD) == -1) {
138Error FDSimpleRemoteEPCTransport::readBytes(
char *Dst,
size_t Size,
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);
147 if (Completed == 0 && IsEOF) {
152 }
else if (ErrNo == EAGAIN || ErrNo == EINTR)
155 std::lock_guard<std::mutex> Lock(M);
156 if (Disconnected && IsEOF) {
// disconnect called, pretend this is EOF.
161 std::error_code(ErrNo, std::generic_category()));
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);
176 if (ErrNo == EAGAIN || ErrNo == EINTR)
181 Completed += Written;
186void FDSimpleRemoteEPCTransport::listenLoop() {
190 char HeaderBuffer[FDMsgHeader::Size];
191 // Read the header buffer.
194 if (
auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) {
195 Err =
joinErrors(std::move(Err), std::move(Err2));
202 // Decode header buffer.
206 ExecutorAddr TagAddr;
217 if (MsgSize < FDMsgHeader::Size) {
224 // Read the argument bytes.
226 ArgBytes.
resize(MsgSize - FDMsgHeader::Size);
227 if (
auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) {
228 Err =
joinErrors(std::move(Err), std::move(Err2));
232 if (
auto Action = C.handleMessage(OpC, SeqNo, TagAddr, ArgBytes)) {
236 Err =
joinErrors(std::move(Err), Action.takeError());
241 // Attempt to close FDs, set Disconnected to true so that subsequent
242 // sendMessage calls fail.
245 // Call up to the client to handle the disconnection.
246 C.handleDisconnect(std::move(Err));
249}
// end namespace orc
250}
// end namespace llvm
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.
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).
Error start() override
Called during setup of the client to indicate that the client is ready to receive messages.
Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, ArrayRef< char > ArgBytes) override
Send a SimpleRemoteEPC message.
~FDSimpleRemoteEPCTransport() override
virtual ~SimpleRemoteEPCTransportClient()
virtual ~SimpleRemoteEPCTransport()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI const char * DispatchFnName
LLVM_ABI const char * ExecutorSessionObjectName
SmallVector< char, 128 > SimpleRemoteEPCArgBytesVector
static Error makeUnexpectedEOFError()
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.
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.