Don't pull in environ, not always safe. Global variables are bad anyway.
[oota-llvm.git] / lib / System / Unix / Process.inc
1 //===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the 
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file provides the generic Unix implementation of the Process class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Unix.h"
15 #ifdef HAVE_SYS_TIME_H
16 #include <sys/time.h>
17 #endif
18 #ifdef HAVE_SYS_RESOURCE_H
19 #include <sys/resource.h>
20 #endif
21 #ifdef HAVE_MALLOC_H
22 #include <malloc.h>
23 #endif
24 #ifdef HAVE_MALLOC_MALLOC_H
25 #include <malloc/malloc.h>
26 #endif
27
28 //===----------------------------------------------------------------------===//
29 //=== WARNING: Implementation here must contain only generic UNIX code that
30 //===          is guaranteed to work on *all* UNIX variants.
31 //===----------------------------------------------------------------------===//
32
33 namespace llvm {
34 using namespace sys;
35
36 unsigned 
37 Process::GetPageSize() 
38 {
39 #if defined(HAVE_GETPAGESIZE)
40   static const int page_size = ::getpagesize();
41 #elif defined(HAVE_SYSCONF)
42   static long page_size = ::sysconf(_SC_PAGE_SIZE);
43 #else
44 #warning Cannot get the page size on this machine
45 #endif
46   return static_cast<unsigned>(page_size);
47 }
48
49 size_t Process::GetMallocUsage() {
50 #if defined(HAVE_MALLINFO)
51   struct mallinfo mi;
52   mi = ::mallinfo();
53   return mi.uordblks;
54 #elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
55   malloc_statistics_t Stats;
56   malloc_zone_statistics(malloc_default_zone(), &Stats);
57   return Stats.size_in_use;   // darwin
58 #elif defined(HAVE_SBRK)
59   // Note this is only an approximation and more closely resembles
60   // the value returned by mallinfo in the arena field.
61   static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
62   char *EndOfMemory = (char*)sbrk(0);
63   if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
64     return EndOfMemory - StartOfMemory;
65   else
66     return 0;
67 #else
68 #warning Cannot get malloc info on this platform
69   return 0;
70 #endif
71 }
72
73 size_t
74 Process::GetTotalMemoryUsage()
75 {
76 #if defined(HAVE_MALLINFO)
77   struct mallinfo mi = ::mallinfo();
78   return mi.uordblks + mi.hblkhd;
79 #elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
80   malloc_statistics_t Stats;
81   malloc_zone_statistics(malloc_default_zone(), &Stats);
82   return Stats.size_allocated;   // darwin
83 #elif defined(HAVE_GETRUSAGE)
84   struct rusage usage;
85   ::getrusage(RUSAGE_SELF, &usage);
86   return usage.ru_maxrss;
87 #else
88 #warning Cannot get total memory size on this platform
89   return 0;
90 #endif
91 }
92
93 void
94 Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time, 
95                       TimeValue& sys_time)
96 {
97   elapsed = TimeValue::now();
98 #if defined(HAVE_GETRUSAGE)
99   struct rusage usage;
100   ::getrusage(RUSAGE_SELF, &usage);
101   user_time = TimeValue( 
102     static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ), 
103     static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec * 
104       TimeValue::NANOSECONDS_PER_MICROSECOND ) );
105   sys_time = TimeValue( 
106     static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ), 
107     static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec * 
108       TimeValue::NANOSECONDS_PER_MICROSECOND ) );
109 #else
110 #warning Cannot get usage times on this platform
111   user_time.seconds(0);
112   user_time.microseconds(0);
113   sys_time.seconds(0);
114   sys_time.microseconds(0);
115 #endif
116 }
117
118 int Process::GetCurrentUserId()
119 {
120   return getuid();
121 }
122
123 int Process::GetCurrentGroupId()
124 {
125   return getgid();
126 }
127
128 // Some LLVM programs such as bugpoint produce core files as a normal part of
129 // their operation. To prevent the disk from filling up, this function
130 // does what's necessary to prevent their generation.
131 void Process::PreventCoreFiles() {
132 #if HAVE_SETRLIMIT
133   struct rlimit rlim;
134   rlim.rlim_cur = rlim.rlim_max = 0;
135   setrlimit(RLIMIT_CORE, &rlim);
136 #endif
137 }
138
139 bool Process::StandardInIsUserInput() {
140 #if HAVE_ISATTY
141   return isatty(0);
142 #endif
143   // If we don't have isatty, just return false.
144   return false;
145 }
146
147 bool Process::StandardOutIsDisplayed() {
148 #if HAVE_ISATTY
149   return isatty(1);
150 #endif
151   // If we don't have isatty, just return false.
152   return false;
153 }
154
155 bool Process::StandardErrIsDisplayed() {
156 #if HAVE_ISATTY
157   return isatty(2);
158 #endif
159   // If we don't have isatty, just return false.
160   return false;
161 }
162
163 }