1 /*=========================================================================
2 *
3 * Copyright Insight Software Consortium
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18 #ifndef itkSmapsFileParser_hxx
19 #define itkSmapsFileParser_hxx
20
21 #include "itkSmapsFileParser.h"
22
23 #if defined( _WIN32 )
24 #include <io.h>
25 #include <process.h>
26 #else
27 #include <unistd.h>
28 #endif
29
30 #include <fstream> // std::ifstream
31 #include <numeric> // std::accumulate
32 #include <algorithm> // std::find
33
34 namespace itk
35 {
36
37 template< typename TMapDataType >
38 bool
Update()39 MapFileParser< TMapDataType >::Update()
40 {
41 this->ReadFile(m_MapFilePath);
42 return m_MapFilePath.empty();
43 }
44
45 template< typename TMapDataType >
46 typename MapFileParser< TMapDataType >::MemoryLoadType
47 MapFileParser< TMapDataType >
GetHeapUsage()48 ::GetHeapUsage()
49 {
50 if ( m_MapData.Empty() )
51 {
52 std::cerr << "Read a map file before quering memory usage";
53 }
54 return m_MapData.GetHeapUsage();
55 }
56
57 template< typename TMapDataType >
58 typename MapFileParser< TMapDataType >::MemoryLoadType
59 MapFileParser< TMapDataType >
GetStackUsage()60 ::GetStackUsage()
61 {
62 if ( m_MapData.Empty() )
63 {
64 std::cerr << "Read a map file before quering memory usage";
65 }
66 return m_MapData.GetStackUsage();
67 }
68
69 template< typename TMapDataType >
70 typename MapFileParser< TMapDataType >::MemoryLoadType
71 MapFileParser< TMapDataType >
GetTotalMemoryUsage()72 ::GetTotalMemoryUsage()
73 {
74 if ( m_MapData.Empty() )
75 {
76 std::cerr << "Read a map file before quering memory usage";
77 }
78 return m_MapData.GetTotalMemoryUsage();
79 }
80
81 template< typename TMapDataType >
82 typename MapFileParser< TMapDataType >::MemoryLoadType
83 MapFileParser< TMapDataType >
GetMemoryUsage(const char * filter,const char * token)84 ::GetMemoryUsage(const char *filter, const char *token)
85 {
86 if ( m_MapData.Empty() )
87 {
88 std::cerr << "Read a map file before quering memory usage";
89 }
90 return m_MapData.GetMemoryUsage(filter, token);
91 }
92
93 //---------------------------------
94 // SmapsFileParser
95 //---------------------------------
96
97 /* SmapsFileParser implementation */
98 template< typename TSmapsDataType >
ReadFile(const std::string & mapFileLocation)99 void SmapsFileParser< TSmapsDataType >::ReadFile(const std::string & mapFileLocation)
100 {
101 std::stringstream filename;
102
103 filename << mapFileLocation;
104
105 // if location is empty (default parameter), use the regular linux smaps file.
106 if ( filename.str().empty() )
107 {
108 #if defined( WIN32 ) || defined ( _WIN32 )
109 itkGenericExceptionMacro(<< "smaps files don't exist on Windows");
110 #else
111 int pid = getpid();
112 filename << "/proc/" << pid << "/smaps";
113 #endif
114 }
115
116 // open the Smaps file
117 std::ifstream inputFile( filename.str().c_str() );
118
119 // can't find or open the Smaps file
120 if ( inputFile.is_open() == false )
121 {
122 std::cerr << "The smaps file " << filename.str() << " could not be open";
123 return;
124 }
125
126 try
127 {
128 //load the file
129 inputFile >> this->m_MapData;
130 }
131 catch ( ExceptionObject excp )
132 {
133 // propagate the exception
134 itkGenericExceptionMacro(<< "The smaps file " << filename.str() << " is an invalid file or contains errors");
135 }
136 this->m_MapFilePath = filename.str();
137 }
138
139 /* VMapFileParser implementation */
140 template< typename TVMMapDataType >
ReadFile(const std::string & mapFileLocation)141 void VMMapFileParser< TVMMapDataType >::ReadFile(const std::string & mapFileLocation)
142 {
143 try
144 {
145 if ( !mapFileLocation.empty() )
146 {
147 // open the VMap file
148 std::ifstream inputFile( mapFileLocation.c_str() );
149 // can't find or open the VMap file
150 if ( inputFile.is_open() == false )
151 {
152 itkGenericExceptionMacro(<< "The VMap file " << mapFileLocation << " could not be open");
153 return;
154 }
155 //load the file
156 inputFile >> this->m_MapData;
157 this->m_MapFilePath = mapFileLocation;
158 }
159 else
160 {
161 #if defined( WIN32 ) || defined ( _WIN32 )
162 itkGenericExceptionMacro(<< "VMMap files don't exist on Windows");
163 #else
164 std::stringstream vmmapCommand;
165 vmmapCommand << "vmmap " << getpid();
166
167 FILE *vmmapCommandOutput = nullptr;
168 if ( ( vmmapCommandOutput = popen(vmmapCommand.str().c_str(), "r") ) == nullptr )
169 {
170 itkGenericExceptionMacro(<< "Error using pmap. Can execute pmap command");
171 }
172
173 // Not optimal solution: copy the output into an std::istream object.
174 std::stringstream vmmapFile;
175 char buf[256];
176 while ( !feof(vmmapCommandOutput) )
177 {
178 fgets(buf, 256, vmmapCommandOutput);
179 vmmapFile << buf;
180 }
181
182 fclose(vmmapCommandOutput);
183 //fill the data
184 vmmapFile >> this->m_MapData;
185 this->m_MapFilePath = "";
186 #endif
187 }
188 }
189 catch ( ExceptionObject excp )
190 {
191 // propagate the exception
192 itkGenericExceptionMacro(<< "The vmmap file is an invalid file or contains errors");
193 }
194 }
195 } //end namespace itk
196
197 #endif //itkSmapsFileParser_hxx
198