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> |
f0430952 |
21 | #include <Psapi.h> |
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 | // ======================================================================= |
44 | OSD_MemInfo::OSD_MemInfo() |
45 | { |
46 | Update(); |
47 | } |
48 | |
49 | // ======================================================================= |
50 | // function : Update |
51 | // purpose : |
52 | // ======================================================================= |
53 | void 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 | // ======================================================================= |
177 | TCollection_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 | // ======================================================================= |
217 | Standard_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 | // ======================================================================= |
230 | Standard_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 | // ======================================================================= |
244 | TCollection_AsciiString OSD_MemInfo::PrintInfo() |
245 | { |
246 | OSD_MemInfo anInfo; |
247 | return anInfo.ToString(); |
248 | } |