Main MRPT website > C++ reference for MRPT 1.9.9
memory.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <cstdio> // for size_t, fclose, fopen, fscanf, FILE
13 #include <cstdlib> // for free, posix_memalign, realloc
14 #include <exception> // for exception
15 #include <mrpt/config.h> // for HAVE_POSIX_MEMALIGN, MRPT_OS_LINUX
16 #include <mrpt/utils/mrpt_macros.h> // for MRPT_END, MRPT_START, MRPT_UNUSE...
17 #include <mrpt/system/memory.h>
18 
19 #ifdef MRPT_OS_APPLE
20 #include <mach/mach_init.h>
21 #include <mach/task.h>
22 #endif
23 
24 using namespace mrpt;
25 using namespace mrpt::system;
26 using namespace std;
27 
28 // Management of aligned memory for efficiency:
29 // If we have "posix_memalign", use it, then realloc / free as usual.
30 // (GCC/Linux)
31 // If we have "_aligned_malloc", use it, then _aligned_realloc/_aligned_free
32 // (MSVC, MinGW)
33 
34 /** Returns an aligned memory block.
35  * \param alignment The desired alignment, typ. 8 or 16 bytes. 1 means no
36  * alignment required. It must be a power of two.
37  * \sa aligned_free, aligned_realloc
38  * \note Based on code by William Chan
39 */
40 void* mrpt::system::os::aligned_malloc(size_t bytes, size_t alignment)
41 {
42 #if defined(HAVE_ALIGNED_MALLOC)
43 #if defined(__GNUC__) && !defined(__MINGW32__)
44  return ::aligned_malloc(bytes, alignment);
45 #else
46  return _aligned_malloc(bytes, alignment);
47 #endif
48 #elif defined(HAVE_POSIX_MEMALIGN)
49  void* ptr = nullptr;
50  int ret = posix_memalign(&ptr, alignment, bytes);
51  if (ret) THROW_EXCEPTION("posix_memalign returned an error.");
52  return ptr;
53 #else
54  // We don't have aligned memory:
55  return ::malloc(bytes);
56 #endif
57 }
58 
59 /** Frees a memory block reserved by aligned_malloc.
60  * \param alignment The desired alignment, typ. 8 or 16 bytes. 1 means no
61  * alignment required.
62  * If old_ptr is nullptr, a new block will be reserved from scratch.
63  * \sa aligned_malloc, aligned_free
64  */
66  void* old_ptr, size_t bytes, size_t alignment)
67 {
68 #if defined(HAVE_ALIGNED_MALLOC)
69 #if defined(__GNUC__) && !defined(__MINGW32__)
70  return ::aligned_realloc(old_ptr, bytes, alignment);
71 #else
72  return _aligned_realloc(old_ptr, bytes, alignment);
73 #endif
74 #elif defined(HAVE_POSIX_MEMALIGN)
75  MRPT_UNUSED_PARAM(alignment);
76  return ::realloc(old_ptr, bytes);
77 #else
78  MRPT_UNUSED_PARAM(alignment);
79  // We don't have aligned memory:
80  return ::realloc(old_ptr, bytes);
81 #endif
82 }
83 
84 /** Frees a memory block reserved by aligned_malloc
85  * \sa aligned_malloc
86  */
88 {
89 #if defined(HAVE_ALIGNED_MALLOC)
90 #if defined(__GNUC__) && !defined(__MINGW32__)
92 #else
93  _aligned_free(p);
94 #endif
95 #elif defined(HAVE_POSIX_MEMALIGN)
96  free(p);
97 #else
98  // We don't have aligned memory:
99  free(p);
100 #endif
101 }
102 
103 #ifdef MRPT_OS_WINDOWS
104 #include <windows.h>
105 // Windows:
106 typedef struct _PROCESS_MEMORY_COUNTERS
107 {
108  DWORD cb;
109  DWORD PageFaultCount;
110  SIZE_T PeakWorkingSetSize;
111  SIZE_T WorkingSetSize;
112  SIZE_T QuotaPeakPagedPoolUsage;
113  SIZE_T QuotaPagedPoolUsage;
114  SIZE_T QuotaPeakNonPagedPoolUsage;
115  SIZE_T QuotaNonPagedPoolUsage;
116  SIZE_T PagefileUsage;
117  SIZE_T PeakPagefileUsage;
118 } PROCESS_MEMORY_COUNTERS, *PPROCESS_MEMORY_COUNTERS;
119 
120 namespace mrpt
121 {
122 namespace system
123 {
124 /** This is an auxiliary class for mrpt::system::getMemoryUsage() under Windows.
125  * It loads in runtime PSAPI.DLL. This is to avoid problems in some platforms,
126  * i.e Windows 2000,
127  * where this DLL must not be present.
128  */
129 class CAuxPSAPI_Loader
130 {
131  protected:
132  typedef BOOL(WINAPI* TGetProcessMemoryInfo)(
133  HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb);
134 
135  TGetProcessMemoryInfo m_ptr;
136 
137  public:
138  HMODULE m_dll;
139 
140  CAuxPSAPI_Loader()
141  {
142  m_ptr = nullptr;
143 
144  m_dll = LoadLibraryA("PSAPI.DLL");
145  if (m_dll)
146  {
147  m_ptr = (TGetProcessMemoryInfo)GetProcAddress(
148  m_dll, "GetProcessMemoryInfo");
149  }
150  }
151  ~CAuxPSAPI_Loader()
152  {
153  if (m_dll)
154  {
155  FreeLibrary(m_dll);
156  m_dll = nullptr;
157  m_ptr = nullptr;
158  }
159  }
160 
161  BOOL WINAPI GetProcessMemoryInfo(
162  HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb)
163  {
164  try
165  {
166  if (!m_ptr)
167  return false;
168  else
169  return (*m_ptr)(Process, ppsmemCounters, cb);
170  }
171  catch (...)
172  {
173  return false;
174  }
175  }
176 };
177 }
178 }
179 
180 #endif
181 
182 /*---------------------------------------------------------------
183  getMemoryUsage
184  ---------------------------------------------------------------*/
186 {
187  MRPT_START
188  unsigned long MEM = 0;
189 
190 #ifdef MRPT_OS_WINDOWS
191  // Windows:
192  static CAuxPSAPI_Loader PSAPI_LOADER;
193 
194  PROCESS_MEMORY_COUNTERS pmc;
195  pmc.cb = sizeof(pmc);
196 
197  if (PSAPI_LOADER.GetProcessMemoryInfo(
198  GetCurrentProcess(), &pmc, sizeof(pmc)))
199  {
200  MEM = (long)pmc.PagefileUsage;
201  }
202 #endif
203 
204 #ifdef MRPT_OS_LINUX
205  // Linux:
206  // int page_size = getpagesize();
207 
208  FILE* f = ::fopen("/proc/self/stat", "r");
209  if (!f) return 0;
210 
211  // Note: some of these scanf specifiers would normally be 'long' versions if
212  // not for the fact that we are using suppression (gcc warns). see 'man
213  // proc' for scanf specifiers and meanings.
214  if (!::fscanf(
215  f,
216  "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*u %*u %*d "
217  "%*d %*d %*d %*d %*d %*u %lu",
218  &MEM))
219  {
220  // Error parsing:
221  MEM = 0;
222  }
223  ::fclose(f);
224 //::system("cat /proc/self/statm");
225 #endif
226 
227 #ifdef MRPT_OS_APPLE
228  mach_task_basic_info info;
229  mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
230  if (task_info(
231  mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info,
232  &count) == 0)
233  {
234  MEM = info.virtual_size;
235  }
236 #endif
237  return MEM;
238  MRPT_END
239 }
GLuint GLuint GLsizei count
Definition: glext.h:3528
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
#define THROW_EXCEPTION(msg)
void * aligned_realloc(void *old_ptr, size_t bytes, size_t alignment)
Frees a memory block reserved by aligned_malloc.
Definition: memory.cpp:65
STL namespace.
int BOOL
Definition: xstypedefs.h:76
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
unsigned long getMemoryUsage()
Returns the memory occupied by this process, in bytes.
Definition: memory.cpp:185
void * aligned_malloc(size_t bytes, size_t alignment)
Returns an aligned memory block.
Definition: memory.cpp:40
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:254
void aligned_free(void *p)
Frees a memory block reserved by aligned_malloc.
Definition: memory.cpp:87
GLfloat GLfloat p
Definition: glext.h:6305
Definition: inflate.h:53



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019