From b5eb00c20a21d346eedd20904e0b31768f172465 Mon Sep 17 00:00:00 2001 From: Logan Chien Date: Fri, 18 May 2012 19:56:46 +0800 Subject: Use multithread while compiling LLVM bitcode. Since the LLVM multithread issue has been resolved, we can use multithreaded compilation instead of multi-process with pipe. With this CL, we can reduce the strange deadlock between "main" and "Compile Worker" process. Change-Id: Ib2db7eb371347d6631a0dfc51a959a6237b5e513 --- src/compiler_llvm/compilation_unit.cc | 99 ++++------------------------------- 1 file changed, 9 insertions(+), 90 deletions(-) (limited to 'src/compiler_llvm/compilation_unit.cc') diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc index 598a8b3f11..b8e88504a3 100644 --- a/src/compiler_llvm/compilation_unit.cc +++ b/src/compiler_llvm/compilation_unit.cc @@ -206,98 +206,17 @@ CompilationUnit::~CompilationUnit() { bool CompilationUnit::Materialize(size_t thread_count) { MutexLock GUARD(cunit_lock_); - if (thread_count == 1) { - llvm::raw_string_ostream str_os(elf_image_); - bool success = MaterializeToFile(str_os); - LOG(INFO) << "Compilation Unit: " << elf_idx_ << (success ? " (done)" : " (failed)"); + // Materialize the bitcode to elf_image_ + llvm::raw_string_ostream str_os(elf_image_); + bool success = MaterializeToFile(str_os); + LOG(INFO) << "Compilation Unit: " << elf_idx_ << (success ? " (done)" : " (failed)"); - // Free the resources - context_.reset(NULL); - irb_.reset(NULL); - module_ = NULL; + // Free the resources + context_.reset(NULL); + irb_.reset(NULL); + module_ = NULL; - return success; - } - - // Prepare the pipe between parent process and child process - int pipe_fd[2]; - if (pipe(pipe_fd) == -1) { - PLOG(FATAL) << "Failed to create pipe for CompilerWorker"; - return false; - } - - // Fork a process to do the compilation - pid_t pid = fork(); - if (pid < 0) { - close(pipe_fd[0]); - close(pipe_fd[1]); - PLOG(FATAL) << "Failed to fork a process to do the compilation"; - return false; - - } else if (pid == 0) { // Child process - // Close the unused pipe read end - close(pipe_fd[0]); - - // Change process groups, so we don't get ripped by ProcessManager - setpgid(0, 0); - - llvm::raw_fd_ostream fd_os(pipe_fd[1], /* shouldClose */true); - - // TODO: Should use exec* family instead of invoking a function. - // Forward our compilation request to bcc. - exit(static_cast(!MaterializeToFile(fd_os))); - - } else { // Parent process - // Close the unused pipe write end - close(pipe_fd[1]); - - // Free the resources - context_.reset(NULL); - irb_.reset(NULL); - module_ = NULL; - - // Read the result out from the pipe read end (until failure) - const size_t buf_size = 1024; - std::vector buf(buf_size); - while (true) { - // Read from the pipe - ssize_t nread = read(pipe_fd[0], &*buf.begin(), buf_size); - if (nread < 0) { - if (errno == EAGAIN || errno == EINTR) { - continue; - } else { - LOG(ERROR) << "Unexpected error during IPC: " << strerror(errno); - } - } - - // Append to the end of the elf_image_ - elf_image_.append(buf.begin(), buf.begin() + nread); - - if (nread < static_cast(buf_size)) { // EOF reached! - break; - } - } - - close(pipe_fd[0]); - - // Wait for child to finish - int status; - pid_t got_pid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); - if (got_pid != pid) { - PLOG(ERROR) << "waitpid failed: wanted " << pid << ", got " << got_pid; - elf_image_.clear(); - return false; - } - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { - LOG(ERROR) << "Failed to compile the bitcode: " << WEXITSTATUS(status); - elf_image_.clear(); - return false; - } - - LOG(INFO) << "Compilation Unit: " << elf_idx_ << " (done)"; - return true; - } + return success; } -- cgit v1.2.3-59-g8ed1b