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-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
38 
40 :
41  peak_(0),
42  size_(0),
43  rss_(0),
44  free_(0)
45 {
46  populate();
47 }
48 
49 
50 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
51 
52 bool Foam::memInfo::good() const noexcept
53 {
54  return peak_ > 0;
55 }
56 
57 
59 {
60  peak_ = size_ = rss_ = free_ = 0;
61 }
62 
63 
64 void Foam::memInfo::populate()
65 {
66  std::string line;
67 
68  // "/proc/meminfo"
69  // ===========================
70  // MemTotal: 65879268 kB
71  // MemFree: 51544256 kB
72  // MemAvailable: 58999636 kB
73  // Buffers: 2116 kB
74  // ...
75  // Stop parsing when known keys have been extracted
76  {
77  std::ifstream is("/proc/meminfo");
78 
79  for
80  (
81  unsigned nkeys = 1;
82  nkeys && is.good() && std::getline(is, line);
83  /*nil*/
84  )
85  {
86  const auto delim = line.find(':');
87  if (delim == std::string::npos)
88  {
89  continue;
90  }
91 
92  const std::string key(line.substr(0, delim));
93 
94  // std::stol() skips whitespace before using as many digits as
95  // possible. So just need to skip over the ':' and let stol do
96  // the rest
97 
98  if (key == "MemFree")
99  {
100  free_ = std::stol(line.substr(delim+1));
101  --nkeys;
102  }
103  }
104  }
105 
106  // "/proc/PID/status"
107  // ===========================
108  // VmPeak: 15920 kB
109  // VmSize: 15916 kB
110  // VmLck: 0 kB
111  // VmPin: 0 kB
112  // VmHWM: 6972 kB
113  // VmRSS: 6972 kB
114  // ...
115  // Stop parsing when known keys have been extracted
116 
117  // These units are kibi-btyes (1024)
118  {
119  std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
120 
121  for
122  (
123  unsigned nkeys = 3;
124  nkeys && is.good() && std::getline(is, line);
125  /*nil*/
126  )
127  {
128  const auto delim = line.find(':');
129  if (delim == std::string::npos)
130  {
131  continue;
132  }
133 
134  const std::string key(line.substr(0, delim));
135 
136  // std::stoi() skips whitespace before using as many digits as
137  // possible. So just need to skip over the ':' and let stoi do
138  // the rest
139 
140  if (key == "VmPeak")
141  {
142  peak_ = std::stol(line.substr(delim+1));
143  --nkeys;
144  }
145  else if (key == "VmSize")
146  {
147  size_ = std::stol(line.substr(delim+1));
148  --nkeys;
149  }
150  else if (key == "VmRSS")
151  {
152  rss_ = std::stol(line.substr(delim+1));
153  --nkeys;
154  }
155  }
156  }
157 }
158 
159 
161 {
162  clear();
163  populate();
164  return *this;
165 }
166 
167 
169 {
170  os.writeEntry("size", size_);
171  os.writeEntry("peak", peak_);
172  os.writeEntry("rss", rss_);
173  os.writeEntry("free", free_);
174  os.writeEntry("units", "kB");
175 }
176 
177 
178 void Foam::memInfo::writeEntry(const word& keyword, Ostream& os) const
179 {
180  os.beginBlock(keyword);
181  writeEntries(os);
182  os.endBlock();
183 }
184 
185 
186 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
187 
188 // Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
189 // {
190 // is.readBegin("memInfo");
191 // is >> m.peak_ >> m.size_ >> m.rss_ >> m.free_;
192 // is.readEnd("memInfo");
193 //
194 // is.check(FUNCTION_NAME);
195 // return is;
196 // }
197 
198 
200 {
202  << m.peak() << token::SPACE
203  << m.size() << token::SPACE
204  << m.rss() << token::SPACE
205  << m.free()
206  << token::END_LIST;
207 
209  return os;
210 }
211 
212 
213 // ************************************************************************* //
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
int64_t rss() const noexcept
Resident set size at last update - (VmRSS in /proc/PID/status)
Definition: memInfo.H:123
void clear() noexcept
Reset to zero.
Definition: memInfo.C:51
const memInfo & update()
Update according to /proc/PID/status and /proc/memory contents.
Definition: memInfo.C:153
Begin list [isseparator].
Definition: token.H:161
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:321
int64_t free() const noexcept
System memory free (MemFree in /proc/meminfo)
Definition: memInfo.H:128
void writeEntry(const word &keyword, Ostream &os) const
Write mem-info as dictionary.
Definition: memInfo.C:171
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...
memInfo()
Construct and populate with values.
Definition: memInfo.C:32
A class for handling words, derived from Foam::string.
Definition: word.H:63
int64_t peak() const noexcept
Peak memory at last update - (VmPeak in /proc/PID/status)
Definition: memInfo.H:113
virtual Ostream & endBlock()
Write end block group.
Definition: Ostream.C:108
Space [isspace].
Definition: token.H:131
bool good() const noexcept
True if the memory information appears valid.
Definition: memInfo.C:45
End list [isseparator].
Definition: token.H:162
patchWriters clear()
pid_t pid()
Return the PID of this process.
Definition: POSIX.C:314
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
Memory usage information for the current process, and the system memory that is free.
Definition: memInfo.H:58
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
void writeEntries(Ostream &os) const
Write mem-info as dictionary entries.
Definition: memInfo.C:161
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
virtual Ostream & beginBlock(const keyType &kw)
Write begin block group with the given name.
Definition: Ostream.C:90
int64_t size() const noexcept
Memory size at last update - (VmSize in /proc/PID/status)
Definition: memInfo.H:118