LLVM API Documentation
00001 //===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Reid Spencer and is distributed under the 00006 // University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides the generic Unix implementation of the Process class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "Unix.h" 00015 #ifdef HAVE_SYS_TIME_H 00016 #include <sys/time.h> 00017 #endif 00018 #ifdef HAVE_SYS_RESOURCE_H 00019 #include <sys/resource.h> 00020 #endif 00021 #ifdef HAVE_MALLOC_H 00022 #include <malloc.h> 00023 #endif 00024 #ifdef HAVE_MALLOC_MALLOC_H 00025 #include <malloc/malloc.h> 00026 #endif 00027 00028 //===----------------------------------------------------------------------===// 00029 //=== WARNING: Implementation here must contain only generic UNIX code that 00030 //=== is guaranteed to work on *all* UNIX variants. 00031 //===----------------------------------------------------------------------===// 00032 00033 namespace llvm { 00034 using namespace sys; 00035 00036 unsigned 00037 Process::GetPageSize() 00038 { 00039 #if defined(HAVE_GETPAGESIZE) 00040 static const int page_size = ::getpagesize(); 00041 #elif defined(HAVE_SYSCONF) 00042 static long page_size = ::sysconf(_SC_PAGE_SIZE); 00043 #else 00044 #warning Cannot get the page size on this machine 00045 #endif 00046 return static_cast<unsigned>(page_size); 00047 } 00048 00049 size_t Process::GetMallocUsage() { 00050 #if defined(HAVE_MALLINFO) 00051 struct mallinfo mi; 00052 mi = ::mallinfo(); 00053 return mi.uordblks; 00054 #elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) 00055 malloc_statistics_t Stats; 00056 malloc_zone_statistics(malloc_default_zone(), &Stats); 00057 return Stats.size_in_use; // darwin 00058 #elif defined(HAVE_SBRK) 00059 // Note this is only an approximation and more closely resembles 00060 // the value returned by mallinfo in the arena field. 00061 static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0)); 00062 char *EndOfMemory = (char*)sbrk(0); 00063 if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1)) 00064 return EndOfMemory - StartOfMemory; 00065 else 00066 return 0; 00067 #else 00068 #warning Cannot get malloc info on this platform 00069 return 0; 00070 #endif 00071 } 00072 00073 size_t 00074 Process::GetTotalMemoryUsage() 00075 { 00076 #if defined(HAVE_MALLINFO) 00077 struct mallinfo mi = ::mallinfo(); 00078 return mi.uordblks + mi.hblkhd; 00079 #elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H) 00080 malloc_statistics_t Stats; 00081 malloc_zone_statistics(malloc_default_zone(), &Stats); 00082 return Stats.size_allocated; // darwin 00083 #elif defined(HAVE_GETRUSAGE) 00084 struct rusage usage; 00085 ::getrusage(RUSAGE_SELF, &usage); 00086 return usage.ru_maxrss; 00087 #else 00088 #warning Cannot get total memory size on this platform 00089 return 0; 00090 #endif 00091 } 00092 00093 void 00094 Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time, 00095 TimeValue& sys_time) 00096 { 00097 elapsed = TimeValue::now(); 00098 #if defined(HAVE_GETRUSAGE) 00099 struct rusage usage; 00100 ::getrusage(RUSAGE_SELF, &usage); 00101 user_time = TimeValue( 00102 static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ), 00103 static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec * 00104 TimeValue::NANOSECONDS_PER_MICROSECOND ) ); 00105 sys_time = TimeValue( 00106 static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ), 00107 static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec * 00108 TimeValue::NANOSECONDS_PER_MICROSECOND ) ); 00109 #else 00110 #warning Cannot get usage times on this platform 00111 user_time.seconds(0); 00112 user_time.microseconds(0); 00113 sys_time.seconds(0); 00114 sys_time.microseconds(0); 00115 #endif 00116 } 00117 00118 int Process::GetCurrentUserId() 00119 { 00120 return getuid(); 00121 } 00122 00123 int Process::GetCurrentGroupId() 00124 { 00125 return getgid(); 00126 } 00127 00128 // Some LLVM programs such as bugpoint produce core files as a normal part of 00129 // their operation. To prevent the disk from filling up, this function 00130 // does what's necessary to prevent their generation. 00131 void Process::PreventCoreFiles() { 00132 #if HAVE_SETRLIMIT 00133 struct rlimit rlim; 00134 rlim.rlim_cur = rlim.rlim_max = 0; 00135 int res = setrlimit(RLIMIT_CORE, &rlim); 00136 if (res != 0) 00137 ThrowErrno("Can't prevent core file generation"); 00138 #endif 00139 } 00140 00141 bool Process::StandardInIsUserInput() { 00142 #if HAVE_ISATTY 00143 return isatty(0); 00144 #endif 00145 // If we don't have isatty, just return false. 00146 return false; 00147 } 00148 00149 bool Process::StandardOutIsDisplayed() { 00150 #if HAVE_ISATTY 00151 return isatty(1); 00152 #endif 00153 // If we don't have isatty, just return false. 00154 return false; 00155 } 00156 00157 bool Process::StandardErrIsDisplayed() { 00158 #if HAVE_ISATTY 00159 return isatty(2); 00160 #endif 00161 // If we don't have isatty, just return false. 00162 return false; 00163 } 00164 00165 }