Index   Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

SgTime.cpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file SgTime.cpp
00003     See SgTime.h. */
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) // Shouldn't happen
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 } // namespace
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             // Do not cast FILETIME to ULARGE_INTEGER because it can cause alignment
00100             // faults on 64-bit Windows (according to MSDN docs)
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             // Implementation using POSIX functions
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 


Sun Mar 13 2011 Doxygen 1.7.1