f73444f0c05b766f46221e9e569183b5099bb2aa
[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_MSTATS) && defined(HAVE_MALLOC_MALLOC_H)
55   return mstats().bytes_used;   // darwin
56 #elif defined(HAVE_SBRK)
57   // Note this is only an approximation and more closely resembles
58   // the value returned by mallinfo in the arena field.
59   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;
63   else
64     return 0;
65 #else
66 #warning Cannot get malloc info on this platform
67   return 0;
68 #endif
69 }
70
71 size_t
72 Process::GetTotalMemoryUsage()
73 {
74 #if defined(HAVE_MALLINFO)
75   struct mallinfo mi = ::mallinfo();
76   return mi.uordblks + mi.hblkhd;
77 #elif defined(HAVE_MSTATS) && defined(HAVE_MALLOC_MALLOC_H)
78   return mstats().bytes_total;   // darwin
79 #elif defined(HAVE_GETRUSAGE)
80   struct rusage usage;
81   ::getrusage(RUSAGE_SELF, &usage);
82   return usage.ru_maxrss;
83 #else
84 #warning Cannot get total memory size on this platform
85   return 0;
86 #endif
87 }
88
89 void
90 Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time, 
91                       TimeValue& sys_time)
92 {
93   elapsed = TimeValue::now();
94 #if defined(HAVE_GETRUSAGE)
95   struct rusage usage;
96   ::getrusage(RUSAGE_SELF, &usage);
97   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 ) );
105 #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
114 int Process::GetCurrentUserId()
115 {
116   return getuid();
117 }
118
119 int Process::GetCurrentGroupId()
120 {
121   return getgid();
122 }
123
124 // 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.
127 void 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 }
136
137 bool 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
145 bool 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
153 bool 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
161 }