dynare/dynare++/kord/journal.cweb

294 lines
7.5 KiB
Plaintext

@q Copyright (C) 2004-2011, Ondra Kamenik @>
@ Start of {\tt journal.cpp} file.
@c
#include "journal.h"
#include "kord_exception.h"
#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@>;
#endif
#if defined(__APPLE__)
#define _SC_PHYS_PAGES 2
#define _SC_AVPHYS_PAGES 3
#endif
@<|SystemResources| constructor code@>;
@<|SystemResources::pageSize| code@>;
@<|SystemResources::physicalPages| code@>;
@<|SystemResources::onlineProcessors| code@>;
@<|SystemResources::availableMemory| code@>;
@<|SystemResources::getRUS| code@>;
@<|SystemResourcesFlash| constructor code@>;
@<|SystemResourcesFlash::diff| code@>;
@<|JournalRecord::operator<<| symmetry code@>;
@<|JournalRecord::writePrefix| code@>;
@<|JournalRecord::writePrefixForEnd| code@>;
@<|JournalRecordPair| destructor code@>;
@<|endrec| code@>;
@<|Journal::printHeader| code@>;
@
@<|SystemResources| constructor code@>=
SystemResources::SystemResources()
{
gettimeofday(&start, NULL);
}
@
@<|SystemResources::pageSize| code@>=
long int SystemResources::pageSize()
{
return sysconf(_SC_PAGESIZE);
}
@
@<|SystemResources::physicalPages| code@>=
long int SystemResources::physicalPages()
{
return sysconf(_SC_PHYS_PAGES);
}
@
@<|SystemResources::onlineProcessors| code@>=
long int SystemResources::onlineProcessors()
{
return sysconf(_SC_NPROCESSORS_ONLN);
}
@
@<|SystemResources::availableMemory| code@>=
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.
@<|SystemResources::getRUS| code@>=
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, NULL);
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
#if !defined(__MINGW32__) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) && !defined(__MINGW64__) && !defined(__CYGWIN64__)
getloadavg(&load_avg, 1);
#else
load_avg = -1.0;
#endif
pg_avail = sysconf(_SC_AVPHYS_PAGES);
}
@
@<|SystemResourcesFlash| constructor code@>=
SystemResourcesFlash::SystemResourcesFlash()
{
_sysres.getRUS(load_avg, pg_avail, utime, stime,
elapsed, idrss, majflt);
}
@
@<|SystemResourcesFlash::diff| code@>=
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;
}
@
@<|JournalRecord::writePrefix| code@>=
void JournalRecord::writePrefix(const SystemResourcesFlash& f)
{
for (int i = 0; i < MAXLEN; 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';
}
@
@<|JournalRecord::writePrefixForEnd| code@>=
void JournalRecordPair::writePrefixForEnd(const SystemResourcesFlash& f)
{
for (int i = 0; i < MAXLEN; 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| destructor code@>=
JournalRecordPair::~JournalRecordPair()
{
journal.decrementDepth();
writePrefixForEnd(flash);
journal << prefix_end;
journal << mes;
journal << endl;
journal.flush();
}
@
@<|endrec| code@>=
JournalRecord& endrec(JournalRecord& rec)
{
rec.journal << rec.prefix;
rec.journal << rec.mes;
rec.journal << endl;
rec.journal.flush();
rec.journal.incrementOrd();
return rec;
}
@
@<|Journal::printHeader| code@>=
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(NULL);
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";
}
@ 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.
@<|sysconf| Win32 implementation@>=
#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;
}
}
@ End of {\tt journal.cpp} file.