@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 # include #endif #include #include #include 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 #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.