gettickcount.h

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 // Name:        common/timercmn.cpp
00003 // Purpose:     Common timer implementation
00004 // Author:
00005 //    Original version by Julian Smart
00006 //    Vadim Zeitlin got rid of all ifdefs (11.12.99)
00007 //    Sylvain Bougnoux added wxStopWatch class
00008 //    Guillermo Rodriguez <guille@iies.es> rewrote from scratch (Dic/99)
00009 // Modified by:
00010 // Created:     04/01/98
00011 // RCS-ID:      $Id: gettickcount.h 1172 2005-04-18 03:52:29Z madcat $
00012 // Copyright:   (c) Julian Smart and Markus Holzem
00013 //              (c) 1999 Guillermo Rodriguez <guille@iies.es>
00014 // Licence:     wxWindows license
00015 /////////////////////////////////////////////////////////////////////////////
00016 
00017 /** @file gettickcount.h Portable gettimeofday clone function. */
00018 
00019 
00020 #ifndef __GETTICKCOUNT_H__
00021 #define __GETTICKCOUNT_H__
00022 
00023 #if !defined(HAVE_CONFIG_H)
00024         #if defined(__linux__) || defined(__FreeBSD__)
00025                 #define HAVE_GETTIMEOFDAY
00026         #endif
00027 #endif
00028 
00029 #if defined(WIN32) || defined(_MSC_VER)
00030         // Prevents inclusion of winsock1 API when this file is included before
00031         // winsock2.h gets included.
00032         #define _WINSOCKAPI_ 
00033         #include <windows.h>
00034         // No, thank you very much, we do NOT need these macros.
00035         #undef max
00036         #undef min
00037 #elif defined(HAVE_GETTIMEOFDAY)
00038         #include <sys/time.h>
00039 #elif defined(__MAC__)
00040         #include <Timer.h>
00041         #include <DriverServices.h>
00042         #undef check   // we don't want this macro defined
00043         #undef verify  // we don't want this macro defined
00044 #elif defined(HAVE_FTIME)
00045         #include <sys/timeb.h>
00046 #endif
00047 
00048 #include <hn/osdep.h>
00049 
00050 namespace Utils {
00051 
00052 /**
00053  * getTick() function copied from wxWidgets library wxGetLocalTimeMillis()
00054  * function (from src/common/timercmn.cpp)
00055  */
00056 inline uint64_t getTick() {
00057 #if defined(WIN32) || defined(_MSC_VER)
00058         // 00:00:00 Jan 1st 1970
00059         SYSTEMTIME thenst = { 1970, 1, 4, 1, 0, 0, 0, 0 };
00060         FILETIME thenft;
00061         SystemTimeToFileTime(&thenst, &thenft);
00062 
00063         // time in 100 nanoseconds
00064         uint64_t then = thenft.dwHighDateTime;
00065         then <<= 32;
00066         then += thenft.dwLowDateTime;
00067 
00068         SYSTEMTIME nowst;
00069         GetLocalTime(&nowst);
00070         FILETIME nowft;
00071         SystemTimeToFileTime(&nowst, &nowft);
00072 
00073         // time in 100 nanoseconds
00074         uint64_t now = nowft.dwHighDateTime;
00075         now <<= 32;
00076         now += nowft.dwLowDateTime;
00077 
00078         // time from 00:00:00 Jan 1st 1970 to now in milliseconds
00079         return (now - then) / 10000;
00080 
00081 #elif defined(HAVE_GETTIMEOFDAY)
00082         uint64_t val = 1000l;
00083         struct timeval tp;
00084         if (gettimeofday(&tp, (struct timezone *)0) != -1) {
00085                 val *= tp.tv_sec;
00086                 return (val + (tp.tv_usec / 1000));
00087         } else {
00088                 return 0;
00089         }
00090 #elif defined(HAVE_FTIME)
00091         uint64_t val = 1000l;
00092         struct timeb tp;
00093 
00094         // ftime() is void and not int in some mingw32 headers, so don't
00095         // test the return code (well, it shouldn't fail anyhow...)
00096         (void)ftime(&tp);
00097         val *= tp.time;
00098         return (val + tp.millitm);
00099 #elif defined(__MAC__)
00100         uint64_t val = 1000l;
00101         static UInt64 gMilliAtStart = 0;
00102 
00103         Nanoseconds upTime = AbsoluteToNanoseconds( UpTime() );
00104 
00105         if (gMilliAtStart == 0) {
00106             time_t start = time(NULL);
00107             gMilliAtStart = ((UInt64) start) * 1000000L;
00108             gMilliAtStart -= upTime.lo / 1000 ;
00109             gMilliAtStart -= ( ( (UInt64) upTime.hi ) << 32 ) / (1000 * 1000);
00110         }
00111 
00112         UInt64 millival = gMilliAtStart;
00113         millival += upTime.lo / (1000 * 1000);
00114         millival += ( ( (UInt64) upTime.hi ) << 32 ) / (1000 * 1000);
00115         val = millival;
00116 
00117         return val;
00118 #else
00119         #error GetTickCount not implemented for your platform.
00120 #endif
00121 }
00122 
00123 } // namespace Utils
00124 
00125 #endif