f0430952 |
1 | // Created on: 2011-10-05 |
2 | // Created by: Kirill GAVRILOV |
3 | // Copyright (c) 2012 OPEN CASCADE SAS |
4 | // |
5 | // The content of this file is subject to the Open CASCADE Technology Public |
6 | // License Version 6.5 (the "License"). You may not use the content of this file |
7 | // except in compliance with the License. Please obtain a copy of the License |
8 | // at http://www.opencascade.org and read it completely before using this file. |
9 | // |
10 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
11 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
12 | // |
13 | // The Original Code and all software distributed under the License is |
14 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
15 | // Initial Developer hereby disclaims all such warranties, including without |
16 | // limitation, any warranties of merchantability, fitness for a particular |
17 | // purpose or non-infringement. Please see the License for the specific terms |
18 | // and conditions governing the rights and limitations under the License. |
19 | |
20 | #if (defined(_WIN32) || defined(__WIN32__)) |
21 | #include <windows.h> |
22 | #include <winbase.h> |
23 | #include <process.h> |
24 | #include <Psapi.h> |
25 | #ifdef _MSC_VER |
26 | #pragma comment(lib, "Psapi.lib") |
27 | #endif |
28 | #elif (defined(__APPLE__)) |
29 | #include <mach/task.h> |
30 | #include <mach/mach.h> |
31 | #endif |
32 | |
33 | #include <string> |
34 | #include <sstream> |
35 | #include <fstream> |
36 | |
37 | #include <OSD_MemInfo.hxx> |
38 | |
39 | // ======================================================================= |
40 | // function : OSD_MemInfo |
41 | // purpose : |
42 | // ======================================================================= |
43 | OSD_MemInfo::OSD_MemInfo() |
44 | { |
45 | Update(); |
46 | } |
47 | |
48 | // ======================================================================= |
49 | // function : Update |
50 | // purpose : |
51 | // ======================================================================= |
52 | void OSD_MemInfo::Update() |
53 | { |
54 | // reset values |
55 | for (Standard_Integer anIter = 0; anIter < MemCounter_NB; ++anIter) |
56 | { |
57 | myCounters[anIter] = Standard_Size(-1); |
58 | } |
59 | |
60 | #if (defined(_WIN32) || defined(__WIN32__)) |
61 | MEMORYSTATUSEX aStatEx; |
62 | aStatEx.dwLength = sizeof(aStatEx); |
63 | GlobalMemoryStatusEx (&aStatEx); |
64 | myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual); |
65 | |
66 | // use Psapi library |
67 | HANDLE aProcess = GetCurrentProcess(); |
9fa641d9 |
68 | #if (_WIN32_WINNT >= 0x0501) |
f0430952 |
69 | PROCESS_MEMORY_COUNTERS_EX aProcMemCnts; |
9fa641d9 |
70 | #else |
71 | PROCESS_MEMORY_COUNTERS aProcMemCnts; |
72 | #endif |
f0430952 |
73 | if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts))) |
74 | { |
9fa641d9 |
75 | #if (_WIN32_WINNT >= 0x0501) |
f0430952 |
76 | myCounters[MemPrivate] = aProcMemCnts.PrivateUsage; |
9fa641d9 |
77 | #endif |
f0430952 |
78 | myCounters[MemWorkingSet] = aProcMemCnts.WorkingSetSize; |
79 | myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize; |
80 | myCounters[MemSwapUsage] = aProcMemCnts.PagefileUsage; |
81 | myCounters[MemSwapUsagePeak] = aProcMemCnts.PeakPagefileUsage; |
82 | } |
9fa641d9 |
83 | |
f0430952 |
84 | #elif (defined(__linux__) || defined(__linux)) |
85 | // use procfs on Linux |
86 | char aBuff[4096]; |
87 | snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid()); |
88 | std::ifstream aFile; |
89 | aFile.open (aBuff); |
90 | if (!aFile.is_open()) |
91 | { |
92 | return; |
93 | } |
94 | |
95 | while (!aFile.eof()) |
96 | { |
97 | memset (aBuff, 0, sizeof(aBuff)); |
98 | aFile.getline (aBuff, 4096); |
99 | if (aBuff[0] == '\0') |
100 | { |
101 | continue; |
102 | } |
103 | |
104 | if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0) |
105 | { |
106 | myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024; |
107 | } |
108 | //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0) |
109 | // myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024; |
110 | else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0) |
111 | { |
112 | myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size |
113 | } |
114 | else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0) |
115 | { |
116 | myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark |
117 | } |
118 | else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0) |
119 | { |
120 | if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; |
121 | myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024; |
122 | } |
123 | else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0) |
124 | { |
125 | if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate]; |
126 | myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024; |
127 | } |
128 | } |
129 | aFile.close(); |
130 | #elif (defined(__APPLE__)) |
131 | struct task_basic_info aTaskInfo; |
132 | mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT; |
133 | if (task_info (mach_task_self(), TASK_BASIC_INFO, |
134 | (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS) |
135 | { |
136 | // On Mac OS X, these values in bytes, not pages! |
137 | myCounters[MemVirtual] = aTaskInfo.virtual_size; |
138 | myCounters[MemWorkingSet] = aTaskInfo.resident_size; |
139 | } |
140 | #endif |
141 | } |
142 | |
143 | // ======================================================================= |
144 | // function : ToString |
145 | // purpose : |
146 | // ======================================================================= |
147 | TCollection_AsciiString OSD_MemInfo::ToString() const |
148 | { |
149 | TCollection_AsciiString anInfo; |
150 | if (myCounters[MemPrivate] != Standard_Size(-1)) |
151 | { |
152 | anInfo += TCollection_AsciiString(" Private memory: ") + Standard_Integer (ValueMiB (MemPrivate)) + " MiB\n"; |
153 | } |
154 | if (myCounters[MemWorkingSet] != Standard_Size(-1)) |
155 | { |
156 | anInfo += TCollection_AsciiString(" Working Set: ") + Standard_Integer (ValueMiB (MemWorkingSet)) + " MiB"; |
157 | if (myCounters[MemWorkingSetPeak] != Standard_Size(-1)) |
158 | { |
159 | anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemWorkingSetPeak)) + " MiB)"; |
160 | } |
161 | anInfo += "\n"; |
162 | } |
163 | if (myCounters[MemSwapUsage] != Standard_Size(-1)) |
164 | { |
165 | anInfo += TCollection_AsciiString(" Pagefile usage: ") + Standard_Integer (ValueMiB (MemSwapUsage)) + " MiB"; |
166 | if (myCounters[MemSwapUsagePeak] != Standard_Size(-1)) |
167 | { |
168 | anInfo += TCollection_AsciiString(" (peak: ") + Standard_Integer (ValueMiB (MemSwapUsagePeak)) + " MiB)"; |
169 | } |
170 | anInfo += "\n"; |
171 | } |
172 | if (myCounters[MemVirtual] != Standard_Size(-1)) |
173 | { |
174 | anInfo += TCollection_AsciiString(" Virtual memory: ") + Standard_Integer (ValueMiB (MemVirtual)) + " MiB\n"; |
175 | } |
176 | return anInfo; |
177 | } |
178 | |
179 | // ======================================================================= |
180 | // function : Value |
181 | // purpose : |
182 | // ======================================================================= |
183 | Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const |
184 | { |
185 | if (theCounter < 0 || theCounter >= MemCounter_NB) |
186 | { |
187 | return Standard_Size(-1); |
188 | } |
189 | return myCounters[theCounter]; |
190 | } |
191 | |
192 | // ======================================================================= |
193 | // function : ValueMiB |
194 | // purpose : |
195 | // ======================================================================= |
196 | Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) const |
197 | { |
198 | if (theCounter < 0 || theCounter >= MemCounter_NB) |
199 | { |
200 | return Standard_Size(-1); |
201 | } |
202 | return (myCounters[theCounter] == Standard_Size(-1)) |
203 | ? Standard_Size(-1) : (myCounters[theCounter] / (1024 * 1024)); |
204 | } |
205 | |
206 | // ======================================================================= |
207 | // function : ShowInfo |
208 | // purpose : |
209 | // ======================================================================= |
210 | TCollection_AsciiString OSD_MemInfo::PrintInfo() |
211 | { |
212 | OSD_MemInfo anInfo; |
213 | return anInfo.ToString(); |
214 | } |