STYLE: replace file-local functions with the Ostream writeEntry() method

ENH: use std C++ for conversions instead of sscanf()
This commit is contained in:
Mark Olesen
2017-08-11 08:39:45 +02:00
parent 59b70b04d5
commit b3128e6ced
4 changed files with 134 additions and 165 deletions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd. \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,102 +24,61 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "cpuInfo.H" #include "cpuInfo.H"
#include "IFstream.H"
#include "IOstreams.H" #include "IOstreams.H"
#include <fstream>
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// file-scope function // file-scope function
template<class T> // split things like "a key word\t: value information"
inline static void writeEntry // into ("a_key_word", "value information")
( //
Foam::Ostream& os, const Foam::word& key, const T& value static bool split(const std::string& line, std::string& key, std::string& val)
)
{ {
os.writeKeyword(key) << value << Foam::token::END_STATEMENT << '\n'; key.clear();
} val.clear();
const auto keyLen = line.find_first_of("\t:");
const auto sep = line.find(':');
// file-scope function if (keyLen == std::string::npos || sep == std::string::npos)
static bool split(std::string& line, std::string& key, std::string& val)
{
std::string::size_type sep = line.find(':');
if (sep == std::string::npos)
{ {
return false; return false;
} }
std::string::size_type endKey = line.find_last_not_of("\t:", sep); const auto begVal = line.find_first_not_of(" :", sep);
std::string::size_type begVal = line.find_first_not_of(" :", sep);
if (endKey == std::string::npos || begVal == std::string::npos) if (begVal == std::string::npos)
{ {
return false; return false;
} }
++endKey;
// replace spaces in key with '_' for ease of use/consistency key = line.substr(0, keyLen);
for val = line.substr(begVal);
(
std::string::iterator iter = line.begin(); // Avoid spaces in key - replace with '_'
iter != line.end(); for (auto iter = key.begin(); iter < key.end(); ++iter)
++iter
)
{ {
if (*iter == ' ') if (*iter == ' ')
{ {
*iter = '_'; *iter = '_';
} }
else if (*iter == ':')
{
break;
}
} }
key = line.substr(0, endKey); // std::cerr<<"key=<" << key << "> val=<" << val << ">\n";
val = line.substr(begVal);
// std::cerr<<"key=" << key << " val= " << val << '\n';
return true; return true;
} }
// file-scope function - get int
static inline bool getInt(const std::string& str, int& val)
{
int i;
if (sscanf(str.c_str(), "%d", &i) == 1)
{
val = i;
return true;
}
else
{
return false;
}
}
// file-scope function - get float
static inline bool getFlt(const std::string& str, float& val)
{
float f;
if (sscanf(str.c_str(), "%f", &f) == 1)
{
val = f;
return true;
}
else
{
return false;
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// parse this type of content: // Parse the following type of content.
// A TAB separates the keyword from content. Eg,
//
// "cpu cores\t: 6"
//
// =========================== // ===========================
// processor : 0 // processor : 0
// vendor_id : GenuineIntel // vendor_id : GenuineIntel
@ -151,14 +110,14 @@ static inline bool getFlt(const std::string& str, float& val)
void Foam::cpuInfo::parse() void Foam::cpuInfo::parse()
{ {
int ncpu = 0; int ncpu = 0;
std::string line, key, val;
IFstream is("/proc/cpuinfo"); std::ifstream is("/proc/cpuinfo");
while (is.good()) while (is.good())
{ {
string line, key, value; std::getline(is, line);
is.getLine(line);
if (!split(line, key, value)) if (!split(line, key, val))
{ {
continue; continue;
} }
@ -170,13 +129,13 @@ void Foam::cpuInfo::parse()
break; // stop after the first cpu break; // stop after the first cpu
} }
} }
else if (key == "vendor_id") { vendor_id = value; } else if (key == "vendor_id") { vendor_id = val; }
else if (key == "model_name") { model_name = value; } else if (key == "model_name") { model_name = val; }
else if (key == "cpu_family") { getInt(value, cpu_family); } else if (key == "cpu_family") { cpu_family = std::stoi(val); }
else if (key == "model") { getInt(value, model); } else if (key == "model") { model = std::stoi(val); }
else if (key == "cpu_MHz") { getFlt(value, cpu_MHz); } else if (key == "cpu_MHz") { cpu_MHz = std::stof(val); }
else if (key == "cpu_cores") { getInt(value, cpu_cores); } else if (key == "cpu_cores") { cpu_cores = std::stoi(val); }
else if (key == "siblings") { getInt(value, siblings); } else if (key == "siblings") { siblings = std::stoi(val); }
} }
} }
@ -209,31 +168,31 @@ void Foam::cpuInfo::write(Ostream& os) const
{ {
if (!vendor_id.empty()) if (!vendor_id.empty())
{ {
writeEntry(os, "vendor_id", vendor_id); os.writeEntry("vendor_id", vendor_id);
} }
if (!model_name.empty()) if (!model_name.empty())
{ {
writeEntry(os, "model_name", model_name); os.writeEntry("model_name", model_name);
} }
if (cpu_family != -1) if (cpu_family != -1)
{ {
writeEntry(os, "cpu_family", cpu_family); os.writeEntry("cpu_family", cpu_family);
} }
if (model != -1) if (model != -1)
{ {
writeEntry(os, "model", model); os.writeEntry("model", model);
} }
if (cpu_MHz > 0) if (cpu_MHz > 0)
{ {
writeEntry(os, "cpu_MHz", cpu_MHz); os.writeEntry("cpu_MHz", cpu_MHz);
} }
if (cpu_cores > 0) if (cpu_cores > 0)
{ {
writeEntry(os, "cpu_cores", cpu_cores); os.writeEntry("cpu_cores", cpu_cores);
} }
if (siblings > 0) if (siblings > 0)
{ {
writeEntry(os, "siblings", siblings); os.writeEntry("siblings", siblings);
} }
} }

View File

@ -47,7 +47,8 @@ SourceFiles
namespace Foam namespace Foam
{ {
// forward declarations
// Forward declarations
class Ostream; class Ostream;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
@ -68,6 +69,7 @@ class cpuInfo
int siblings; int siblings;
int cpu_cores; int cpu_cores;
// Private Member Functions // Private Member Functions
//- Parse /proc/cpuinfo //- Parse /proc/cpuinfo
@ -83,7 +85,7 @@ public:
// Constructors // Constructors
//- Construct null //- Construct and populate with information
cpuInfo(); cpuInfo();
@ -94,7 +96,7 @@ public:
// Member Functions // Member Functions
//- Write content as dictionary entries //- Write content as dictionary entries
void write(Ostream&) const; void write(Ostream& os) const;
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -24,21 +24,11 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "memInfo.H" #include "memInfo.H"
#include "IFstream.H" #include "OSspecific.H"
#include "IOstreams.H" #include "IOstreams.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // #include <fstream>
#include <string>
// file-scope function
template<class T>
inline static void writeEntry
(
Foam::Ostream& os, const Foam::word& key, const T& value
)
{
os.writeKeyword(key) << value << Foam::token::END_STATEMENT << '\n';
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -59,34 +49,64 @@ Foam::memInfo::~memInfo()
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
//
// Parse the following type of content.
//
// ===========================
// VmPeak: 15920 kB
// VmSize: 15916 kB
// VmLck: 0 kB
// VmPin: 0 kB
// VmHWM: 6972 kB
// VmRSS: 6972 kB
// VmLib: 2208 kB
// VmPTE: 52 kB
// VmPMD: 12 kB
// VmSwap: 0 kB
const Foam::memInfo& Foam::memInfo::update() const Foam::memInfo& Foam::memInfo::update()
{ {
// reset to invalid values first // Clear (invalidate) values first
peak_ = size_ = rss_ = 0; peak_ = size_ = rss_ = 0;
IFstream is("/proc/" + name(pid()) + "/status"); std::string line;
while (is.good()) unsigned nKeys = 0;
std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
while (is.good() && nKeys < 3) // Stop after getting the known keys
{ {
string line; std::getline(is, line);
is.getLine(line);
char tag[32];
int value;
if (sscanf(line.c_str(), "%30s %d", tag, &value) == 2) const auto keyLen = line.find(':');
if (keyLen == std::string::npos)
{ {
if (!strcmp(tag, "VmPeak:")) continue;
{ }
peak_ = value;
} // Value is after the ':', but skip any leading whitespace since
else if (!strcmp(tag, "VmSize:")) // strtoi will do it anyhow
{ const auto begVal = line.find_first_not_of("\t :", keyLen);
size_ = value; if (begVal == std::string::npos)
} {
else if (!strcmp(tag, "VmRSS:")) continue;
{ }
rss_ = value;
} const std::string key = line.substr(0, keyLen);
if (key == "VmPeak")
{
peak_ = std::stoi(line.substr(begVal));
++nKeys;
}
else if (key == "VmSize")
{
size_ = std::stoi(line.substr(begVal));
++nKeys;
}
else if (key == "VmRSS")
{
rss_ = std::stoi(line.substr(begVal));
++nKeys;
} }
} }
@ -102,9 +122,9 @@ bool Foam::memInfo::valid() const
void Foam::memInfo::write(Ostream& os) const void Foam::memInfo::write(Ostream& os) const
{ {
writeEntry(os, "size", size_); os.writeEntry("size", size_);
writeEntry(os, "peak", peak_); os.writeEntry("peak", peak_);
writeEntry(os, "rss", rss_); os.writeEntry("rss", rss_);
} }
@ -113,9 +133,7 @@ void Foam::memInfo::write(Ostream& os) const
Foam::Istream& Foam::operator>>(Istream& is, memInfo& m) Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
{ {
is.readBegin("memInfo"); is.readBegin("memInfo");
is >> m.peak_ >> m.size_ >> m.rss_; is >> m.peak_ >> m.size_ >> m.rss_;
is.readEnd("memInfo"); is.readEnd("memInfo");
is.check(FUNCTION_NAME); is.check(FUNCTION_NAME);

View File

@ -38,27 +38,20 @@ SourceFiles
#ifndef memInfo_H #ifndef memInfo_H
#define memInfo_H #define memInfo_H
#include "OSspecific.H"
#include "POSIX.H"
#include "IFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
class memInfo; class memInfo;
Istream& operator>>(Istream&, memInfo&);
Ostream& operator<<(Ostream&, const memInfo&);
// forward declarations
class Istream; class Istream;
class Ostream; class Ostream;
Istream& operator>>(Istream& is, memInfo& m);
Ostream& operator<<(Ostream& os, const memInfo& m);
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class memInfo Declaration Class memInfo Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -76,12 +69,6 @@ class memInfo
//- Resident set size of the process (VmRSS in /proc/PID/status) //- Resident set size of the process (VmRSS in /proc/PID/status)
int rss_; int rss_;
//- Disallow default bitwise assignment
void operator=(const memInfo&) = delete;
//- Disallow default copy constructor
memInfo(const memInfo&) = delete;
public: public:
// Constructors // Constructors
@ -96,44 +83,47 @@ public:
// Member Functions // Member Functions
//- Parse /proc/PID/status and update accordingly //- Update according to /proc/PID/status contents
const memInfo& update(); const memInfo& update();
// Access
//- Peak memory (VmPeak in /proc/PID/status) at last update() // Access
int peak() const
{
return peak_;
}
//- Memory size (VmSize in /proc/PID/status) at last update() //- Peak memory (VmPeak in /proc/PID/status) at last update()
int size() const inline int peak() const
{ {
return size_; return peak_;
} }
//- Resident set size (VmRSS in /proc/PID/status) at last update() //- Memory size (VmSize in /proc/PID/status) at last update()
int rss() const inline int size() const
{ {
return rss_; return size_;
} }
//- True if the memory information appears valid //- Resident set size (VmRSS in /proc/PID/status) at last update()
bool valid() const; inline int rss() const
{
return rss_;
}
//- True if the memory information appears valid
bool valid() const;
// Write
//- Write content as dictionary entries //- Write content as dictionary entries
void write(Ostream&) const; void write(Ostream& os) const;
// IOstream Operators // IOstream Operators
//- Read peak/size/rss from stream //- Read peak/size/rss from stream
friend Istream& operator>>(Istream&, memInfo&); friend Istream& operator>>(Istream& is, memInfo& m);
//- Write peak/size/rss to stream //- Write peak/size/rss to stream
friend Ostream& operator<<(Ostream&, const memInfo&); friend Ostream& operator<<(Ostream& os, const memInfo& m);
}; };