From 2a02d4bee3f683180a40b65a2c3833ceb64236c3 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Thu, 23 Jan 2014 22:19:45 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199947 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/ChildTarget/ChildTarget.cpp | 15 +++--- tools/lli/ChildTarget/Unix/ChildTarget.inc | 46 ---------------- tools/lli/ChildTarget/Windows/ChildTarget.inc | 30 ----------- tools/lli/RPCChannel.h | 51 ++++++++++++++++++ tools/lli/RemoteTargetExternal.cpp | 6 +-- tools/lli/RemoteTargetExternal.h | 51 +++++++++++++----- ...emoteTargetExternal.inc => RPCChannel.inc} | 53 +++++++------------ tools/lli/Windows/RPCChannel.inc | 31 +++++++++++ tools/lli/Windows/RemoteTargetExternal.inc | 36 ------------- 9 files changed, 151 insertions(+), 168 deletions(-) delete mode 100644 tools/lli/ChildTarget/Unix/ChildTarget.inc delete mode 100644 tools/lli/ChildTarget/Windows/ChildTarget.inc create mode 100644 tools/lli/RPCChannel.h rename tools/lli/Unix/{RemoteTargetExternal.inc => RPCChannel.inc} (64%) create mode 100644 tools/lli/Windows/RPCChannel.inc delete mode 100644 tools/lli/Windows/RemoteTargetExternal.inc diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp index de264af2cdd..1e3000da46a 100644 --- a/tools/lli/ChildTarget/ChildTarget.cpp +++ b/tools/lli/ChildTarget/ChildTarget.cpp @@ -1,5 +1,6 @@ #include "llvm/Config/config.h" #include "llvm/Support/Memory.h" +#include "../RPCChannel.h" #include "../RemoteTarget.h" #include "../RemoteTargetMessage.h" #include @@ -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 diff --git a/tools/lli/ChildTarget/Unix/ChildTarget.inc b/tools/lli/ChildTarget/Unix/ChildTarget.inc deleted file mode 100644 index 67a24ece965..00000000000 --- a/tools/lli/ChildTarget/Unix/ChildTarget.inc +++ /dev/null @@ -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 -#include -#include - -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); -} - -// 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); -} diff --git a/tools/lli/ChildTarget/Windows/ChildTarget.inc b/tools/lli/ChildTarget/Windows/ChildTarget.inc deleted file mode 100644 index 289f27a4703..00000000000 --- a/tools/lli/ChildTarget/Windows/ChildTarget.inc +++ /dev/null @@ -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; -} diff --git a/tools/lli/RPCChannel.h b/tools/lli/RPCChannel.h new file mode 100644 index 00000000000..d04c8c25b49 --- /dev/null +++ b/tools/lli/RPCChannel.h @@ -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 +#include + +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 diff --git a/tools/lli/RemoteTargetExternal.cpp b/tools/lli/RemoteTargetExternal.cpp index 3bf7bf4e3b8..c1bc8dfe99c 100644 --- a/tools/lli/RemoteTargetExternal.cpp +++ b/tools/lli/RemoteTargetExternal.cpp @@ -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 diff --git a/tools/lli/RemoteTargetExternal.h b/tools/lli/RemoteTargetExternal.h index 5ef67100e36..b332b19c0b5 100644 --- a/tools/lli/RemoteTargetExternal.h +++ b/tools/lli/RemoteTargetExternal.h @@ -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 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 diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RPCChannel.inc similarity index 64% rename from tools/lli/Unix/RemoteTargetExternal.inc rename to tools/lli/Unix/RPCChannel.inc index ea8e4597d5f..b7dec37d93d 100644 --- a/tools/lli/Unix/RemoteTargetExternal.inc +++ b/tools/lli/Unix/RPCChannel.inc @@ -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); } diff --git a/tools/lli/Windows/RPCChannel.inc b/tools/lli/Windows/RPCChannel.inc new file mode 100644 index 00000000000..3ad57aecf94 --- /dev/null +++ b/tools/lli/Windows/RPCChannel.inc @@ -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 diff --git a/tools/lli/Windows/RemoteTargetExternal.inc b/tools/lli/Windows/RemoteTargetExternal.inc deleted file mode 100644 index 0a4dba664d7..00000000000 --- a/tools/lli/Windows/RemoteTargetExternal.inc +++ /dev/null @@ -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 -- 2.34.1