2019-01-04 16:29:57 +01:00
|
|
|
// Copyright (C) 2004-2011, Ondra Kamenik
|
|
|
|
|
|
|
|
#include "journal.hh"
|
|
|
|
#include "kord_exception.hh"
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
#include <iomanip>
|
|
|
|
#include <cmath>
|
2019-01-04 16:29:57 +01:00
|
|
|
#include <ctime>
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
|
|
|
# include <sys/time.h> // For getrusage()
|
|
|
|
# include <sys/resource.h> // For getrusage()
|
|
|
|
# include <sys/utsname.h> // For uname()
|
|
|
|
# include <cstdlib> // For getloadavg()
|
|
|
|
# include <unistd.h> // For sysconf()
|
|
|
|
#else
|
2019-01-04 16:29:57 +01:00
|
|
|
# ifndef NOMINMAX
|
2019-03-05 18:35:35 +01:00
|
|
|
# define NOMINMAX // Do not define "min" and "max" macros
|
2019-01-04 16:29:57 +01:00
|
|
|
# endif
|
2019-03-05 18:35:35 +01:00
|
|
|
# include <windows.h> // For GlobalMemoryStatus()
|
2019-01-04 16:29:57 +01:00
|
|
|
#endif
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
const std::chrono::time_point<std::chrono::high_resolution_clock> SystemResources::start = std::chrono::high_resolution_clock::now();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
/* The pagesize is set to 1024 bytes on Windows. Real pagesize can differ but
|
|
|
|
it is not important. We can do this since Windows kernel32
|
|
|
|
GlobalMemoryStatus() call returns a number of bytes. */
|
|
|
|
long
|
2019-01-04 16:29:57 +01:00
|
|
|
SystemResources::pageSize()
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
return sysconf(_SC_PAGESIZE);
|
2019-03-05 18:35:35 +01:00
|
|
|
#else
|
|
|
|
return 1024;
|
|
|
|
#endif
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
long
|
2019-01-04 16:29:57 +01:00
|
|
|
SystemResources::physicalPages()
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
return sysconf(_SC_PHYS_PAGES);
|
2019-03-05 18:35:35 +01:00
|
|
|
#else
|
|
|
|
MEMORYSTATUS memstat;
|
|
|
|
GlobalMemoryStatus(&memstat);
|
|
|
|
return memstat.dwTotalPhys/1024;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
long
|
|
|
|
SystemResources::availablePhysicalPages()
|
|
|
|
{
|
|
|
|
#ifndef __MINGW32__
|
|
|
|
return sysconf(_SC_AVPHYS_PAGES);
|
|
|
|
#else
|
|
|
|
MEMORYSTATUS memstat;
|
|
|
|
GlobalMemoryStatus(&memstat);
|
|
|
|
return memstat.dwAvailPhys/1024;
|
|
|
|
#endif
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
long
|
2019-01-04 16:29:57 +01:00
|
|
|
SystemResources::onlineProcessors()
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
return sysconf(_SC_NPROCESSORS_ONLN);
|
2019-03-05 18:35:35 +01:00
|
|
|
#else
|
|
|
|
return -1;
|
|
|
|
#endif
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
long
|
2019-01-04 16:29:57 +01:00
|
|
|
SystemResources::availableMemory()
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
return pageSize()*availablePhysicalPages();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
SystemResources::SystemResources()
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
auto now = std::chrono::high_resolution_clock::now();
|
|
|
|
std::chrono::duration<double> duration = now - start;
|
|
|
|
elapsed = duration.count();
|
2019-01-04 16:29:57 +01:00
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
struct rusage rus;
|
|
|
|
getrusage(RUSAGE_SELF, &rus);
|
|
|
|
utime = rus.ru_utime.tv_sec+rus.ru_utime.tv_usec*1.0e-6;
|
|
|
|
stime = rus.ru_stime.tv_sec+rus.ru_stime.tv_usec*1.0e-6;
|
|
|
|
idrss = rus.ru_idrss;
|
|
|
|
majflt = rus.ru_majflt;
|
|
|
|
#else
|
|
|
|
utime = -1.0;
|
|
|
|
stime = -1.0;
|
|
|
|
idrss = -1;
|
|
|
|
majflt = -1;
|
|
|
|
#endif
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
getloadavg(&load_avg, 1);
|
|
|
|
#else
|
|
|
|
load_avg = -1.0;
|
|
|
|
#endif
|
|
|
|
|
2019-03-05 18:35:35 +01:00
|
|
|
pg_avail = availablePhysicalPages();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
SystemResources::diff(const SystemResources &pre)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
|
|
|
utime -= pre.utime;
|
|
|
|
stime -= pre.stime;
|
|
|
|
elapsed -= pre.elapsed;
|
|
|
|
idrss -= pre.idrss;
|
|
|
|
majflt -= pre.majflt;
|
|
|
|
}
|
|
|
|
|
|
|
|
// |JournalRecord::operator<<| symmetry code
|
|
|
|
JournalRecord &
|
|
|
|
JournalRecord::operator<<(const IntSequence &s)
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<('[');
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < s.size(); i++)
|
|
|
|
{
|
|
|
|
operator<<(s[i]);
|
|
|
|
if (i < s.size()-1)
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<(',');
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
2019-03-05 18:35:35 +01:00
|
|
|
operator<<(']');
|
2019-01-04 16:29:57 +01:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
JournalRecord::writeFloatTabular(std::ostream &s, double d, int width)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
// Number of digits of integer part
|
|
|
|
int intdigits = std::max(static_cast<int>(std::floor(log10(d))+1), 1);
|
|
|
|
|
|
|
|
int prec = std::max(width - 1 - intdigits, 0);
|
|
|
|
s << std::fixed << std::setw(width) << std::setprecision(prec) << d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
JournalRecord::writePrefix(const SystemResources &f)
|
|
|
|
{
|
|
|
|
constexpr double mb = 1024*1024;
|
|
|
|
std::ostringstream s;
|
|
|
|
s << std::setfill('0');
|
|
|
|
writeFloatTabular(s, f.elapsed, 7);
|
|
|
|
s << ':' << recChar << std::setw(5) << ord << ':';
|
|
|
|
writeFloatTabular(s, f.load_avg, 3);
|
|
|
|
s << ':';
|
|
|
|
writeFloatTabular(s, f.pg_avail*SystemResources::pageSize()/mb, 5);
|
|
|
|
s << ": : ";
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < 2*journal.getDepth(); i++)
|
2019-03-05 18:35:35 +01:00
|
|
|
s << ' ';
|
|
|
|
prefix = s.str();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2019-03-05 18:35:35 +01:00
|
|
|
JournalRecordPair::writePrefixForEnd(const SystemResources &f)
|
2019-01-04 16:29:57 +01:00
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
constexpr double mb = 1024*1024;
|
|
|
|
SystemResources difnow;
|
2019-01-04 16:29:57 +01:00
|
|
|
difnow.diff(f);
|
2019-03-05 18:35:35 +01:00
|
|
|
std::ostringstream s;
|
|
|
|
s << std::setfill('0');
|
|
|
|
writeFloatTabular(s, f.elapsed+difnow.elapsed, 7);
|
|
|
|
s << ":E" << std::setw(5) << ord << ':';
|
|
|
|
writeFloatTabular(s, difnow.load_avg, 3);
|
|
|
|
s << ':';
|
|
|
|
writeFloatTabular(s, difnow.pg_avail*SystemResources::pageSize()/mb, 5);
|
|
|
|
s << ':';
|
|
|
|
writeFloatTabular(s, difnow.majflt*SystemResources::pageSize()/mb, 6);
|
|
|
|
s << ": ";
|
2019-01-04 16:29:57 +01:00
|
|
|
for (int i = 0; i < 2*journal.getDepth(); i++)
|
2019-03-05 18:35:35 +01:00
|
|
|
s << ' ';
|
|
|
|
prefix_end = s.str();
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
JournalRecordPair::~JournalRecordPair()
|
|
|
|
{
|
|
|
|
journal.decrementDepth();
|
|
|
|
writePrefixForEnd(flash);
|
|
|
|
journal << prefix_end;
|
|
|
|
journal << mes;
|
2019-02-06 15:50:01 +01:00
|
|
|
journal << std::endl;
|
2019-01-04 16:29:57 +01:00
|
|
|
journal.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
JournalRecord &
|
|
|
|
endrec(JournalRecord &rec)
|
|
|
|
{
|
|
|
|
rec.journal << rec.prefix;
|
|
|
|
rec.journal << rec.mes;
|
2019-02-06 15:50:01 +01:00
|
|
|
rec.journal << std::endl;
|
2019-01-04 16:29:57 +01:00
|
|
|
rec.journal.flush();
|
|
|
|
rec.journal.incrementOrd();
|
|
|
|
return rec;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Journal::printHeader()
|
|
|
|
{
|
2019-03-05 18:35:35 +01:00
|
|
|
*this << "This is Dynare++, Copyright (C) 2004-2011, Ondra Kamenik\n"
|
|
|
|
<< "Dynare++ comes with ABSOLUTELY NO WARRANTY and is distributed under\n"
|
|
|
|
<< "GPL: modules integ, tl, kord, sylv, src, extern and documentation\n"
|
|
|
|
<< "LGPL: modules parser, utils\n"
|
|
|
|
<< " for GPL see http://www.gnu.org/licenses/gpl.html\n"
|
|
|
|
<< " for LGPL see http://www.gnu.org/licenses/lgpl.html\n"
|
|
|
|
<< "\n\n"
|
|
|
|
<< "System info: ";
|
|
|
|
#ifndef __MINGW32__
|
2019-01-04 16:29:57 +01:00
|
|
|
utsname info;
|
|
|
|
uname(&info);
|
2019-03-05 18:35:35 +01:00
|
|
|
*this << info.sysname << " " << info.release << " " << info.version << " "
|
|
|
|
<< info.machine << ", processors online: " << SystemResources::onlineProcessors();
|
2019-01-04 16:29:57 +01:00
|
|
|
#else
|
2019-03-05 18:35:35 +01:00
|
|
|
*this << "(not implemented for MinGW)";
|
2019-01-04 16:29:57 +01:00
|
|
|
#endif
|
2019-03-05 18:35:35 +01:00
|
|
|
*this << "\n\nStart time: ";
|
|
|
|
std::time_t t = std::time(nullptr);
|
|
|
|
*this << std::put_time(std::localtime(&t), "%c %Z")
|
|
|
|
<< "\n\n"
|
|
|
|
<< " ------ elapsed time (seconds) \n"
|
|
|
|
<< " | ------ record unique identifier \n"
|
|
|
|
<< " | | ------ load average \n"
|
|
|
|
<< " | | | ------ available memory (MB) \n"
|
|
|
|
<< " | | | | ------ major faults (MB)\n"
|
|
|
|
<< " | | | | | \n"
|
|
|
|
<< " V V V V V \n"
|
|
|
|
<< "\n";
|
2019-01-04 16:29:57 +01:00
|
|
|
}
|