LLVM API Documentation

Unix/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 is distributed under the University of Illinois Open Source
00006 // 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 using 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   return getuid();
00120 }
00121 
00122 int Process::GetCurrentGroupId() {
00123   return getgid();
00124 }
00125 
00126 #ifdef HAVE_MACH_MACH_H
00127 #include <mach/mach.h>
00128 #endif
00129 
00130 // Some LLVM programs such as bugpoint produce core files as a normal part of
00131 // their operation. To prevent the disk from filling up, this function
00132 // does what's necessary to prevent their generation.
00133 void Process::PreventCoreFiles() {
00134 #if HAVE_SETRLIMIT
00135   struct rlimit rlim;
00136   rlim.rlim_cur = rlim.rlim_max = 0;
00137   setrlimit(RLIMIT_CORE, &rlim);
00138 #endif
00139 
00140 #ifdef HAVE_MACH_MACH_H
00141   // Disable crash reporting on Mac OS X 10.0-10.4
00142 
00143   // get information about the original set of exception ports for the task
00144   mach_msg_type_number_t Count = 0;
00145   exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
00146   exception_port_t OriginalPorts[EXC_TYPES_COUNT];
00147   exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
00148   thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
00149   kern_return_t err = 
00150     task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
00151                              &Count, OriginalPorts, OriginalBehaviors,
00152                              OriginalFlavors);
00153   if (err == KERN_SUCCESS) {
00154     // replace each with MACH_PORT_NULL.
00155     for (unsigned i = 0; i != Count; ++i)
00156       task_set_exception_ports(mach_task_self(), OriginalMasks[i], 
00157                                MACH_PORT_NULL, OriginalBehaviors[i],
00158                                OriginalFlavors[i]);
00159   }
00160 
00161   // Disable crash reporting on Mac OS X 10.5
00162   signal(SIGABRT, _exit);
00163   signal(SIGILL,  _exit);
00164   signal(SIGFPE,  _exit);
00165   signal(SIGSEGV, _exit);
00166   signal(SIGBUS,  _exit);
00167 #endif
00168 }
00169 
00170 bool Process::StandardInIsUserInput() {
00171 #if HAVE_ISATTY
00172   return isatty(0);
00173 #endif
00174   // If we don't have isatty, just return false.
00175   return false;
00176 }
00177 
00178 bool Process::StandardOutIsDisplayed() {
00179 #if HAVE_ISATTY
00180   return isatty(1);
00181 #endif
00182   // If we don't have isatty, just return false.
00183   return false;
00184 }
00185 
00186 bool Process::StandardErrIsDisplayed() {
00187 #if HAVE_ISATTY
00188   return isatty(2);
00189 #endif
00190   // If we don't have isatty, just return false.
00191   return false;
00192 }



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.