aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/Unix
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-30 11:34:40 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-30 11:34:40 -0800
commit1843e19bce9b11fc840858e136c6c52cf8b42e0b (patch)
treee8bfc928152e2d3b3dd120d141d13dc08a9b49e4 /lib/Support/Unix
parentaa0fa8a8df25807f784ec9ca9deeb40328636595 (diff)
parenta662a9862501fc86904e90054f7c1519101d9126 (diff)
Merge commit 'a662a9862501fc86904e90054f7c1519101d9126'
Conflicts: include/llvm/CodeGen/IntrinsicLowering.h include/llvm/MC/MCAssembler.h include/llvm/MC/MCObjectStreamer.h lib/LLVMBuild.txt lib/Linker/LinkArchives.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCPureStreamer.cpp lib/MC/WinCOFFStreamer.cpp lib/Makefile lib/Support/Unix/Memory.inc lib/Support/Unix/Process.inc lib/Support/Unix/Program.inc lib/Target/ARM/ARM.h lib/Target/ARM/ARMFastISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/X86/CMakeLists.txt lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86TargetMachine.cpp lib/Target/X86/X86TargetObjectFile.cpp lib/Transforms/InstCombine/InstCombineCalls.cpp test/CodeGen/X86/fast-isel-x86-64.ll tools/llc/llc.cpp tools/lto/LTOModule.cpp utils/TableGen/EDEmitter.cpp
Diffstat (limited to 'lib/Support/Unix')
-rw-r--r--lib/Support/Unix/Memory.inc20
-rw-r--r--lib/Support/Unix/PathV2.inc13
-rw-r--r--lib/Support/Unix/Process.inc102
-rw-r--r--lib/Support/Unix/Program.inc23
-rw-r--r--lib/Support/Unix/Signals.inc26
5 files changed, 84 insertions, 100 deletions
diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc
index f4cfbc65cf..8a766f041e 100644
--- a/lib/Support/Unix/Memory.inc
+++ b/lib/Support/Unix/Memory.inc
@@ -12,11 +12,9 @@
//===----------------------------------------------------------------------===//
#include "Unix.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Process.h"
-#include "llvm/Support/Debug.h"
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
@@ -75,7 +73,7 @@ Memory::allocateMappedMemory(size_t NumBytes,
if (NumBytes == 0)
return MemoryBlock();
- static const size_t PageSize = Process::GetPageSize();
+ static const size_t PageSize = process::get_self()->page_size();
const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
@@ -172,8 +170,8 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
- size_t pageSize = Process::GetPageSize();
- size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+ size_t PageSize = process::get_self()->page_size();
+ size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
#ifdef NEED_DEV_ZERO_FOR_MMAP
@@ -197,13 +195,11 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
NearBlock->size() : 0;
#if defined(__APPLE__) && defined(__arm__)
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC,
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC,
flags, fd, 0);
#else
-dbgs() << "calling mmap, start " << start << "\n";
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
flags, fd, 0);
- DEBUG(dbgs() << "mmap returned " << pa<<"\n");
#endif
if (pa == MAP_FAILED) {
if (NearBlock) //Try again without a near hint
@@ -215,7 +211,7 @@ dbgs() << "calling mmap, start " << start << "\n";
#if defined(__APPLE__) && defined(__arm__)
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
+ (vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect max RX failed");
@@ -223,7 +219,7 @@ dbgs() << "calling mmap, start " << start << "\n";
}
kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
+ (vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_WRITE);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect RW failed");
@@ -233,7 +229,7 @@ dbgs() << "calling mmap, start " << start << "\n";
MemoryBlock result;
result.Address = pa;
- result.Size = NumPages*pageSize;
+ result.Size = NumPages*PageSize;
return result;
}
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index 820041bccc..b5b76867ec 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -450,11 +450,12 @@ retry_random_path:
rety_open_create:
int RandomFD = ::open(RandomPath.c_str(), O_RDWR | O_CREAT | O_EXCL, mode);
if (RandomFD == -1) {
+ int SavedErrno = errno;
// If the file existed, try again, otherwise, error.
- if (errno == errc::file_exists)
+ if (SavedErrno == errc::file_exists)
goto retry_random_path;
// If path prefix doesn't exist, try to create it.
- if (errno == errc::no_such_file_or_directory &&
+ if (SavedErrno == errc::no_such_file_or_directory &&
!exists(path::parent_path(RandomPath))) {
StringRef p(RandomPath);
SmallString<64> dir_to_create;
@@ -469,13 +470,15 @@ rety_open_create:
(*i)[1] == '/' &&
(*i)[2] != '/')
return make_error_code(errc::no_such_file_or_directory);
- if (::mkdir(dir_to_create.c_str(), 0700) == -1)
+ if (::mkdir(dir_to_create.c_str(), 0700) == -1 &&
+ errno != errc::file_exists)
return error_code(errno, system_category());
}
}
goto rety_open_create;
}
- return error_code(errno, system_category());
+
+ return error_code(SavedErrno, system_category());
}
// Make the path absolute.
@@ -616,7 +619,7 @@ const char *mapped_file_region::const_data() const {
}
int mapped_file_region::alignment() {
- return Process::GetPageSize();
+ return process::get_self()->page_size();
}
error_code detail::directory_iterator_construct(detail::DirIterState &it,
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index b2983b21f7..c246634321 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -46,9 +46,49 @@
using namespace llvm;
using namespace sys;
-unsigned
-Process::GetPageSize()
-{
+
+process::id_type self_process::get_id() {
+ return getpid();
+}
+
+static std::pair<TimeValue, TimeValue> getRUsageTimes() {
+#if defined(HAVE_GETRUSAGE)
+ struct rusage RU;
+ ::getrusage(RUSAGE_SELF, &RU);
+ return std::make_pair(
+ TimeValue(
+ static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(
+ RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
+ TimeValue(
+ static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(
+ RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
+#else
+#warning Cannot get usage times on this platform
+ return std::make_pair(TimeValue(), TimeValue());
+#endif
+}
+
+TimeValue self_process::get_user_time() const {
+#if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0
+ // Try to get a high resolution CPU timer.
+ struct timespec TS;
+ if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0)
+ return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec));
+#endif
+
+ // Otherwise fall back to rusage based timing.
+ return getRUsageTimes().first;
+}
+
+TimeValue self_process::get_system_time() const {
+ // We can only collect system time by inspecting the results of getrusage.
+ return getRUsageTimes().second;
+}
+
+static unsigned getPageSize() {
#if defined(__CYGWIN__)
// On Cygwin, getpagesize() returns 64k but the page size for the purposes of
// memory protection and mmap() is 4k.
@@ -65,6 +105,12 @@ Process::GetPageSize()
return static_cast<unsigned>(page_size);
}
+// This constructor guaranteed to be run exactly once on a single thread, and
+// sets up various process invariants that can be queried cheaply from then on.
+self_process::self_process() : PageSize(getPageSize()) {
+}
+
+
size_t Process::GetMallocUsage() {
#if defined(HAVE_MALLINFO)
struct mallinfo mi;
@@ -89,49 +135,10 @@ size_t Process::GetMallocUsage() {
#endif
}
-size_t
-Process::GetTotalMemoryUsage()
-{
-#if defined(HAVE_MALLINFO)
- struct mallinfo mi = ::mallinfo();
- return mi.uordblks + mi.hblkhd;
-#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
- malloc_statistics_t Stats;
- malloc_zone_statistics(malloc_default_zone(), &Stats);
- return Stats.size_allocated; // darwin
-#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- return usage.ru_maxrss;
-#else
-#warning Cannot get total memory size on this platform
- return 0;
-#endif
-}
-
-void
-Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
- TimeValue& sys_time)
-{
+void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time) {
elapsed = TimeValue::now();
-#if defined(HAVE_GETRUSAGE) && !defined(__native_client__)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- user_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
- sys_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
-#else
-#warning Cannot get usage times on this platform
- user_time.seconds(0);
- user_time.microseconds(0);
- sys_time.seconds(0);
- sys_time.microseconds(0);
-#endif
+ llvm::tie(user_time, sys_time) = getRUsageTimes();
}
int Process::GetCurrentUserId() {
@@ -333,7 +340,7 @@ static unsigned GetRandomNumberSeed() {
// Otherwise, swizzle the current time and the process ID to form a reasonable
// seed.
- TimeValue Now = llvm::TimeValue::now();
+ TimeValue Now = TimeValue::now();
return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
}
#endif
@@ -347,6 +354,3 @@ unsigned llvm::sys::Process::GetRandomNumber() {
return ::rand();
#endif
}
-
-#if !defined(__native_client__)
-#endif
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc
index 9c34f2ba1a..13626d1106 100644
--- a/lib/Support/Unix/Program.inc
+++ b/lib/Support/Unix/Program.inc
@@ -47,11 +47,6 @@ Program::Program() : Data_(0) {}
Program::~Program() {}
-unsigned Program::GetPid() const {
- uint64_t pid = reinterpret_cast<uint64_t>(Data_);
- return static_cast<unsigned>(pid);
-}
-
// This function just uses the PATH environment variable to find the program.
Path
Program::FindProgramByName(const std::string& progName) {
@@ -407,25 +402,7 @@ Program::Wait(const sys::Path &path,
MakeErrMsg(ErrMsg, "PNACL does not know how to wait for a child process!");
return -1;
#endif // (__native_client__)
-}
-
-bool
-Program::Kill(std::string* ErrMsg) {
#if !defined(__native_client__)
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return true;
- }
-
- uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
- pid_t pid = static_cast<pid_t>(pid64);
-
- if (kill(pid, SIGKILL) != 0) {
- MakeErrMsg(ErrMsg, "The process couldn't be killed!");
- return true;
- }
-
- return false;
#else // (__native_client__)
MakeErrMsg(ErrMsg, "PNACL does not know how to kill processes!");
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc
index 7aa43f6dce..b64ec8cc03 100644
--- a/lib/Support/Unix/Signals.inc
+++ b/lib/Support/Unix/Signals.inc
@@ -260,7 +260,7 @@ void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
//
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
-static void PrintStackTrace(void *) {
+void llvm::sys::PrintStackTrace(FILE *FD) {
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
static void* StackTrace[256];
// Use backtrace() to output a backtrace on Linux systems with glibc.
@@ -284,26 +284,26 @@ static void PrintStackTrace(void *) {
Dl_info dlinfo;
dladdr(StackTrace[i], &dlinfo);
- fprintf(stderr, "%-2d", i);
+ fprintf(FD, "%-2d", i);
const char* name = strrchr(dlinfo.dli_fname, '/');
- if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
- else fprintf(stderr, " %-*s", width, name+1);
+ if (name == NULL) fprintf(FD, " %-*s", width, dlinfo.dli_fname);
+ else fprintf(FD, " %-*s", width, name+1);
- fprintf(stderr, " %#0*lx",
+ fprintf(FD, " %#0*lx",
(int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
if (dlinfo.dli_sname != NULL) {
int res;
- fputc(' ', stderr);
+ fputc(' ', FD);
char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
- if (d == NULL) fputs(dlinfo.dli_sname, stderr);
- else fputs(d, stderr);
+ if (d == NULL) fputs(dlinfo.dli_sname, FD);
+ else fputs(d, FD);
free(d);
- fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
+ fprintf(FD, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
}
- fputc('\n', stderr);
+ fputc('\n', FD);
}
#else
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
@@ -311,10 +311,14 @@ static void PrintStackTrace(void *) {
#endif
}
+static void PrintStackTraceSignalHandler(void *) {
+ PrintStackTrace(stderr);
+}
+
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal() {
- AddSignalHandler(PrintStackTrace, 0);
+ AddSignalHandler(PrintStackTraceSignalHandler, 0);
#if defined(__APPLE__)
// Environment variable to disable any kind of crash dialog.