1//=- RemoteTargetExternal.inc - LLVM out-of-process JIT execution for Unix --=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Implementation of the Unix-specific parts of the RemoteTargetExternal class 11// which executes JITed code in a separate process from where it was built. 12// 13//===----------------------------------------------------------------------===// 14 15#include <unistd.h> 16#include <stdio.h> 17#include <stdlib.h> 18#include <sys/wait.h> 19 20namespace { 21 22struct ConnectionData_t { 23 int InputPipe; 24 int OutputPipe; 25 26 ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {} 27}; 28 29} // namespace 30 31namespace llvm { 32 33void RemoteTargetExternal::create() { 34 int PipeFD[2][2]; 35 pid_t ChildPID; 36 37 // Create two pipes. 38 if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0) 39 perror("Error creating pipe: "); 40 41 ChildPID = fork(); 42 43 if (ChildPID == 0) { 44 // In the child... 45 46 // Close the parent ends of the pipes 47 close(PipeFD[0][1]); 48 close(PipeFD[1][0]); 49 50 // Use our pipes as stdin and stdout 51 if (PipeFD[0][0] != STDIN_FILENO) { 52 dup2(PipeFD[0][0], STDIN_FILENO); 53 close(PipeFD[0][0]); 54 } 55 if (PipeFD[1][1] != STDOUT_FILENO) { 56 dup2(PipeFD[1][1], STDOUT_FILENO); 57 close(PipeFD[1][1]); 58 } 59 60 // Execute the child process. 61 char *args[1] = { NULL }; 62 int rc = execv(ChildName.c_str(), args); 63 if (rc != 0) 64 perror("Error executing child process: "); 65 } 66 else { 67 // In the parent... 68 69 // Close the child ends of the pipes 70 close(PipeFD[0][0]); 71 close(PipeFD[1][1]); 72 73 // Store the parent ends of the pipes 74 ConnectionData = (void*)new ConnectionData_t(PipeFD[1][0], PipeFD[0][1]); 75 76 Receive(LLI_ChildActive); 77 } 78} 79 80int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) { 81 return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size); 82} 83 84int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) { 85 return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size); 86} 87 88void RemoteTargetExternal::Wait() { 89 wait(NULL); 90} 91 92RemoteTargetExternal::~RemoteTargetExternal() { 93 delete static_cast<ConnectionData_t *>(ConnectionData); 94} 95 96} // namespace llvm 97