Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "SgSystem.h"
00007 #include "SgTime.h"
00008
00009 #include <cstring>
00010 #include <ctime>
00011 #include <iomanip>
00012 #include <limits>
00013 #include <iostream>
00014 #include <sstream>
00015 #include <errno.h>
00016 #if WIN32
00017 #include <Windows.h>
00018 #else
00019 #include <sys/times.h>
00020 #include <unistd.h>
00021 #endif
00022 #include <boost/date_time/posix_time/posix_time.hpp>
00023 #include "SgException.h"
00024
00025 using namespace std;
00026 using boost::posix_time::microsec_clock;
00027 using boost::posix_time::ptime;
00028 using boost::posix_time::time_duration;
00029
00030
00031
00032 namespace {
00033
00034 SgTimeMode g_defaultMode = SG_TIME_REAL;
00035
00036 bool g_isInitialized = false;
00037
00038 ptime g_start;
00039
00040 #if ! WIN32
00041 clock_t g_ticksPerSecond;
00042
00043 clock_t g_ticksPerMinute;
00044 #endif
00045
00046 void Init()
00047 {
00048 #if ! WIN32
00049 long ticksPerSecond = sysconf(_SC_CLK_TCK);
00050 if (ticksPerSecond < 0)
00051 throw SgException("Could not get _SC_CLK_TCK.");
00052 g_ticksPerSecond = static_cast<clock_t>(ticksPerSecond);
00053 g_ticksPerMinute = 60 * g_ticksPerSecond;
00054 #endif
00055 g_start = microsec_clock::universal_time();
00056 g_isInitialized = true;
00057 }
00058
00059 }
00060
00061
00062
00063 string SgTime::Format(double time, bool minsAndSecs)
00064 {
00065 ostringstream out;
00066 if (minsAndSecs)
00067 {
00068 int mins = static_cast<int>(time / 60);
00069 int secs = static_cast<int>(time - mins * 60);
00070 out << setw(2) << mins << ':' << setw(2) << setfill('0')
00071 << secs;
00072 }
00073 else
00074 out << setprecision(2) << fixed << time;
00075 return out.str();
00076 }
00077
00078 double SgTime::Get()
00079 {
00080 return Get(g_defaultMode);
00081 }
00082
00083 double SgTime::Get(SgTimeMode mode)
00084 {
00085 if (! g_isInitialized)
00086 Init();
00087 switch (mode)
00088 {
00089 case SG_TIME_CPU:
00090 {
00091 #if WIN32
00092 FILETIME creationTime;
00093 FILETIME exitTime;
00094 FILETIME kernelTime;
00095 FILETIME userTime;
00096 HANDLE handle = GetCurrentProcess();
00097 if (! GetProcessTimes(handle, &creationTime, &exitTime, &kernelTime, &userTime))
00098 throw SgException("GetProcessTimes() returned an error");
00099
00100
00101 ULARGE_INTEGER kernelInteger;
00102 kernelInteger.LowPart = kernelTime.dwLowDateTime;
00103 kernelInteger.HighPart = kernelTime.dwHighDateTime;
00104 ULARGE_INTEGER userInteger;
00105 userInteger.LowPart = userTime.dwLowDateTime;
00106 userInteger.HighPart = userTime.dwHighDateTime;
00107 ULARGE_INTEGER totalTime;
00108 totalTime.QuadPart= kernelInteger.QuadPart + userInteger.QuadPart;
00109 return double(totalTime.QuadPart * 1e-7);
00110 #else
00111
00112 struct tms buf;
00113 if (times(&buf) == static_cast<clock_t>(-1))
00114 {
00115 std::cerr << "Time measurement overflow.\n";
00116 return 0;
00117 }
00118 clock_t clockTicks =
00119 buf.tms_utime + buf.tms_stime
00120 + buf.tms_cutime + buf.tms_cstime;
00121 return double(clockTicks) / double(g_ticksPerSecond);
00122 #endif
00123 }
00124 case SG_TIME_REAL:
00125 {
00126 time_duration diff = microsec_clock::universal_time() - g_start;
00127 return double(diff.total_nanoseconds()) * 1e-9;
00128 }
00129 default:
00130 SG_ASSERT(false);
00131 return 0;
00132 }
00133 }
00134
00135 SgTimeMode SgTime::DefaultMode()
00136 {
00137 return g_defaultMode;
00138 }
00139
00140 void SgTime::SetDefaultMode(SgTimeMode mode)
00141 {
00142 g_defaultMode = mode;
00143 }
00144
00145 string SgTime::TodaysDate()
00146 {
00147 time_t systime = time(0);
00148 struct tm* currtime = localtime(&systime);
00149 const int BUF_SIZE = 14;
00150 char buf[BUF_SIZE];
00151 strftime(buf, BUF_SIZE - 1, "%Y-%m-%d", currtime);
00152 return string(buf);
00153 }
00154
00155
00156