blob: f73444f0c05b766f46221e9e569183b5099bb2aa [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//
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
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
33namespace llvm {
34using 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 Lattner513a9542005-11-14 07:00:29 +000054#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H)
55 return mstats().bytes_used; // darwin
Reid Spencerbc1ee842004-12-20 16:06:44 +000056#elif defined(HAVE_SBRK)
Reid Spencer721d9aa2004-12-20 00:59:28 +000057 // Note this is only an approximation and more closely resembles
58 // the value returned by mallinfo in the arena field.
Chris Lattner513a9542005-11-14 07:00:29 +000059 static char *StartOfMemory = reinterpret_cast<char*>(::sbrk(0));
60 char *EndOfMemory = (char*)sbrk(0);
61 if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
62 return EndOfMemory - StartOfMemory;
Reid Spencer721d9aa2004-12-20 00:59:28 +000063 else
64 return 0;
65#else
66#warning Cannot get malloc info on this platform
67 return 0;
68#endif
69}
70
Jeff Cohene269a1a2005-01-08 20:15:57 +000071size_t
Reid Spencer721d9aa2004-12-20 00:59:28 +000072Process::GetTotalMemoryUsage()
73{
Reid Spencerbc1ee842004-12-20 16:06:44 +000074#if defined(HAVE_MALLINFO)
Reid Spencer721d9aa2004-12-20 00:59:28 +000075 struct mallinfo mi = ::mallinfo();
76 return mi.uordblks + mi.hblkhd;
Chris Lattner513a9542005-11-14 07:00:29 +000077#elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H)
78 return mstats().bytes_total; // darwin
Reid Spencered5e7bf2004-12-20 16:33:37 +000079#elif defined(HAVE_GETRUSAGE)
80 struct rusage usage;
81 ::getrusage(RUSAGE_SELF, &usage);
82 return usage.ru_maxrss;
Reid Spencer721d9aa2004-12-20 00:59:28 +000083#else
84#warning Cannot get total memory size on this platform
85 return 0;
86#endif
87}
88
89void
90Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
91 TimeValue& sys_time)
92{
93 elapsed = TimeValue::now();
Reid Spencerbc1ee842004-12-20 16:06:44 +000094#if defined(HAVE_GETRUSAGE)
Reid Spencer721d9aa2004-12-20 00:59:28 +000095 struct rusage usage;
96 ::getrusage(RUSAGE_SELF, &usage);
Reid Spencer8b662892004-12-20 21:43:33 +000097 user_time = TimeValue(
98 static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ),
99 static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec *
100 TimeValue::NANOSECONDS_PER_MICROSECOND ) );
101 sys_time = TimeValue(
102 static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ),
103 static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec *
104 TimeValue::NANOSECONDS_PER_MICROSECOND ) );
Reid Spencer721d9aa2004-12-20 00:59:28 +0000105#else
106#warning Cannot get usage times on this platform
107 user_time.seconds(0);
108 user_time.microseconds(0);
109 sys_time.seconds(0);
110 sys_time.microseconds(0);
111#endif
112}
113
Reid Spencer93b34732005-04-21 16:12:57 +0000114int Process::GetCurrentUserId()
115{
116 return getuid();
117}
118
119int Process::GetCurrentGroupId()
120{
121 return getgid();
122}
123
Reid Spencer68fdcc12004-12-27 06:17:27 +0000124// Some LLVM programs such as bugpoint produce core files as a normal part of
125// their operation. To prevent the disk from filling up, this function
126// does what's necessary to prevent their generation.
127void Process::PreventCoreFiles() {
128#if HAVE_SETRLIMIT
129 struct rlimit rlim;
130 rlim.rlim_cur = rlim.rlim_max = 0;
131 int res = setrlimit(RLIMIT_CORE, &rlim);
132 if (res != 0)
133 ThrowErrno("Can't prevent core file generation");
134#endif
135}
Reid Spencer721d9aa2004-12-20 00:59:28 +0000136
Reid Spencera01aade2005-01-01 22:29:26 +0000137bool Process::StandardInIsUserInput() {
138#if HAVE_ISATTY
139 return isatty(0);
140#endif
141 // If we don't have isatty, just return false.
142 return false;
143}
144
145bool Process::StandardOutIsDisplayed() {
146#if HAVE_ISATTY
147 return isatty(1);
148#endif
149 // If we don't have isatty, just return false.
150 return false;
151}
152
153bool Process::StandardErrIsDisplayed() {
154#if HAVE_ISATTY
155 return isatty(2);
156#endif
157 // If we don't have isatty, just return false.
158 return false;
159}
160
Reid Spencer27dafe12004-09-11 04:56:56 +0000161}