Skip to content
Snippets Groups Projects
memInfo.C 5.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • graham's avatar
    graham committed
    /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011 OpenFOAM Foundation
        Copyright (C) 2016-2017 OpenCFD Ltd.
    
    graham's avatar
    graham committed
    -------------------------------------------------------------------------------
    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 <http://www.gnu.org/licenses/>.
    
    \*---------------------------------------------------------------------------*/
    
    #include "memInfo.H"
    
    #include "IOstreams.H"
    
    
    graham's avatar
    graham committed
    
    // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
    
    Foam::memInfo::memInfo()
    :
    
        peak_(0),
        size_(0),
    
    graham's avatar
    graham committed
    {
        update();
    }
    
    
    
    // * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
    
    graham's avatar
    graham committed
    
    
    bool Foam::memInfo::valid() const
    {
        return peak_ > 0;
    }
    
    graham's avatar
    graham committed
    
    
    
    void Foam::memInfo::clear()
    {
        peak_ = size_ = rss_ = 0;
        free_ = 0;
    }
    
    
    graham's avatar
    graham committed
    
    const Foam::memInfo& Foam::memInfo::update()
    {
    
        // "/proc/PID/status"
        // ===========================
        // VmPeak:    15920 kB
        // VmSize:    15916 kB
        // VmLck:         0 kB
        // VmPin:         0 kB
        // VmHWM:      6972 kB
        // VmRSS:      6972 kB
        // ...
        // Stop parsing when known keys have been extracted
    
    graham's avatar
    graham committed
        {
    
            std::ifstream is("/proc/" + std::to_string(Foam::pid()) + "/status");
    
            for
            (
                unsigned nkeys = 3;
                nkeys && is.good() && std::getline(is, line);
                /*nil*/
            )
    
                const auto delim = line.find(':');
                if (delim == std::string::npos)
                {
                    continue;
                }
    
                const std::string key(line.substr(0, delim));
    
                // std::stoi() skips whitespace before using as many digits as
                // possible. So just need to skip over the ':' and let stoi do
                // the rest
    
                if (key == "VmPeak")
                {
                    peak_ = std::stoi(line.substr(delim+1));
                    --nkeys;
                }
                else if (key == "VmSize")
                {
                    size_ = std::stoi(line.substr(delim+1));
                    --nkeys;
                }
                else if (key == "VmRSS")
                {
                    rss_ = std::stoi(line.substr(delim+1));
                    --nkeys;
                }
    
        // "/proc/meminfo"
        // ===========================
        // MemTotal:       65879268 kB
        // MemFree:        51544256 kB
        // MemAvailable:   58999636 kB
        // Buffers:            2116 kB
        // ...
        // Stop parsing when known keys have been extracted
        {
            std::ifstream is("/proc/meminfo");
    
            for
            (
                unsigned nkeys = 1;
                nkeys && is.good() && std::getline(is, line);
                /*nil*/
            )
    
                const auto delim = line.find(':');
                if (delim == std::string::npos)
                {
                    continue;
                }
    
                const std::string key = line.substr(0, delim);
    
                // std::stoi() skips whitespace before using as many digits as
                // possible. So just need to skip over the ':' and let stoi do
                // the rest
    
                if (key == "MemFree")
                {
                    free_ = std::stoi(line.substr(delim+1));
                    --nkeys;
                }
    
    void Foam::memInfo::write(Ostream& os) const
    {
    
        os.writeEntry("size", size_);
        os.writeEntry("peak", peak_);
        os.writeEntry("rss", rss_);
    
        os.writeEntry("free", free_);
    
    graham's avatar
    graham committed
    // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
    
    Foam::Istream& Foam::operator>>(Istream& is, memInfo& m)
    {
        is.readBegin("memInfo");
    
        is  >> m.peak_ >> m.size_ >> m.rss_ >> m.free_;
    
    graham's avatar
    graham committed
        is.readEnd("memInfo");
    
    
    graham's avatar
    graham committed
        return is;
    }
    
    
    Foam::Ostream& Foam::operator<<(Ostream& os, const memInfo& m)
    {
        os  << token::BEGIN_LIST
    
            << m.peak_ << token::SPACE
            << m.size_ << token::SPACE
    
            << m.rss_  << token::SPACE
            << m.free_
    
    graham's avatar
    graham committed
            << token::END_LIST;
    
    
    graham's avatar
    graham committed
        return os;
    }
    
    
    // ************************************************************************* //