Correction of compilation errors
[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 #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();
68 #if (_WIN32_WINNT >= 0x0501)
69   PROCESS_MEMORY_COUNTERS_EX aProcMemCnts;
70 #else
71   PROCESS_MEMORY_COUNTERS    aProcMemCnts;
72 #endif
73   if (GetProcessMemoryInfo (aProcess, (PROCESS_MEMORY_COUNTERS* )&aProcMemCnts, sizeof(aProcMemCnts)))
74   {
75   #if (_WIN32_WINNT >= 0x0501)
76     myCounters[MemPrivate]        = aProcMemCnts.PrivateUsage;
77   #endif
78     myCounters[MemWorkingSet]     = aProcMemCnts.WorkingSetSize;
79     myCounters[MemWorkingSetPeak] = aProcMemCnts.PeakWorkingSetSize;
80     myCounters[MemSwapUsage]      = aProcMemCnts.PagefileUsage;
81     myCounters[MemSwapUsagePeak]  = aProcMemCnts.PeakPagefileUsage;
82   }
83  
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 }