LLVM API Documentation

Process.inc

Go to the documentation of this file.
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 }