diff options
author | Andrew Kaylor <andrew.kaylor@intel.com> | 2013-10-02 17:12:36 +0000 |
---|---|---|
committer | Andrew Kaylor <andrew.kaylor@intel.com> | 2013-10-02 17:12:36 +0000 |
commit | 0ab5c6c16b1b09d76c3ba2d70443b10bcc26169c (patch) | |
tree | af098f261c3db5f9da3efd5aa5ab1ca9e05046e0 /tools/lli/Unix | |
parent | af7ae9d6890ce5fae27e38ccebb5da09288c49e0 (diff) | |
download | llvm-0ab5c6c16b1b09d76c3ba2d70443b10bcc26169c.tar.gz llvm-0ab5c6c16b1b09d76c3ba2d70443b10bcc26169c.tar.bz2 llvm-0ab5c6c16b1b09d76c3ba2d70443b10bcc26169c.tar.xz |
Adding out-of-process execution support to lli.
At this time only Unix-based systems are supported. Windows has stubs and should re-route to the simulated mode.
Thanks to Sriram Murali for contributions to this patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191843 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/lli/Unix')
-rw-r--r-- | tools/lli/Unix/RemoteTargetExternal.inc | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RemoteTargetExternal.inc new file mode 100644 index 0000000000..fd6c16b563 --- /dev/null +++ b/tools/lli/Unix/RemoteTargetExternal.inc @@ -0,0 +1,91 @@ +//=- RemoteTargetExternal.inc - LLVM out-of-process 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 RemoteTargetExternal class +// which executes JITed code in a separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/wait.h> + +namespace { + +struct ConnectionData_t { + int InputPipe; + int OutputPipe; + + ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {} +}; + +} // namespace + +namespace llvm { + +void RemoteTargetExternal::create() { + int PipeFD[2][2]; + pid_t ChildPID; + + pipe(PipeFD[0]); + pipe(PipeFD[1]); + + ChildPID = fork(); + + if (ChildPID == 0) { + // In the child... + + // Close the parent ends of the pipes + close(PipeFD[0][1]); + close(PipeFD[1][0]); + + // Use our pipes as stdin and stdout + if (PipeFD[0][0] != STDIN_FILENO) { + dup2(PipeFD[0][0], STDIN_FILENO); + close(PipeFD[0][0]); + } + if (PipeFD[1][1] != STDOUT_FILENO) { + dup2(PipeFD[1][1], STDOUT_FILENO); + close(PipeFD[1][1]); + } + + // Execute the child process. + char *args[1] = { NULL }; + int rc = execv(ChildName.c_str(), args); + if (rc != 0) + perror("Error executing child process: "); + } + else { + // In the parent... + + // Close the child ends of the pipes + close(PipeFD[0][0]); + close(PipeFD[1][1]); + + // Store the parent ends of the pipes + ConnectionData = (void*)new ConnectionData_t(PipeFD[1][0], PipeFD[0][1]); + + Receive(LLI_ChildActive); + } +} + +int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) { + return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size); +} + +int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) { + return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size); +} + +void RemoteTargetExternal::Wait() { + wait(NULL); +} + +} // namespace llvm
\ No newline at end of file |