0023250: Missing include in OSD_MemInfo.cxx
[occt.git] / src / OSD / OSD_MemInfo.cxx
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 #else
32   #include <unistd.h>
33 #endif
34
35 #include <string>
36 #include <sstream>
37 #include <fstream>
38
39 #include <OSD_MemInfo.hxx>
40
41 // =======================================================================
42 // function : OSD_MemInfo
43 // purpose  :
44 // =======================================================================
45 OSD_MemInfo::OSD_MemInfo()
46 {
47   Update();
48 }
49
50 // =======================================================================
51 // function : Update
52 // purpose  :
53 // =======================================================================
54 void OSD_MemInfo::Update()
55 {
56   // reset values
57   for (Standard_Integer anIter = 0; anIter < MemCounter_NB; ++anIter)
58   {
59     myCounters[anIter] = Standard_Size(-1);
60   }
61
62 #if (defined(_WIN32) || defined(__WIN32__))
63   MEMORYSTATUSEX aStatEx;
64   aStatEx.dwLength = sizeof(aStatEx);
65   GlobalMemoryStatusEx (&aStatEx);
66   myCounters[MemVirtual] = Standard_Size(aStatEx.ullTotalVirtual - aStatEx.ullAvailVirtual);
67
68   // use Psapi library
69   HANDLE aProcess = GetCurrentProcess();
70 #if (_WIN32_WINNT >= 0x0501)
71   PROCESS_MEMORY_COUNTERS_EX aProcMemCnts;
72 #else
73   PROCESS_MEMORY_COUNTERS    aProcMemCnts;
74 #endif
75   if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts)))
76   {
77   #if (_WIN32_WINNT >= 0x0501)
78     myCounters[MemPrivate]        = aProcMemCnts.PrivateUsage;
79   #endif
80     myCounters[MemWorkingSet]     = aProcMemCnts.WorkingSetSize;
81     myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize;
82     myCounters[MemSwapUsage]      = aProcMemCnts.PagefileUsage;
83     myCounters[MemSwapUsagePeak]  = aProcMemCnts.PeakPagefileUsage;
84   }
85
86 #elif (defined(__linux__) || defined(__linux))
87   // use procfs on Linux
88   char aBuff[4096];
89   snprintf (aBuff, sizeof(aBuff), "/proc/%d/status", getpid());
90   std::ifstream aFile;
91   aFile.open (aBuff);
92   if (!aFile.is_open())
93   {
94     return;
95   }
96
97   while (!aFile.eof())
98   {
99     memset (aBuff, 0, sizeof(aBuff));
100     aFile.getline (aBuff, 4096);
101     if (aBuff[0] == '\0')
102     {
103       continue;
104     }
105
106     if (strncmp (aBuff, "VmSize:", strlen ("VmSize:")) == 0)
107     {
108       myCounters[MemVirtual] = atol (aBuff + strlen ("VmSize:")) * 1024;
109     }
110     //else if (strncmp (aBuff, "VmPeak:", strlen ("VmPeak:")) == 0)
111     //  myVirtualPeak = atol (aBuff + strlen ("VmPeak:")) * 1024;
112     else if (strncmp (aBuff, "VmRSS:", strlen ("VmRSS:")) == 0)
113     {
114       myCounters[MemWorkingSet] = atol (aBuff + strlen ("VmRSS:")) * 1024; // RSS - resident set size
115     }
116     else if (strncmp (aBuff, "VmHWM:", strlen ("VmHWM:")) == 0)
117     {
118       myCounters[MemWorkingSetPeak] = atol (aBuff + strlen ("VmHWM:")) * 1024; // HWM - high water mark
119     }
120     else if (strncmp (aBuff, "VmData:", strlen ("VmData:")) == 0)
121     {
122       if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
123       myCounters[MemPrivate] += atol (aBuff + strlen ("VmData:")) * 1024;
124     }
125     else if (strncmp (aBuff, "VmStk:", strlen ("VmStk:")) == 0)
126     {
127       if (myCounters[MemPrivate] == Standard_Size(-1)) ++myCounters[MemPrivate];
128       myCounters[MemPrivate] += atol (aBuff + strlen ("VmStk:")) * 1024;
129     }
130   }
131   aFile.close();
132 #elif (defined(__APPLE__))
133   struct task_basic_info aTaskInfo;
134   mach_msg_type_number_t aTaskInfoCount = TASK_BASIC_INFO_COUNT;
135   if (task_info (mach_task_self(), TASK_BASIC_INFO,
136                  (task_info_t )&aTaskInfo, &aTaskInfoCount) == KERN_SUCCESS)
137   {
138     // On Mac OS X, these values in bytes, not pages!
139     myCounters[MemVirtual]    = aTaskInfo.virtual_size;
140     myCounters[MemWorkingSet] = aTaskInfo.resident_size;
141   }
142 #endif
143 }
144
145 // =======================================================================
146 // function : ToString
147 // purpose  :
148 // =======================================================================
149 TCollection_AsciiString OSD_MemInfo::ToString() const
150 {
151   TCollection_AsciiString anInfo;
152   if (myCounters[MemPrivate] != Standard_Size(-1))
153   {
154     anInfo += TCollection_AsciiString("  Private memory:     ") + Standard_Integer (ValueMiB (MemPrivate)) + " MiB\n";
155   }
156   if (myCounters[MemWorkingSet] != Standard_Size(-1))
157   {
158     anInfo += TCollection_AsciiString("  Working Set:        ") +  Standard_Integer (ValueMiB (MemWorkingSet)) + " MiB";
159     if (myCounters[MemWorkingSetPeak] != Standard_Size(-1))
160     {
161       anInfo += TCollection_AsciiString(" (peak: ") +  Standard_Integer (ValueMiB (MemWorkingSetPeak)) + " MiB)";
162     }
163     anInfo += "\n";
164   }
165   if (myCounters[MemSwapUsage] != Standard_Size(-1))
166   {
167     anInfo += TCollection_AsciiString("  Pagefile usage:     ") +  Standard_Integer (ValueMiB (MemSwapUsage)) + " MiB";
168     if (myCounters[MemSwapUsagePeak] != Standard_Size(-1))
169     {
170       anInfo += TCollection_AsciiString(" (peak: ") +  Standard_Integer (ValueMiB (MemSwapUsagePeak)) + " MiB)";
171     }
172     anInfo += "\n";
173   }
174   if (myCounters[MemVirtual] != Standard_Size(-1))
175   {
176     anInfo += TCollection_AsciiString("  Virtual memory:     ") +  Standard_Integer (ValueMiB (MemVirtual)) + " MiB\n";
177   }
178   return anInfo;
179 }
180
181 // =======================================================================
182 // function : Value
183 // purpose  :
184 // =======================================================================
185 Standard_Size OSD_MemInfo::Value (const OSD_MemInfo::Counter theCounter) const
186 {
187   if (theCounter < 0 || theCounter >= MemCounter_NB)
188   {
189     return Standard_Size(-1);
190   }
191   return myCounters[theCounter];
192 }
193
194 // =======================================================================
195 // function : ValueMiB
196 // purpose  :
197 // =======================================================================
198 Standard_Size OSD_MemInfo::ValueMiB (const OSD_MemInfo::Counter theCounter) const
199 {
200   if (theCounter < 0 || theCounter >= MemCounter_NB)
201   {
202     return Standard_Size(-1);
203   }
204   return (myCounters[theCounter] == Standard_Size(-1))
205        ? Standard_Size(-1) : (myCounters[theCounter] / (1024 * 1024));
206 }
207
208 // =======================================================================
209 // function : ShowInfo
210 // purpose  :
211 // =======================================================================
212 TCollection_AsciiString OSD_MemInfo::PrintInfo()
213 {
214   OSD_MemInfo anInfo;
215   return anInfo.ToString();
216 }