dynare/dynare++/kord/journal.cc

261 lines
6.6 KiB
C++
Raw Normal View History

// Copyright (C) 2004-2011, Ondra Kamenik
#include "journal.hh"
#include "kord_exception.hh"
#if !defined(__MINGW32__)
# include <sys/resource.h>
# include <sys/utsname.h>
#endif
#include <cstdlib>
#include <unistd.h>
#include <ctime>
SystemResources _sysres;
#if defined(__MINGW32__)
//|sysconf| Win32 implementation
/* Here we implement |sysconf| for MinGW. We implement only page size,
number of physial pages, and a number of available physical pages. The
pagesize is set to 1024 bytes, real pagesize can differ but it is not
important. We can do this since Windows kernel32 |GlobalMemoryStatus|
call returns number of bytes.
Number of online processors is not implemented and returns -1, since
Windows kernel32 |GetSystemInfo| call is too complicated. */
# ifndef NOMINMAX
# define NOMINMAX // Do not define "min" and "max" macros
# endif
# include <windows.h>
# define _SC_PAGESIZE 1
# define _SC_PHYS_PAGES 2
# define _SC_AVPHYS_PAGES 3
# define _SC_NPROCESSORS_ONLN 4
long
sysconf(int name)
{
switch (name)
{
case _SC_PAGESIZE:
return 1024;
case _SC_PHYS_PAGES:
{
MEMORYSTATUS memstat;
GlobalMemoryStatus(&memstat);
return memstat.dwTotalPhys/1024;
}
case _SC_AVPHYS_PAGES:
{
MEMORYSTATUS memstat;
GlobalMemoryStatus(&memstat);
return memstat.dwAvailPhys/1024;
}
case _SC_NPROCESSORS_ONLN:
return -1;
default:
KORD_RAISE("Not implemented in Win32 sysconf.");
return -1;
}
}
#endif
#if defined(__APPLE__)
# define _SC_PHYS_PAGES 2
# define _SC_AVPHYS_PAGES 3
#endif
SystemResources::SystemResources()
{
gettimeofday(&start, nullptr);
}
long int
SystemResources::pageSize()
{
return sysconf(_SC_PAGESIZE);
}
long int
SystemResources::physicalPages()
{
return sysconf(_SC_PHYS_PAGES);
}
long int
SystemResources::onlineProcessors()
{
return sysconf(_SC_NPROCESSORS_ONLN);
}
long int
SystemResources::availableMemory()
{
return pageSize()*sysconf(_SC_AVPHYS_PAGES);
}
/* Here we read the current values of resource usage. For MinGW, we
implement only a number of available physical memory pages. */
void
SystemResources::getRUS(double &load_avg, long int &pg_avail,
double &utime, double &stime, double &elapsed,
long int &idrss, long int &majflt)
{
struct timeval now;
gettimeofday(&now, nullptr);
elapsed = now.tv_sec-start.tv_sec + (now.tv_usec-start.tv_usec)*1.0e-6;
#if !defined(__MINGW32__)
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
#define MINGCYGTMP (!defined(__MINGW32__) && !defined(__CYGWIN32__) && !defined(__CYGWIN__))
#define MINGCYG (MINGCYGTMP && !defined(__MINGW64__) && !defined(__CYGWIN64__))
#if MINGCYG
getloadavg(&load_avg, 1);
#else
load_avg = -1.0;
#endif
pg_avail = sysconf(_SC_AVPHYS_PAGES);
}
SystemResourcesFlash::SystemResourcesFlash()
{
_sysres.getRUS(load_avg, pg_avail, utime, stime,
elapsed, idrss, majflt);
}
void
SystemResourcesFlash::diff(const SystemResourcesFlash &pre)
{
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)
{
operator<<("[");
for (int i = 0; i < s.size(); i++)
{
operator<<(s[i]);
if (i < s.size()-1)
operator<<(",");
}
operator<<("]");
return *this;
}
void
JournalRecord::writePrefix(const SystemResourcesFlash &f)
{
for (char & i : prefix)
i = ' ';
double mb = 1024*1024;
sprintf(prefix, "%07.6g", f.elapsed);
sprintf(prefix+7, ":%c%05d", recChar, ord);
sprintf(prefix+14, ":%1.1f", f.load_avg);
sprintf(prefix+18, ":%05.4g", f.pg_avail*_sysres.pageSize()/mb);
sprintf(prefix+24, "%s", ": : ");
for (int i = 0; i < 2*journal.getDepth(); i++)
prefix[i+33] = ' ';
prefix[2*journal.getDepth()+33] = '\0';
}
void
JournalRecordPair::writePrefixForEnd(const SystemResourcesFlash &f)
{
for (char & i : prefix_end)
i = ' ';
double mb = 1024*1024;
SystemResourcesFlash difnow;
difnow.diff(f);
sprintf(prefix_end, "%07.6g", f.elapsed+difnow.elapsed);
sprintf(prefix_end+7, ":E%05d", ord);
sprintf(prefix_end+14, ":%1.1f", difnow.load_avg);
sprintf(prefix_end+18, ":%05.4g", difnow.pg_avail*_sysres.pageSize()/mb);
sprintf(prefix_end+24, ":%06.5g", difnow.majflt*_sysres.pageSize()/mb);
sprintf(prefix_end+31, "%s", ": ");
for (int i = 0; i < 2*journal.getDepth(); i++)
prefix_end[i+33] = ' ';
prefix_end[2*journal.getDepth()+33] = '\0';
}
JournalRecordPair::~JournalRecordPair()
{
journal.decrementDepth();
writePrefixForEnd(flash);
journal << prefix_end;
journal << mes;
journal << std::endl;
journal.flush();
}
JournalRecord &
endrec(JournalRecord &rec)
{
rec.journal << rec.prefix;
rec.journal << rec.mes;
rec.journal << std::endl;
rec.journal.flush();
rec.journal.incrementOrd();
return rec;
}
void
Journal::printHeader()
{
(*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";
#if !defined(__MINGW32__)
utsname info;
uname(&info);
(*this)<< "System info: ";
(*this)<< info.sysname << " " << info.release << " " << info.version << " ";
(*this)<< info.machine << ", processors online: " << _sysres.onlineProcessors();
(*this)<< "\n\nStart time: ";
char ts[100];
time_t curtime = time(nullptr);
tm loctime;
localtime_r(&curtime, &loctime);
asctime_r(&loctime, ts);
(*this)<< ts << "\n";
#else
(*this) << "System info: (not implemented for MINGW)\n";
(*this) << "Start time: (not implemented for MINGW)\n\n";
#endif
(*this)<< " ------ elapsed time (seconds) \n";
(*this)<< " | ------ record unique identifier \n";
(*this)<< " | | ------ load average \n";
(*this)<< " | | | ------ available memory (MB) \n";
(*this)<< " | | | | ------ major faults (MB)\n";
(*this)<< " | | | | | \n";
(*this)<< " V V V V V \n";
(*this)<< "\n";
}