Loading...
Searching...
No Matches
memInfo.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011 OpenFOAM Foundation
9 Copyright (C) 2016-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "memInfo.H"
30#include "IOstreams.H"
31#include "OSspecific.H" // For pid()
32
33#include <cstdlib>
34#include <fstream>
35#include <string>
36
37// Future?
38// - with sysctl(...)
39//
40// #ifdef __APPLE__
41// #include <sys/types.h>
42// #include <sys/sysctl.h>
43// #endif
44
45
46// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
47
48static int is_supported(-1);
49
51{
52 if (is_supported < 0)
53 {
54 // This is Linux-specific!
55 std::ifstream is("/proc/meminfo");
56 is_supported = is.good();
57 }
59 return is_supported;
60}
61
62
63// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
64
66:
67 peak_(0),
68 size_(0),
69 rss_(0),
70 free_(0)
72 populate();
73}
74
75
76// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
79{
80 return peak_ > 0;
81}
82
83
85{
86 peak_ = size_ = rss_ = free_ = 0;
87}
88
89
90void Foam::memInfo::populate()
91{
92 std::string line;
93
94 // This is all Linux-specific!
95
96 // "/proc/meminfo"
97 // ===========================
98 // MemTotal: 65879268 kB
99 // MemFree: 51544256 kB
100 // MemAvailable: 58999636 kB
101 // Buffers: 2116 kB
102 // ...
103 // Stop parsing when known keys have been extracted
104
105 if
106 (
107 std::ifstream is("/proc/meminfo");
108 is.good()
109 )
110 {
111 for
112 (
113 unsigned nkeys = 1;
114 nkeys && is.good() && std::getline(is, line);
115 /*nil*/
116 )
117 {
118 const auto delim = line.find(':');
119 if (delim == std::string::npos)
120 {
121 continue;
122 }
123
124 // Compare initial part of line to "Key"
125 #undef isKeyEqual
126 #define isKeyEqual(Key) (!line.compare(0, delim, Key))
127
128 // std::stol() and std::strtol()
129 // both skip whitespace before using as many digits as possible.
130 // So just skip over the ':' and let those do the rest
131
132 const char * value = (line.data() + (delim+1));
133 char *endptr = nullptr;
134
135 #undef parseValue
136 #define parseValue (std::strtol(value, &endptr, 10))
137 // Could also check for 'kB' etc ending
138
139
140 // ------------------
141 // Extract key: value
142 // ------------------
143
144 if (isKeyEqual("MemFree"))
145 {
146 free_ = parseValue;
147 --nkeys;
148 }
149
150 #undef isKeyEqual
151 #undef parseValue
152 }
153 }
154
155 // "/proc/PID/status"
156 // ===========================
157 // VmPeak: 15920 kB
158 // VmSize: 15916 kB
159 // VmLck: 0 kB
160 // VmPin: 0 kB
161 // VmHWM: 6972 kB
162 // VmRSS: 6972 kB
163 // ...
164 // Stop parsing when known keys have been extracted
165
166 // These units are kibi-btyes (1024)
167 if
168 (
169 std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
170 is.good()
171 )
172 {
173 for
174 (
175 unsigned nkeys = 3;
176 nkeys && is.good() && std::getline(is, line);
177 /*nil*/
178 )
179 {
180 const auto delim = line.find(':');
181 if (delim == std::string::npos)
182 {
183 continue;
184 }
185
186 // Compare initial part of line to "Key"
187 #undef isKeyEqual
188 #define isKeyEqual(Key) (!line.compare(0, delim, Key))
189
190 // std::stol() and std::strtol()
191 // both skip whitespace before using as many digits as possible.
192 // So just skip over the ':' and let those do the rest
193
194 const char * value = (line.data() + (delim+1));
195 char *endptr = nullptr;
196
197 #undef parseValue
198 #define parseValue (std::strtol(value, &endptr, 10))
199 // Could also check for 'kB' etc ending
200
201
202 // ------------------
203 // Extract key: value
204 // ------------------
205
206 if (isKeyEqual("VmPeak"))
207 {
208 peak_ = parseValue;
209 --nkeys;
210 }
211 else if (isKeyEqual("VmSize"))
212 {
213 size_ = parseValue;
214 --nkeys;
215 }
216 else if (isKeyEqual("VmRSS"))
217 {
218 rss_ = parseValue;
219 --nkeys;
220 }
221
222 #undef isKeyEqual
223 #undef parseValue
224 }
225 }
226}
227
228
229const Foam::memInfo& Foam::memInfo::update()
231 clear();
232 populate();
233 return *this;
234}
235
236
238{
239 os.writeEntry("size", size_);
240 os.writeEntry("peak", peak_);
241 os.writeEntry("rss", rss_);
242 os.writeEntry("free", free_);
243 os.writeEntry("units", "kB");
244}
245
246
247void Foam::memInfo::writeEntry(const word& keyword, Ostream& os) const
248{
249 os.beginBlock(keyword);
250 writeEntries(os);
251 os.endBlock();
252}
253
254
255// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
256
257// Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
258// {
259// is.readBegin("memInfo");
260// is >> m.peak_ >> m.size_ >> m.rss_ >> m.free_;
261// is.readEnd("memInfo");
262//
263// is.check(FUNCTION_NAME);
264// return is;
265// }
266
267
269{
271 << m.peak() << token::SPACE
272 << m.size() << token::SPACE
273 << m.rss() << token::SPACE
274 << m.free()
276
277 os.check(FUNCTION_NAME);
278 return os;
279}
280
281
282// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A line primitive.
Definition line.H:180
Memory usage information for the current process, and the system memory that is free.
Definition memInfo.H:59
void clear() noexcept
Reset to zero.
Definition memInfo.C:77
int64_t peak() const noexcept
Peak memory at last update - (VmPeak in /proc/PID/status).
Definition memInfo.H:119
bool good() const noexcept
True if the memory information appears valid.
Definition memInfo.C:71
memInfo()
Construct and populate with values.
Definition memInfo.C:58
int64_t size() const noexcept
Memory size at last update - (VmSize in /proc/PID/status).
Definition memInfo.H:124
void writeEntries(Ostream &os) const
Write mem-info as dictionary entries.
Definition memInfo.C:230
void writeEntry(const word &keyword, Ostream &os) const
Write mem-info as dictionary.
Definition memInfo.C:240
int64_t rss() const noexcept
Resident set size at last update - (VmRSS in /proc/PID/status).
Definition memInfo.H:129
int64_t free() const noexcept
System memory free (MemFree in /proc/meminfo).
Definition memInfo.H:134
static bool supported()
True if memory information appears to be supported.
Definition memInfo.C:43
const memInfo & update()
Update according to /proc/PID/status and /proc/memory contents.
Definition memInfo.C:222
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
@ SPACE
Space [isspace].
Definition token.H:144
A class for handling words, derived from Foam::string.
Definition word.H:66
OBJstream os(runTime.globalPath()/outputName)
#define isKeyEqual(Key)
#define parseValue
static int is_supported(-1)
surface1 clear()
#define FUNCTION_NAME
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
pid_t pid()
Return the PID of this process.
Definition POSIX.C:316
const direction noexcept
Definition scalarImpl.H:265