blob: addfef358f9b224336caabe7c2850e1470cc6f02 [file] [log] [blame]
Reid Spencer27dafe12004-09-11 04:56:56 +00001//===- Unix/Process.cpp - Unix Process Implementation --------- -*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Reid Spencer27dafe12004-09-11 04:56:56 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file provides the generic Unix implementation of the Process class.
11//
12//===----------------------------------------------------------------------===//
13
Reid Spencer721d9aa2004-12-20 00:59:28 +000014#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
Chris Lattner513a9542005-11-14 07:00:29 +000024#ifdef HAVE_MALLOC_MALLOC_H
25#include <malloc/malloc.h>
26#endif
Reid Spencer27dafe12004-09-11 04:56:56 +000027
28//===----------------------------------------------------------------------===//
29//=== WARNING: Implementation here must contain only generic UNIX code that
30//=== is guaranteed to work on *all* UNIX variants.
31//===----------------------------------------------------------------------===//
32
Chris Lattner26b6c0b2006-09-14 06:01:41 +000033using namespace llvm;
Reid Spencer27dafe12004-09-11 04:56:56 +000034using namespace sys;
35
36unsigned
Reid Spencer721d9aa2004-12-20 00:59:28 +000037Process::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
Reid Spencer27dafe12004-09-11 04:56:56 +000046 return static_cast<unsigned>(page_size);
47}
48
Chris Lattner513a9542005-11-14 07:00:29 +000049size_t Process::GetMallocUsage() {
Reid Spencerbc1ee842004-12-20 16:06:44 +000050#if defined(HAVE_MALLINFO)
Reid Spencer721d9aa2004-12-20 00:59:28 +000051 struct mallinfo mi;
52 mi = ::mallinfo();
53 return mi.uordblks;
Chris Lattnerc590e9a2005-11-14 07:27:56 +000054#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
Reid Spencerbc1ee842004-12-20 16:06:44 +000058#elif defined(HAVE_SBRK)
Reid Spencer721d9aa2004-12-20 00:59:28 +000059 // Note this is only an approximation and more closely resembles
60 // the value returned by mallinfo in the arena field.
Chris Lattner513a9542005-11-14 07:00:29 +000061 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;
Reid Spencer721d9aa2004-12-20 00:59:28 +000065 else
66 return 0;
67#else
68#warning Cannot get malloc info on this platform
69 return 0;
70#endif
71}
72
Jeff Cohene269a1a2005-01-08 20:15:57 +000073size_t
Reid Spencer721d9aa2004-12-20 00:59:28 +000074Process::GetTotalMemoryUsage()
75{
Reid Spencerbc1ee842004-12-20 16:06:44 +000076#if defined(HAVE_MALLINFO)
Reid Spencer721d9aa2004-12-20 00:59:28 +000077 struct mallinfo mi = ::mallinfo();
78 return mi.uordblks + mi.hblkhd;
Chris Lattnerc590e9a2005-11-14 07:27:56 +000079#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
Reid Spencered5e7bf2004-12-20 16:33:37 +000083#elif defined(HAVE_GETRUSAGE)
84 struct rusage usage;
85 ::getrusage(RUSAGE_SELF, &usage);
86 return usage.ru_maxrss;
Reid Spencer721d9aa2004-12-20 00:59:28 +000087#else
88#warning Cannot get total memory size on this platform
89 return 0;
90#endif
91}
92
93void
94Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
95 TimeValue& sys_time)
96{
97 elapsed = TimeValue::now();
Chris Lattner095cc372006-05-12 18:20:39 +000098#if defined(HAVE_GETRUSAGE)
Reid Spencer721d9aa2004-12-20 00:59:28 +000099 struct rusage usage;
100 ::getrusage(RUSAGE_SELF, &usage);
Reid Spencer8b662892004-12-20 21:43:33 +0000101 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 ) );
Reid Spencer721d9aa2004-12-20 00:59:28 +0000109#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
Chris Lattner26b6c0b2006-09-14 06:01:41 +0000118int Process::GetCurrentUserId() {
Reid Spencer93b34732005-04-21 16:12:57 +0000119 return getuid();
120}
121
Chris Lattner26b6c0b2006-09-14 06:01:41 +0000122int Process::GetCurrentGroupId() {
Reid Spencer93b34732005-04-21 16:12:57 +0000123 return getgid();
124}
125
Chris Lattner5f1d0132006-09-14 06:21:59 +0000126#ifdef HAVE_MACH_MACH_H
Chris Lattner26b6c0b2006-09-14 06:01:41 +0000127#include <mach/mach.h>
128#endif
129
Reid Spencer68fdcc12004-12-27 06:17:27 +0000130// 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.
133void Process::PreventCoreFiles() {
134#if HAVE_SETRLIMIT
135 struct rlimit rlim;
136 rlim.rlim_cur = rlim.rlim_max = 0;
Chris Lattner505f9c82006-05-14 18:53:09 +0000137 setrlimit(RLIMIT_CORE, &rlim);
Reid Spencer68fdcc12004-12-27 06:17:27 +0000138#endif
Chris Lattner26b6c0b2006-09-14 06:01:41 +0000139
Chris Lattner5f1d0132006-09-14 06:21:59 +0000140#ifdef HAVE_MACH_MACH_H
Chris Lattner26b6c0b2006-09-14 06:01:41 +0000141 // 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
Reid Spencer68fdcc12004-12-27 06:17:27 +0000161}
Reid Spencer721d9aa2004-12-20 00:59:28 +0000162
Reid Spencera01aade2005-01-01 22:29:26 +0000163bool 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
171bool 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
179bool 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}