# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

time_nl.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
00024  */
00025 
00026 #include "stdmisc.h"
00027 
00028 #include <time.h>
00029 
00030 #ifdef NL_OS_WINDOWS
00031 #       include <windows.h>
00032 #elif defined (NL_OS_UNIX)
00033 #       include <sys/time.h>
00034 #       include <unistd.h>
00035 #endif
00036 
00037 #include "nel/misc/time_nl.h"
00038 
00039 namespace NLMISC
00040 {
00041 
00042 /*
00043  *
00044  */
00045 uint32 CTime::getSecondsSince1970 ()
00046 {
00047         return (uint32) time (NULL);
00048 }
00049 
00050 
00051 
00052 /*
00053  *
00054  */
00055 TTime CTime::getLocalTime ()
00056 {
00057 #ifdef NL_OS_WINDOWS
00058 
00059         static bool byperfcounter;
00060         static bool initdone = false;
00061 
00062         // Initialization
00063         if ( ! initdone )
00064         {
00065                 byperfcounter = (getPerformanceTime() != 0);
00066                 initdone = true;
00067         }
00068 
00069         /* Retrieve time is ms
00070      * Why do we prefer getPerformanceTime() to timeGetTime() ? Because on one dual-processor Win2k
00071          * PC, we have noticed that timeGetTime() slows down when the client is running !!!
00072          */
00073 
00074 
00075         /* Now we have noticed that on all WinNT4 PC the getPerformanceTime can give us value that
00076          * are less than previous
00077          */
00078 
00079         //if ( byperfcounter )
00080         //{
00081         //      return (TTime)(ticksToSecond(getPerformanceTime()) * 1000.0f);
00082         //}
00083         //else
00084         //{
00085                 return timeGetTime();
00086         //}
00087 
00088 #elif defined (NL_OS_UNIX)
00089 
00090         struct timeval tv;
00091 
00092         if ( gettimeofday( &tv, NULL) == -1 )
00093         {
00094                 nlerror ("Cannot get time of day.");
00095         }
00096         return (TTime)tv.tv_sec * (TTime)1000 + (TTime)tv.tv_usec / (TTime)1000;
00097 
00098 #endif
00099 }
00100 
00101 
00102 /*
00103  *
00104  */
00105 TTicks CTime::getPerformanceTime ()
00106 {
00107 #ifdef NL_OS_WINDOWS
00108         LARGE_INTEGER ret;
00109         if (QueryPerformanceCounter (&ret))
00110                 return ret.QuadPart;
00111         else
00112                 return 0;
00113 #else // NL_OS_WINDOWS
00114 
00115 #ifdef HAVE_X86
00116         unsigned long long int x;
00117         __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
00118         return x;
00119 #else HAVE_X86
00120         static bool firstWarn = true;
00121         if (firstWarn)
00122         {
00123                 nlwarning ("TTicks CTime::getPerformanceTime () is not implemented for your processor, returning 0");
00124                 firstWarn = false;
00125         }
00126         return 0;
00127 #endif // HAVE_X86
00128 
00129 #endif // NL_OS_WINDOWS
00130 }
00131 /*
00132 #define GETTICKS(t) asm volatile ("push %%esi\n\t" "mov %0, %%esi" : : "r" (t)); \
00133                       asm volatile ("push %eax\n\t" "push %edx"); \
00134                       asm volatile ("rdtsc"); \
00135                       asm volatile ("movl %eax, (%esi)\n\t" "movl %edx, 4(%esi)"); \
00136                       asm volatile ("pop %edx\n\t" "pop %eax\n\t" "pop %esi"); 
00137 */
00138 
00139 
00140 /*
00141  *
00142  */
00143 double CTime::ticksToSecond (TTicks ticks)
00144 {
00145 #ifdef NL_OS_WINDOWS
00146         LARGE_INTEGER ret;
00147         if (QueryPerformanceFrequency(&ret))
00148         {
00149                 return (double)(sint64)ticks/(double)ret.QuadPart;
00150         }
00151         else
00152 #endif // NL_OS_WINDOWS
00153         {
00154                 static bool benchFrequency = true;
00155                 static sint64 freq = 0;
00156                 if (benchFrequency)
00157                 {
00158                         // try to have an estimation of the cpu frequency
00159 
00160                         TTicks tickBefore = getPerformanceTime ();
00161                         TTicks tickAfter = tickBefore;
00162                         TTime timeBefore = getLocalTime ();
00163                         TTime timeAfter = timeBefore;
00164                         while (true)
00165                         {
00166                                 if (timeAfter - timeBefore > 1000)
00167                                         break;
00168                                 timeAfter = getLocalTime ();
00169                                 tickAfter = getPerformanceTime ();
00170                         }
00171 
00172                         TTime timeDelta = timeAfter - timeBefore;
00173                         TTicks tickDelta = tickAfter - tickBefore;
00174 
00175                         freq = 1000 * tickDelta / timeDelta;
00176                         benchFrequency = false;
00177                 }
00178 
00179                 return (double)(sint64)ticks/(double)freq;
00180         }
00181 }
00182 
00183 
00184 } // NLMISC