forked from OSchip/llvm-project
lli: Factor portable messaging into a new RPCChannel facility
The client and server now use a single unified low-level RPC core built around LLVM's existing cross-platform abstractions. llvm-svn: 199947
This commit is contained in:
parent
146b7b1230
commit
632c6cd114
|
@ -1,5 +1,6 @@
|
|||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/Memory.h"
|
||||
#include "../RPCChannel.h"
|
||||
#include "../RemoteTarget.h"
|
||||
#include "../RemoteTargetMessage.h"
|
||||
#include <assert.h>
|
||||
|
@ -12,11 +13,11 @@ using namespace llvm;
|
|||
|
||||
class LLIChildTarget {
|
||||
public:
|
||||
~LLIChildTarget(); // OS-specific destructor
|
||||
void initialize();
|
||||
LLIMessageType waitForIncomingMessage();
|
||||
void handleMessage(LLIMessageType messageType);
|
||||
RemoteTarget *RT;
|
||||
RPCChannel RPC;
|
||||
|
||||
private:
|
||||
// Incoming message handlers
|
||||
|
@ -32,8 +33,10 @@ private:
|
|||
|
||||
// OS-specific functions
|
||||
void initializeConnection();
|
||||
int WriteBytes(const void *Data, size_t Size);
|
||||
int ReadBytes(void *Data, size_t Size);
|
||||
int WriteBytes(const void *Data, size_t Size) {
|
||||
return RPC.WriteBytes(Data, Size);
|
||||
}
|
||||
int ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); }
|
||||
|
||||
// Communication handles (OS-specific)
|
||||
void *ConnectionData;
|
||||
|
@ -55,7 +58,7 @@ int main() {
|
|||
|
||||
// Public methods
|
||||
void LLIChildTarget::initialize() {
|
||||
initializeConnection();
|
||||
RPC.createClient();
|
||||
sendChildActive();
|
||||
}
|
||||
|
||||
|
@ -231,9 +234,9 @@ void LLIChildTarget::sendExecutionComplete(int Result) {
|
|||
}
|
||||
|
||||
#ifdef LLVM_ON_UNIX
|
||||
#include "Unix/ChildTarget.inc"
|
||||
#include "../Unix/RPCChannel.inc"
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_ON_WIN32
|
||||
#include "Windows/ChildTarget.inc"
|
||||
#include "../Windows/RPCChannel.inc"
|
||||
#endif
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
//===- ChildTarget.inc - Child process for external JIT execution for Unix -==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implementation of the Unix-specific parts of the ChildTarget class
|
||||
// which executes JITed code in a separate process from where it was built.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
struct ConnectionData_t {
|
||||
int InputPipe;
|
||||
int OutputPipe;
|
||||
|
||||
ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
LLIChildTarget::~LLIChildTarget() {
|
||||
delete static_cast<ConnectionData_t *>(ConnectionData);
|
||||
}
|
||||
|
||||
// OS-specific methods
|
||||
void LLIChildTarget::initializeConnection() {
|
||||
// Store the parent ends of the pipes
|
||||
ConnectionData = (void*)new ConnectionData_t(STDIN_FILENO, STDOUT_FILENO);
|
||||
}
|
||||
|
||||
int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
|
||||
return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size);
|
||||
}
|
||||
|
||||
int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
|
||||
return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
//=- ChildTarget.inc - Child process for external JIT execution for Windows -=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Non-implementation of the Windows-specific parts of the ChildTarget class
|
||||
// which executes JITed code in a separate process from where it was built.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
LLIChildTarget::~LLIChildTarget() {
|
||||
}
|
||||
|
||||
// The RemoteTargetExternal implementation should prevent us from ever getting
|
||||
// here on Windows, but nothing prevents a user from running this directly.
|
||||
void LLIChildTarget::initializeConnection() {
|
||||
assert(0 && "lli-child-target is not implemented for Windows");
|
||||
}
|
||||
|
||||
int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
//===---------- RPCChannel.h - LLVM out-of-process JIT execution ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Definition of the RemoteTargetExternal class which executes JITed code in a
|
||||
// separate process from where it was built.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLI_RPCCHANNEL_H
|
||||
#define LLI_RPCCHANNEL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class RPCChannel {
|
||||
public:
|
||||
std::string ChildName;
|
||||
|
||||
RPCChannel() {}
|
||||
~RPCChannel();
|
||||
|
||||
static void ReportError(int rc, size_t Size, std::string &ErrorMsg);
|
||||
|
||||
/// Start the remote process.
|
||||
///
|
||||
/// @returns True on success. On failure, ErrorMsg is updated with
|
||||
/// descriptive text of the encountered error.
|
||||
bool createServer();
|
||||
|
||||
bool createClient();
|
||||
|
||||
// This will get filled in as a point to an OS-specific structure.
|
||||
void *ConnectionData;
|
||||
|
||||
int WriteBytes(const void *Data, size_t Size);
|
||||
int ReadBytes(void *Data, size_t Size);
|
||||
|
||||
void Wait();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLI_RPCCHANNEL_H
|
|
@ -111,7 +111,7 @@ bool RemoteTargetExternal::executeCode(uint64_t Address, int32_t &RetVal) {
|
|||
|
||||
void RemoteTargetExternal::stop() {
|
||||
SendTerminate();
|
||||
Wait();
|
||||
RPC.Wait();
|
||||
}
|
||||
|
||||
bool RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {
|
||||
|
@ -317,9 +317,9 @@ void RemoteTargetExternal::AppendRead(void *Data, uint32_t Size) {
|
|||
}
|
||||
|
||||
#ifdef LLVM_ON_UNIX
|
||||
#include "Unix/RemoteTargetExternal.inc"
|
||||
#include "Unix/RPCChannel.inc"
|
||||
#endif
|
||||
|
||||
#ifdef LLVM_ON_WIN32
|
||||
#include "Windows/RemoteTargetExternal.inc"
|
||||
#include "Windows/RPCChannel.inc"
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef LLI_REMOTETARGETEXTERNAL_H
|
||||
#define LLI_REMOTETARGETEXTERNAL_H
|
||||
|
||||
#include "RPCChannel.h"
|
||||
#include "RemoteTarget.h"
|
||||
#include "RemoteTargetMessage.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
@ -28,6 +29,28 @@
|
|||
namespace llvm {
|
||||
|
||||
class RemoteTargetExternal : public RemoteTarget {
|
||||
RPCChannel RPC;
|
||||
|
||||
bool WriteBytes(const void *Data, size_t Size) {
|
||||
int rc = RPC.WriteBytes(Data, Size);
|
||||
if (rc != -1 && (size_t)rc == Size)
|
||||
return true;
|
||||
|
||||
ErrorMsg = "WriteBytes: ";
|
||||
RPC.ReportError(rc, Size, ErrorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReadBytes(void *Data, size_t Size) {
|
||||
int rc = RPC.ReadBytes(Data, Size);
|
||||
if (rc != -1 && (size_t)rc == Size)
|
||||
return true;
|
||||
|
||||
ErrorMsg = "ReadBytes: ";
|
||||
RPC.ReportError(rc, Size, ErrorMsg);
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
/// Allocate space in the remote target address space.
|
||||
///
|
||||
|
@ -79,17 +102,26 @@ public:
|
|||
/// @returns Page alignment return value. Default of 4k.
|
||||
virtual unsigned getPageAlignment() { return 4096; }
|
||||
|
||||
/// Start the remote process.
|
||||
///
|
||||
/// @returns True on success. On failure, ErrorMsg is updated with
|
||||
/// descriptive text of the encountered error.
|
||||
virtual bool create();
|
||||
virtual bool create() {
|
||||
RPC.ChildName = ChildName;
|
||||
if (!RPC.createServer())
|
||||
return true;
|
||||
|
||||
// We must get Ack from the client (blocking read)
|
||||
if (!Receive(LLI_ChildActive)) {
|
||||
ErrorMsg += ", (RPCChannel::create) - Stopping process!";
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Terminate the remote process.
|
||||
virtual void stop();
|
||||
|
||||
RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {}
|
||||
virtual ~RemoteTargetExternal();
|
||||
virtual ~RemoteTargetExternal() {}
|
||||
|
||||
private:
|
||||
std::string ChildName;
|
||||
|
@ -119,13 +151,6 @@ private:
|
|||
SmallVector<int, 2> Sizes;
|
||||
void AppendWrite(const void *Data, uint32_t Size);
|
||||
void AppendRead(void *Data, uint32_t Size);
|
||||
|
||||
// This will get filled in as a point to an OS-specific structure.
|
||||
void *ConnectionData;
|
||||
|
||||
bool WriteBytes(const void *Data, size_t Size);
|
||||
bool ReadBytes(void *Data, size_t Size);
|
||||
void Wait();
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//=- RemoteTargetExternal.inc - LLVM out-of-process JIT execution for Unix --=//
|
||||
//=- RPCChannel.inc - LLVM out-of-process JIT execution for Unix --=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implementation of the Unix-specific parts of the RemoteTargetExternal class
|
||||
// Implementation of the Unix-specific parts of the RPCChannel class
|
||||
// which executes JITed code in a separate process from where it was built.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -30,7 +30,7 @@ struct ConnectionData_t {
|
|||
|
||||
namespace llvm {
|
||||
|
||||
bool RemoteTargetExternal::create() {
|
||||
bool RPCChannel::createServer() {
|
||||
int PipeFD[2][2];
|
||||
pid_t ChildPID;
|
||||
|
||||
|
@ -62,8 +62,7 @@ bool RemoteTargetExternal::create() {
|
|||
int rc = execv(ChildName.c_str(), args);
|
||||
if (rc != 0)
|
||||
perror("Error executing child process: ");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// In the parent...
|
||||
|
||||
// Close the child ends of the pipes
|
||||
|
@ -71,19 +70,19 @@ bool RemoteTargetExternal::create() {
|
|||
close(PipeFD[1][1]);
|
||||
|
||||
// Store the parent ends of the pipes
|
||||
ConnectionData = (void*)new ConnectionData_t(PipeFD[1][0], PipeFD[0][1]);
|
||||
|
||||
// We must get Ack from the client (blocking read)
|
||||
if (!Receive(LLI_ChildActive)) {
|
||||
ErrorMsg += ", (RemoteTargetExternal::create) - Stopping process!";
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
ConnectionData = (void *)new ConnectionData_t(PipeFD[1][0], PipeFD[0][1]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RPCChannel::createClient() {
|
||||
// Store the parent ends of the pipes
|
||||
ConnectionData = (void *)new ConnectionData_t(STDIN_FILENO, STDOUT_FILENO);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ReportError(int rc, size_t Size, std::string &ErrorMsg) {
|
||||
void RPCChannel::ReportError(int rc, size_t Size, std::string &ErrorMsg) {
|
||||
if (rc == -1) {
|
||||
if (errno == EPIPE)
|
||||
ErrorMsg += "pipe closed";
|
||||
|
@ -102,31 +101,17 @@ static void ReportError(int rc, size_t Size, std::string &ErrorMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
bool RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
|
||||
int rc = write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size);
|
||||
if (rc != -1 && (size_t)rc == Size)
|
||||
return true;
|
||||
|
||||
ErrorMsg = "WriteBytes: ";
|
||||
ReportError(rc, Size, ErrorMsg);
|
||||
return false;
|
||||
int RPCChannel::WriteBytes(const void *Data, size_t Size) {
|
||||
return write(((ConnectionData_t *)ConnectionData)->OutputPipe, Data, Size);
|
||||
}
|
||||
|
||||
bool RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
|
||||
int rc = read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
|
||||
if (rc != -1 && (size_t)rc == Size)
|
||||
return true;
|
||||
|
||||
ErrorMsg = "ReadBytes: ";
|
||||
ReportError(rc, Size, ErrorMsg);
|
||||
return false;
|
||||
int RPCChannel::ReadBytes(void *Data, size_t Size) {
|
||||
return read(((ConnectionData_t *)ConnectionData)->InputPipe, Data, Size);
|
||||
}
|
||||
|
||||
void RemoteTargetExternal::Wait() {
|
||||
wait(NULL);
|
||||
}
|
||||
void RPCChannel::Wait() { wait(NULL); }
|
||||
|
||||
RemoteTargetExternal::~RemoteTargetExternal() {
|
||||
RPCChannel::~RPCChannel() {
|
||||
delete static_cast<ConnectionData_t *>(ConnectionData);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
//=- RPCChannel.inc - LLVM out-of-process JIT execution for Windows --=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implementation of the Windows-specific parts of the RPCChannel class
|
||||
// which executes JITed code in a separate process from where it was built.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace llvm {
|
||||
|
||||
bool RPCChannel::createServer() { return false; }
|
||||
|
||||
bool RPCChannel::createClient() { return false; }
|
||||
|
||||
void RPCChannel::ReportError(int rc, size_t Size, std::string &ErrorMsg) {}
|
||||
|
||||
int RPCChannel::WriteBytes(const void *Data, size_t Size) { return -1; }
|
||||
|
||||
int RPCChannel::ReadBytes(void *Data, size_t Size) { return -1; }
|
||||
|
||||
void RPCChannel::Wait() {}
|
||||
|
||||
RPCChannel::~RPCChannel() {}
|
||||
|
||||
} // namespace llvm
|
|
@ -1,36 +0,0 @@
|
|||
//= RemoteTargetExternal.inc - LLVM out-of-process JIT execution for Windows =//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Definition of the Windows-specific parts of the RemoteTargetExternal class
|
||||
// which is meant to execute JITed code in a separate process from where it was
|
||||
// built. To support this functionality on Windows, implement these functions.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace llvm {
|
||||
|
||||
bool RemoteTargetExternal::create() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoteTargetExternal::Wait() {
|
||||
}
|
||||
|
||||
RemoteTargetExternal::~RemoteTargetExternal() {
|
||||
}
|
||||
|
||||
} // namespace llvm
|
Loading…
Reference in New Issue