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__) 27staticconstexprunsigned MsgSizeOffset = 0;
28staticconstexprunsigned OpCOffset = MsgSizeOffset +
sizeof(
uint64_t);
29staticconstexprunsigned SeqNoOffset = OpCOffset +
sizeof(
uint64_t);
30staticconstexprunsigned TagAddrOffset = SeqNoOffset +
sizeof(
uint64_t);
31staticconstexprunsignedSize = TagAddrOffset +
sizeof(
uint64_t);
38namespaceSimpleRemoteEPCDefaultBootstrapSymbolNames {
41"__llvm_orc_SimpleRemoteEPC_dispatch_ctx";
44}
// end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames 52#if LLVM_ENABLE_THREADS 54return make_error<StringError>(
"Invalid input file descriptor " +
58return make_error<StringError>(
"Invalid output file descriptor " +
61 std::unique_ptr<FDSimpleRemoteEPCTransport> FDT(
65return make_error<StringError>(
"FD-based SimpleRemoteEPC transport requires " 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(); });
90char HeaderBuffer[FDMsgHeader::Size];
93 FDMsgHeader::Size + ArgBytes.
size();
100 std::lock_guard<std::mutex> Lock(M);
102return make_error<StringError>(
"FD-transport disconnected",
104if (
int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size))
106if (
int ErrNo = writeBytes(ArgBytes.
data(), ArgBytes.
size()))
113return;
// Return if already disconnected. 116bool CloseOutFD = InFD != OutFD;
119while (close(InFD) == -1) {
126while (close(OutFD) == -1) {
134return make_error<StringError>(
"Unexpected end-of-file",
138Error FDSimpleRemoteEPCTransport::readBytes(
char *Dst,
size_tSize,
140assert((
Size == 0 || Dst) &&
"Attempt to read into null.");
141 ssize_t Completed = 0;
142while (Completed <
static_cast<ssize_t
>(
Size)) {
143 ssize_t
Read = ::read(InFD, Dst + Completed,
Size - Completed);
147if (Completed == 0 && IsEOF) {
152 }
elseif (ErrNo == EAGAIN || ErrNo == EINTR)
155 std::lock_guard<std::mutex> Lock(M);
156if (Disconnected && IsEOF) {
// disconnect called, pretend this is EOF. 161 std::error_code(ErrNo, std::generic_category()));
169int FDSimpleRemoteEPCTransport::writeBytes(
constchar *Src,
size_tSize) {
170assert((
Size == 0 || Src) &&
"Attempt to append from null.");
171 ssize_t Completed = 0;
172while (Completed <
static_cast<ssize_t
>(
Size)) {
173 ssize_t Written =
::write(OutFD, Src + Completed,
Size - Completed);
176if (ErrNo == EAGAIN || ErrNo == EINTR)
181 Completed += Written;
186void FDSimpleRemoteEPCTransport::listenLoop() {
190char HeaderBuffer[FDMsgHeader::Size];
191// Read the header buffer. 194if (
auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) {
195 Err =
joinErrors(std::move(Err), std::move(Err2));
202// Decode header buffer. 206 ExecutorAddr TagAddr;
217if (MsgSize < FDMsgHeader::Size) {
219 make_error<StringError>(
"Message size too small",
224// Read the argument bytes. 226 ArgBytes.resize(MsgSize - FDMsgHeader::Size);
227if (
auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) {
228 Err =
joinErrors(std::move(Err), std::move(Err2));
232if (
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. 250}
// end namespace llvm assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
Uses read/write on FileDescriptors for transport.
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 Expected< HandleMessageAction > handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr, SimpleRemoteEPCArgBytesVector ArgBytes)=0
Handle receipt of a message.
virtual void handleDisconnect(Error Err)=0
Handle a disconnection from the underlying transport.
virtual ~SimpleRemoteEPCTransportClient()
virtual ~SimpleRemoteEPCTransport()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
const char * DispatchFnName
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.
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 write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.