Remove attribution from file headers, per discussion on llvmdev.
[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 is distributed under the University of Illinois Open Source
6 // 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 using 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   return getuid();
120 }
121
122 int Process::GetCurrentGroupId() {
123   return getgid();
124 }
125
126 #ifdef HAVE_MACH_MACH_H
127 #include <mach/mach.h>
128 #endif
129
130 // Some LLVM programs such as bugpoint produce core files as a normal part of
131 // their operation. To prevent the disk from filling up, this function
132 // does what's necessary to prevent their generation.
133 void Process::PreventCoreFiles() {
134 #if HAVE_SETRLIMIT
135   struct rlimit rlim;
136   rlim.rlim_cur = rlim.rlim_max = 0;
137   setrlimit(RLIMIT_CORE, &rlim);
138 #endif
139
140 #ifdef HAVE_MACH_MACH_H
141   // Disable crash reporting on Mac OS/X.
142
143   // get information about the original set of exception ports for the task
144   mach_msg_type_number_t Count = 0;
145   exception_mask_t OriginalMasks[EXC_TYPES_COUNT];
146   exception_port_t OriginalPorts[EXC_TYPES_COUNT];
147   exception_behavior_t OriginalBehaviors[EXC_TYPES_COUNT];
148   thread_state_flavor_t OriginalFlavors[EXC_TYPES_COUNT];
149   kern_return_t err = 
150     task_get_exception_ports(mach_task_self(), EXC_MASK_ALL, OriginalMasks,
151                              &Count, OriginalPorts, OriginalBehaviors,
152                              OriginalFlavors);
153   if (err == KERN_SUCCESS) {
154     // replace each with MACH_PORT_NULL.
155     for (unsigned i = 0; i != Count; ++i)
156       task_set_exception_ports(mach_task_self(), OriginalMasks[i], 
157                                MACH_PORT_NULL, OriginalBehaviors[i],
158                                OriginalFlavors[i]);
159   }
160 #endif
161 }
162
163 bool Process::StandardInIsUserInput() {
164 #if HAVE_ISATTY
165   return isatty(0);
166 #endif
167   // If we don't have isatty, just return false.
168   return false;
169 }
170
171 bool Process::StandardOutIsDisplayed() {
172 #if HAVE_ISATTY
173   return isatty(1);
174 #endif
175   // If we don't have isatty, just return false.
176   return false;
177 }
178
179 bool Process::StandardErrIsDisplayed() {
180 #if HAVE_ISATTY
181   return isatty(2);
182 #endif
183   // If we don't have isatty, just return false.
184   return false;
185 }