0030091: Configuration - allow cross-compilation from Linux (case sensitive filesyste...
[occt.git] / src / OSD / OSD_MemInfo.cxx
CommitLineData
f0430952 1// Created on: 2011-10-05
2// Created by: Kirill GAVRILOV
d5f74e42 3// Copyright (c) 2013-2014 OPEN CASCADE SAS
f0430952 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
f0430952 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
f0430952 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
f0430952 15
16#if (defined(_WIN32) || defined(__WIN32__))
17 #include <windows.h>
18 #include <winbase.h>
19 #include <process.h>
67a1064e 20 #include <malloc.h>
5fecc495 21 #include <psapi.h>
f0430952 22 #ifdef _MSC_VER
23 #pragma comment(lib, "Psapi.lib")
24 #endif
25#elif (defined(__APPLE__))
26 #include <mach/task.h>
27 #include <mach/mach.h>
67a1064e 28 #include <malloc/malloc.h>
8fa02385 29#else
30 #include <unistd.h>
67a1064e 31 #include <malloc.h>
f0430952 32#endif
33
34#include <string>
35#include <sstream>
36#include <fstream>
37
38#include <OSD_MemInfo.hxx>
39
40// =======================================================================
41// function : OSD_MemInfo
42// purpose :
43// =======================================================================
44OSD_MemInfo::OSD_MemInfo()
45{
46 Update();
47}
48
49// =======================================================================
50// function : Update
51// purpose :
52// =======================================================================
53void OSD_MemInfo::Update()
54{
55 // reset values
56 for (Standard_Integer anIter = 0; anIter < MemCounter_NB; ++anIter)
57 {
58 myCounters[anIter] = Standard_Size(-1);
59 }
742cc8b0 60#ifndef OCCT_UWP
7c65581d 61#if defined(_WIN32)
62#if (_WIN32_WINNT >= 0x0500)
f0430952 63 MEMORYSTATUSEX aStatEx;
64 aStatEx.dwLength = sizeof(aStatEx);
65 GlobalMemoryStatusEx (&aStatEx);
66 myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual);
7c65581d 67#else
68 MEMORYSTATUS aStat;
69 aStat.dwLength = sizeof(aStat);
70 GlobalMemoryStatus (&aStat);
71 myCounters[MemVirtual] = Standard_Size(aStat.dwTotalVirtual - aStat.dwAvailVirtual);
72#endif
f0430952 73
74 // use Psapi library
75 HANDLE aProcess = GetCurrentProcess();
9fa641d9 76#if (_WIN32_WINNT >= 0x0501)
f0430952 77 PROCESS_MEMORY_COUNTERS_EX aProcMemCnts;
9fa641d9 78#else
79 PROCESS_MEMORY_COUNTERS aProcMemCnts;
80#endif
f0430952 81 if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts)))
82 {
9fa641d9 83 #if (_WIN32_WINNT >= 0x0501)
f0430952 84 myCounters[MemPrivate] = aProcMemCnts.PrivateUsage;
9fa641d9 85 #endif
f0430952 86 myCounters[MemWorkingSet] = aProcMemCnts.WorkingSetSize;
87 myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize;
88 myCounters[MemSwapUsage] = aProcMemCnts.PagefileUsage;
89 myCounters[MemSwapUsagePeak] = aProcMemCnts.PeakPagefileUsage;
90 }
8fa02385 91
67a1064e 92 _HEAPINFO hinfo;
93 int heapstatus;
94 hinfo._pentry = NULL;
95
96 myCounters[MemHeapUsage] = 0;
97 while((heapstatus = _heapwalk(&hinfo)) == _HEAPOK)
98 {
99 if(hinfo._useflag == _USEDENTRY)
100 myCounters[MemHeapUsage] += hinfo._size;
101 }
102
f0430952 103#elif (defined(__linux__) || defined(__linux))
104 // use procfs on Linux
105 char aBuff[4096];
106 snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid());
107 std::ifstream aFile;
108 aFile.open (aBuff);
109 if (!aFile.is_open())
110 {
111 return;
112 }
113
114 while (!aFile.eof())
115 {
116 memset (aBuff, 0, sizeof(aBuff));
117 aFile.getline (aBuff, 4096);
118 if (aBuff[0] == '\0')
119 {
120 continue;
121 }
122
123 if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0)
124 {
125 myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024;
126 }
127 //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0)
128 // myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024;
129 else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0)
130 {
131 myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size
132 }
133 else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0)
134 {
135 myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark
136 }
137 else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0)
138 {
139 if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
140 myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024;
141 }
142 else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0)
143 {
144 if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
145 myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024;
146 }
147 }
148 aFile.close();
67a1064e 149
150 struct mallinfo aMI = mallinfo();
151 myCounters[MemHeapUsage] = aMI.uordblks;
152
f0430952 153#elif (defined(__APPLE__))
154 struct task_basic_info aTaskInfo;
155 mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT;
156 if (task_info (mach_task_self(), TASK_BASIC_INFO,
157 (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS)
158 {
159 // On Mac OS X, these values in bytes, not pages!
160 myCounters[MemVirtual] = aTaskInfo.virtual_size;
161 myCounters[MemWorkingSet] = aTaskInfo.resident_size;
67a1064e 162
163 //Getting malloc statistics
164 malloc_statistics_t aStats;
165 malloc_zone_statistics (NULL, &aStats);
166
167 myCounters[MemHeapUsage] = aStats.size_in_use;
f0430952 168 }
169#endif
742cc8b0 170#endif
f0430952 171}
172
173// =======================================================================
174// function : ToString
175// purpose :
176// =======================================================================
177TCollection_AsciiString OSD_MemInfo::ToString() const
178{
179 TCollection_AsciiString anInfo;
180 if (myCounters[MemPrivate] != Standard_Size(-1))
181 {
182 anInfo += TCollection_AsciiString(" Private memory: ") + Standard_Integer (ValueMiB (MemPrivate)) + " MiB\n";
183 }
184 if (myCounters[MemWorkingSet] != Standard_Size(-1))
185 {
186 anInfo += TCollection_AsciiString(" Working Set: ") + Standard_Integer (ValueMiB (MemWorkingSet)) + " MiB";
187 if (myCounters[MemWorkingSetPeak] != Standard_Size(-1))
188 {
189 anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemWorkingSetPeak)) + " MiB)";
190 }
191 anInfo += "\n";
192 }
193 if (myCounters[MemSwapUsage] != Standard_Size(-1))
194 {
195 anInfo += TCollection_AsciiString(" Pagefile usage: ") + Standard_Integer (ValueMiB (MemSwapUsage)) + " MiB";
196 if (myCounters[MemSwapUsagePeak] != Standard_Size(-1))
197 {
198 anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemSwapUsagePeak)) + " MiB)";
199 }
200 anInfo += "\n";
201 }
202 if (myCounters[MemVirtual] != Standard_Size(-1))
203 {
204 anInfo += TCollection_AsciiString(" Virtual memory: ") + Standard_Integer (ValueMiB (MemVirtual)) + " MiB\n";
205 }
67a1064e 206 if (myCounters[MemHeapUsage] != Standard_Size(-1))
207 {
208 anInfo += TCollection_AsciiString(" Heap memory: ") + Standard_Integer (ValueMiB (MemHeapUsage)) + " MiB\n";
209 }
f0430952 210 return anInfo;
211}
212
213// =======================================================================
214// function : Value
215// purpose :
216// =======================================================================
217Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const
218{
219 if (theCounter < 0 || theCounter >= MemCounter_NB)
220 {
221 return Standard_Size(-1);
222 }
223 return myCounters[theCounter];
224}
225
226// =======================================================================
227// function : ValueMiB
228// purpose :
229// =======================================================================
230Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) const
231{
232 if (theCounter < 0 || theCounter >= MemCounter_NB)
233 {
234 return Standard_Size(-1);
235 }
236 return (myCounters[theCounter] == Standard_Size(-1))
237 ? Standard_Size(-1) : (myCounters[theCounter] / (1024 * 1024));
238}
239
240// =======================================================================
241// function : ShowInfo
242// purpose :
243// =======================================================================
244TCollection_AsciiString OSD_MemInfo::PrintInfo()
245{
246 OSD_MemInfo anInfo;
247 return anInfo.ToString();
248}