diff --git a/applications/test/cpuInfo/Make/files b/applications/test/cpuInfo/Make/files new file mode 100644 index 0000000000..f9302d8ef2 --- /dev/null +++ b/applications/test/cpuInfo/Make/files @@ -0,0 +1,3 @@ +Test-cpuInfo.C + +EXE = $(FOAM_USER_APPBIN)/Test-cpuInfo diff --git a/applications/test/cpuInfo/Make/options b/applications/test/cpuInfo/Make/options new file mode 100644 index 0000000000..e69de29bb2 diff --git a/applications/test/cpuInfo/Test-cpuInfo.C b/applications/test/cpuInfo/Test-cpuInfo.C new file mode 100644 index 0000000000..785b804678 --- /dev/null +++ b/applications/test/cpuInfo/Test-cpuInfo.C @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + +Description + +\*---------------------------------------------------------------------------*/ + +#include "cpuInfo.H" +#include "IOstreams.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + cpuInfo().write(Info); + Info<< endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OSspecific/POSIX/Make/files b/src/OSspecific/POSIX/Make/files index 90dc5bc92e..4780174be9 100644 --- a/src/OSspecific/POSIX/Make/files +++ b/src/OSspecific/POSIX/Make/files @@ -10,6 +10,7 @@ fileStat.C POSIX.C cpuTime/cpuTime.C clockTime/clockTime.C +cpuInfo/cpuInfo.C memInfo/memInfo.C /* diff --git a/src/OSspecific/POSIX/cpuInfo/cpuInfo.C b/src/OSspecific/POSIX/cpuInfo/cpuInfo.C new file mode 100644 index 0000000000..ef71120a74 --- /dev/null +++ b/src/OSspecific/POSIX/cpuInfo/cpuInfo.C @@ -0,0 +1,241 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "cpuInfo.H" +#include "IFstream.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +// file-scope function +template +inline static void writeEntry +( + Foam::Ostream& os, const Foam::word& key, const T& value +) +{ + os.writeKeyword(key) << value << Foam::token::END_STATEMENT << '\n'; +} + + +// file-scope function +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; + } + + std::string::size_type endKey = line.find_last_not_of("\t:", sep); + std::string::size_type begVal = line.find_first_not_of(" :", sep); + + if (endKey == std::string::npos || begVal == std::string::npos) + { + return false; + } + ++endKey; + + // replace spaces in key with '_' for ease of use/consistency + for + ( + std::string::iterator iter = line.begin(); + iter != line.end(); + ++iter + ) + { + if (*iter == ' ') + { + *iter = '_'; + } + else if (*iter == ':') + { + break; + } + } + + key = line.substr(0, endKey); + val = line.substr(begVal); + + // std::cerr<<"key=" << key << " val= " << val << '\n'; + + 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 * * * * * * * * * * * // + +// parse this type of content: +// =========================== +// processor : 0 +// vendor_id : GenuineIntel +// cpu family : 6 +// model : 63 +// model name : Intel(R) Xeon(R) CPU E5-2620 v3 @ 2.40GHz +// stepping : 2 +// microcode : 0x35 +// cpu MHz : 1200.000 +// cache size : 15360 KB +// physical id : 0 +// siblings : 12 +// core id : 0 +// cpu cores : 6 +// apicid : 0 +// initial apicid : 0 +// fpu : yes +// fpu_exception : yes +// cpuid level : 15 +// wp : yes +// flags : fpu vme ... +// bugs : +// bogomips : 4789.15 +// clflush size : 64 +// cache_alignment : 64 +// address sizes : 46 bits physical, 48 bits virtual +// power management: + +void Foam::cpuInfo::parse() +{ + int ncpu = 0; + + IFstream is("/proc/cpuinfo"); + while (is.good()) + { + string line, key, value; + is.getLine(line); + + if (!split(line, key, value)) + { + continue; + } + + if (key == "processor") + { + if (ncpu++) + { + break; // stop after the first cpu + } + } + else if (key == "vendor_id") { vendor_id = value; } + else if (key == "model_name") { model_name = value; } + else if (key == "cpu_family") { getInt(value, cpu_family); } + else if (key == "model") { getInt(value, model); } + else if (key == "cpu_MHz") { getFlt(value, cpu_MHz); } + else if (key == "cpu_cores") { getInt(value, cpu_cores); } + else if (key == "siblings") { getInt(value, siblings); } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cpuInfo::cpuInfo() +: + vendor_id(), + model_name(), + cpu_family(-1), + model(-1), + cpu_MHz(0), + siblings(0), + cpu_cores(0) +{ + parse(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::cpuInfo::~cpuInfo() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::cpuInfo::write(Ostream& os) const +{ + if (!vendor_id.empty()) + { + writeEntry(os, "vendor_id", vendor_id); + } + if (!model_name.empty()) + { + writeEntry(os, "model_name", model_name); + } + if (cpu_family != -1) + { + writeEntry(os, "cpu_family", cpu_family); + } + if (model != -1) + { + writeEntry(os, "model", model); + } + if (cpu_MHz > 0) + { + writeEntry(os, "cpu_MHz", cpu_MHz); + } + if (cpu_cores > 0) + { + writeEntry(os, "cpu_cores", cpu_cores); + } + if (siblings > 0) + { + writeEntry(os, "siblings", siblings); + } +} + + +// ************************************************************************* // diff --git a/src/OSspecific/POSIX/cpuInfo/cpuInfo.H b/src/OSspecific/POSIX/cpuInfo/cpuInfo.H new file mode 100644 index 0000000000..6821684f61 --- /dev/null +++ b/src/OSspecific/POSIX/cpuInfo/cpuInfo.H @@ -0,0 +1,110 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Class + Foam::cpuInfo + +Description + General CPU characteristics. + + If the machine has multiple cpus/cores, only the characteristics + of the first core are used. + +Note + Uses the information from /proc/cpuinfo + +SourceFiles + cpuInfo.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cpuInfo_H +#define cpuInfo_H + +#include + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +// forward declarations +class Ostream; + +/*---------------------------------------------------------------------------*\ + Class cpuInfo Declaration +\*---------------------------------------------------------------------------*/ + +class cpuInfo +{ + // Private data + + // Various bits from /proc/cpuinfo + + std::string vendor_id; + std::string model_name; + int cpu_family; + int model; + float cpu_MHz; + int siblings; + int cpu_cores; + + // Private Member Functions + + //- Parse /proc/cpuinfo + void parse(); + + //- Disallow default bitwise assignment + void operator=(const cpuInfo&) = delete; + + //- Disallow default copy constructor + cpuInfo(const cpuInfo&) = delete; + +public: + + // Constructors + + //- Construct null + cpuInfo(); + + + //- Destructor + ~cpuInfo(); + + + // Member Functions + + //- Write content as dictionary entries + void write(Ostream&) const; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OSspecific/POSIX/memInfo/memInfo.C b/src/OSspecific/POSIX/memInfo/memInfo.C index 6273fe5aa1..43037b5c79 100644 --- a/src/OSspecific/POSIX/memInfo/memInfo.C +++ b/src/OSspecific/POSIX/memInfo/memInfo.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,14 +24,29 @@ License \*---------------------------------------------------------------------------*/ #include "memInfo.H" +#include "IFstream.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +// file-scope function +template +inline static void writeEntry +( + Foam::Ostream& os, const Foam::word& key, const T& value +) +{ + os.writeKeyword(key) << value << Foam::token::END_STATEMENT << '\n'; +} + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::memInfo::memInfo() : - peak_(-1), - size_(-1), - rss_(-1) + peak_(0), + size_(0), + rss_(0) { update(); } @@ -48,7 +63,7 @@ Foam::memInfo::~memInfo() const Foam::memInfo& Foam::memInfo::update() { // reset to invalid values first - peak_ = size_ = rss_ = -1; + peak_ = size_ = rss_ = 0; IFstream is("/proc/" + name(pid()) + "/status"); while (is.good()) @@ -81,7 +96,15 @@ const Foam::memInfo& Foam::memInfo::update() bool Foam::memInfo::valid() const { - return peak_ != -1; + return peak_ > 0; +} + + +void Foam::memInfo::write(Ostream& os) const +{ + writeEntry(os, "size", size_); + writeEntry(os, "peak", peak_); + writeEntry(os, "rss", rss_); } @@ -108,14 +131,15 @@ Foam::Istream& Foam::operator>>(Istream& is, memInfo& m) Foam::Ostream& Foam::operator<<(Ostream& os, const memInfo& m) { os << token::BEGIN_LIST - << m.peak_ << token::SPACE << m.size_ << token::SPACE << m.rss_ + << m.peak_ << token::SPACE + << m.size_ << token::SPACE + << m.rss_ << token::END_LIST; // Check state of Ostream os.check ( - "Foam::Ostream& Foam::operator<<(Foam::Ostream&, " - "const Foam::memInfo&)" + "Foam::Ostream& Foam::operator<<(Foam::Ostream&, const Foam::memInfo&)" ); return os; diff --git a/src/OSspecific/POSIX/memInfo/memInfo.H b/src/OSspecific/POSIX/memInfo/memInfo.H index 540ea9b6d1..cc970896fc 100644 --- a/src/OSspecific/POSIX/memInfo/memInfo.H +++ b/src/OSspecific/POSIX/memInfo/memInfo.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,7 +28,7 @@ Description Memory usage information for the process running this object. Note - Uses the information from /proc/\/status + Uses the information from /proc/PID/status SourceFiles memInfo.C @@ -47,6 +47,10 @@ SourceFiles namespace Foam { +// forward declarations +class Istream; +class Ostream; + /*---------------------------------------------------------------------------*\ Class memInfo Declaration \*---------------------------------------------------------------------------*/ @@ -55,15 +59,20 @@ class memInfo { // Private data - //- Peak memory used by the process (VmPeak in /proc/\/status) + //- Peak memory used by the process (VmPeak in /proc/PID/status) int peak_; - //- Memory used by the process (VmSize in /proc/\/status) + //- Memory used by the process (VmSize in /proc/PID/status) int size_; - //- Resident set size of the process (VmRSS in /proc/\/status) + //- Resident set size of the process (VmRSS in /proc/PID/status) int rss_; + //- Disallow default bitwise assignment + void operator=(const memInfo&) = delete; + + //- Disallow default copy constructor + memInfo(const memInfo&) = delete; public: @@ -79,27 +88,24 @@ public: // Member Functions - //- Parse /proc/\/status + //- Parse /proc/PID/status and update accordingly const memInfo& update(); // Access - //- Access the stored peak memory (VmPeak in /proc/\/status) - // The value is stored from the previous update() + //- Peak memory (VmPeak in /proc/PID/status) at last update() int peak() const { return peak_; } - //- Access the stored memory size (VmSize in /proc/\/status) - // The value is stored from the previous update() + //- Memory size (VmSize in /proc/PID/status) at last update() int size() const { return size_; } - //- Access the stored rss value (VmRSS in /proc/\/status) - // The value is stored from the previous update() + //- Resident set size (VmRSS in /proc/PID/status) at last update() int rss() const { return rss_; @@ -109,6 +115,10 @@ public: bool valid() const; + //- Write content as dictionary entries + void write(Ostream&) const; + + // IOstream Operators //- Read peak/size/rss from stream