PlatformUtils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/common/PlatformUtils.cpp
22 
23  \brief This file contains several utility functions when dealing with Linux specific API.
24 */
25 
26 // TerraLib
27 #include "../Defines.h"
28 #include "Exception.h"
29 #include "PlatformUtils.h"
30 #include "StringUtils.h"
31 
32 // STL
33 #include <fstream>
34 
35 // O.S. Specific
36 #if TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
37 #include <windows.h>
38 #include <winbase.h>
39 
40 #elif TE_PLATFORM == TE_PLATFORMCODE_LINUX || TE_PLATFORM == TE_PLATFORMCODE_AIX || TE_PLATFORM == TE_PLATFORMCODE_FREEBSD || TE_PLATFORM == TE_PLATFORMCODE_OPENBSD
41 #include <cstring>
42 #include <errno.h>
43 #include <dirent.h>
44 #include <malloc.h>
45 #include <sys/resource.h>
46 #include <sys/stat.h>
47 #include <sys/sysctl.h>
48 #include <sys/types.h>
49 #include <unistd.h>
50 
51 #elif TE_PLATFORM == TE_PLATFORMCODE_APPLE
52 #include <cstdlib>
53 #include <dirent.h>
54 #include <sys/stat.h>
55 #include <sys/sysctl.h>
56 #include <mach/mach.h>
57 
58 #else
59  #error "Unsuported plataform for physical memory checking"
60 #endif
61 
62 #include <cstdio>
63 #include <cstdlib>
64 
65 // Boost
66 #include <boost/filesystem.hpp>
67 
68 unsigned long long int te::common::GetFreePhysicalMemory()
69 {
70  unsigned long long int freemem = 0;
71 
72 #if TE_PLATFORM == TE_PLATFORMCODE_FREEBSD || TE_PLATFORM == TE_PLATFORMCODE_OPENBSD || TE_PLATFORM == TE_PLATFORMCODE_APPLE
73  int64_t usermem = 0;
74 
75  std::size_t usermem_len = sizeof(usermem);
76 
77  int mib[2] = { CTL_HW, HW_USERMEM };
78 
79  if(sysctl(mib, 2, &usermem, &usermem_len, NULL, 0) == 0)
80  {
81  freemem = static_cast<unsigned long int>(usermem);
82  }
83  else
84  {
85  throw Exception("Could not get free physical memory!");
86  }
87 
88 #elif TE_PLATFORM == TE_PLATFORMCODE_LINUX
89  freemem = static_cast<unsigned long long int>( sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES) );
90 
91 #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
92  #if defined(_WIN64)
93  MEMORYSTATUSEX status_buffer;
94  status_buffer.dwLength = sizeof(status_buffer);
95  GlobalMemoryStatusEx(&status_buffer);
96  freemem = status_buffer.ullAvailPhys;
97  #else
98  LPMEMORYSTATUS status_buffer = new MEMORYSTATUS;
99  GlobalMemoryStatus(status_buffer);
100  freemem = static_cast<unsigned long int>(status_buffer->dwAvailPhys);
101  delete status_buffer;
102  #endif
103 #else
104  #error "Unsuported plataform for physical memory checking"
105 #endif
106 
107  return freemem;
108 }
109 
110 unsigned long long int te::common::GetTotalPhysicalMemory()
111 {
112  unsigned long long int totalmem = 0;
113 
114  #if TE_PLATFORM == TE_PLATFORMCODE_FREEBSD || TE_PLATFORM == TE_PLATFORMCODE_OPENBSD || TE_PLATFORM == TE_PLATFORMCODE_APPLE
115  #ifdef HW_MEMSIZE /* OSX. --------------------- */
116  int64_t physmem = 0;
117  int mib[2] = { CTL_HW, HW_MEMSIZE };
118  #elif defined(HW_PHYSMEM) /* FreeBSD. ----------------- */
119  unsigned int physmem = 0;
120  int mib[2] = { CTL_HW, HW_PHYSMEM };
121  #elif defined(HW_PHYSMEM64) /* DragonFly BSD. ----------- */
122  int64_t physmem = 0;
123  int mib[2] = { CTL_HW, HW_PHYSMEM64 };
124  #elif defined(HW_REALMEM) /* FreeBSD. ----------------- */
125  unsigned int physmem = 0;
126  int mib[2] = { CTL_HW, HW_REALMEM };
127  #endif
128 
129  std::size_t physmem_len = sizeof(physmem);
130 
131  if(sysctl(mib, 2, &physmem, &physmem_len, NULL, 0) == 0)
132  {
133  totalmem = static_cast<unsigned long long int>(physmem);
134  }
135  else
136  {
137  throw Exception("Could not get total physical memory!");
138  }
139  #elif TE_PLATFORM == TE_PLATFORMCODE_LINUX
140  totalmem = static_cast<unsigned long long int>( sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES) );
141 
142  #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
143  #if defined(_WIN64)
144  MEMORYSTATUSEX status_buffer;
145  status_buffer.dwLength = sizeof(status_buffer);
146  GlobalMemoryStatusEx(&status_buffer);
147  totalmem = status_buffer.ullTotalPhys;
148  #else
149  LPMEMORYSTATUS status_buffer = new MEMORYSTATUS;
150  GlobalMemoryStatus(status_buffer);
151  totalmem = static_cast<unsigned long int>(status_buffer->dwTotalPhys);
152  delete status_buffer;
153  #endif
154 
155  #else
156  #error "Unsuported plataform for physical memory checking"
157  #endif
158 
159  return totalmem;
160 }
161 
162 unsigned long long int te::common::GetUsedVirtualMemory()
163 {
164  unsigned long long int usedmem = 0;
165 
166 #if TE_PLATFORM == TE_PLATFORMCODE_FREEBSD || TE_PLATFORM == TE_PLATFORMCODE_OPENBSD
167  struct rusage rusageinfo;
168  getrusage( RUSAGE_SELF, &rusageinfo );
169  usedmem = static_cast<unsigned long long int>(1024 * rusageinfo.ru_maxrss);
170 
171 #elif TE_PLATFORM == TE_PLATFORMCODE_LINUX
172  std::string pid, comm, state, ppid, pgrp, session, tty_nr,
173  tpgid, flags, minflt, cminflt, majflt, cmajflt,
174  utime, stime, cutime, cstime, priority, nice,
175  stringO, itrealvalue, starttime;
176 
177  std::ifstream stat_stream("/proc/self/stat", std::ios_base::in);
178  if( !stat_stream.is_open() )
179  {
180  throw Exception("Could not get the used virtual memory!");
181  }
182 
183  stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
184  >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
185  >> utime >> stime >> cutime >> cstime >> priority >> nice
186  >> stringO >> itrealvalue >> starttime >> usedmem;
187 
188 #elif TE_PLATFORM == TE_PLATFORMCODE_AIX || TE_PLATFORM == TE_PLATFORMCODE_APPLE
189  struct mach_task_basic_info info;
190  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
191  if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
192  (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
193  throw;
194  usedmem = (unsigned long long int)info.resident_size;
195 
196 #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
197  #if defined(_WIN64)
198  MEMORYSTATUSEX status_buffer;
199  status_buffer.dwLength = sizeof(status_buffer);
200  GlobalMemoryStatusEx(&status_buffer);
201  usedmem = status_buffer.ullTotalVirtual - status_buffer.ullAvailVirtual;
202  #else
203  LPMEMORYSTATUS status_buffer = new MEMORYSTATUS;
204  GlobalMemoryStatus( status_buffer );
205  usedmem = static_cast<unsigned long long int>(status_buffer->dwTotalVirtual - status_buffer->dwAvailVirtual);
206  delete status_buffer;
207  #endif
208 
209 #else
210  #error "Unsuported plataform for virtual memory checking"
211 #endif
212 
213  return usedmem;
214 }
215 
216 
217 unsigned long long int te::common::GetTotalVirtualMemory()
218 {
219  unsigned long long int totalmem = 0;
220 
221 #if (TE_PLATFORM == TE_PLATFORMCODE_FREEBSD) || (TE_PLATFORM == TE_PLATFORMCODE_OPENBSD) || (TE_PLATFORM == TE_PLATFORMCODE_APPLE) || (TE_PLATFORM == TE_PLATFORMCODE_LINUX)
222  struct rlimit info;
223 
224  if( getrlimit( RLIMIT_AS, &info ) == 0 )
225  {
226  totalmem = (unsigned long long int)info.rlim_max;
227  }
228 
229 #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
230  #if defined(_WIN64)
231  MEMORYSTATUSEX status_buffer;
232  status_buffer.dwLength = sizeof(status_buffer);
233  GlobalMemoryStatusEx(&status_buffer);
234  totalmem = status_buffer.ullTotalVirtual;
235  #else
236  LPMEMORYSTATUS status_buffer = new MEMORYSTATUS;
237  GlobalMemoryStatus( status_buffer );
238  totalmem = (unsigned long int) status_buffer->dwTotalVirtual;
239  delete status_buffer;
240  #endif
241 
242 #else
243  #error "Unsuported plataform for virtual memory checking"
244 #endif
245 
246  return totalmem;
247 }
248 
250 {
251  unsigned int procnmb = 0;
252 
253 #if TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
254  SYSTEM_INFO siSysInfo;
255  GetSystemInfo(&siSysInfo);
256  procnmb = static_cast<unsigned int>(siSysInfo.dwNumberOfProcessors);
257 
258 #elif TE_PLATFORM == TE_PLATFORMCODE_LINUX || TE_PLATFORM == TE_PLATFORMCODE_AIX || TE_PLATFORM == TE_PLATFORMCODE_APPLE
259  procnmb = static_cast<unsigned int>(sysconf(_SC_NPROCESSORS_ONLN));
260 
261 #else
262  #error "ERROR: Unsupported platform"
263 #endif
264 
265  return procnmb;
266 }
267 
268 void te::common::GetDecompostedPathEnvVar( std::vector< std::string >& paths )
269 {
270  paths.clear();
271 
272  char* varValuePtr = getenv("PATH");
273 
274  std::string separator;
275  #if (TE_PLATFORM == TE_PLATFORMCODE_FREEBSD) || (TE_PLATFORM == TE_PLATFORMCODE_OPENBSD) || (TE_PLATFORM == TE_PLATFORMCODE_APPLE) || (TE_PLATFORM == TE_PLATFORMCODE_LINUX)
276  separator = ":";
277  #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
278  separator = ";";
279  #else
280  #error "Unsuported plataform for virtual memory checking"
281  #endif
282 
283  if( varValuePtr )
284  {
285  Tokenize( std::string( varValuePtr ), paths, separator );
286  }
287 }
288 
289 void te::common::GetDecompostedLDPathEnvVar( std::vector< std::string >& paths )
290 {
291  paths.clear();
292 
293  char* varValuePtr = getenv("LD_LIBRARY_PATH");
294 
295  std::string separator;
296  #if (TE_PLATFORM == TE_PLATFORMCODE_FREEBSD) || (TE_PLATFORM == TE_PLATFORMCODE_OPENBSD) || (TE_PLATFORM == TE_PLATFORMCODE_APPLE) || (TE_PLATFORM == TE_PLATFORMCODE_LINUX)
297  separator = ":";
298  #elif TE_PLATFORM == TE_PLATFORMCODE_MSWINDOWS
299  separator = ";";
300  #else
301  #error "Unsuported plataform for virtual memory checking"
302  #endif
303 
304  if( varValuePtr )
305  {
306  Tokenize( std::string( varValuePtr ), paths, separator );
307  }
308 }
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
pthread endif() include_directories($
TECOMMONEXPORT void GetDecompostedLDPathEnvVar(std::vector< std::string > &paths)
Returns the system LD_LIBRARY_PATH enviroment variable, decomposed into directory names...
This file is a wrapper around platform specific include files.
TECOMMONEXPORT void GetDecompostedPathEnvVar(std::vector< std::string > &paths)
Returns the system PATH enviroment variable, decomposed into directory names, or an empty vector if n...
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:221
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
Utility functions for dealing with strings.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
TECOMMONEXPORT unsigned long long int GetFreePhysicalMemory()
Returns the amount of free physical memory (bytes).
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...