GetTime.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. /// \file
  11. ///
  12. #if defined(_WIN32)
  13. #include "WindowsIncludes.h"
  14. #if !defined(WINDOWS_PHONE_8)
  15. // To call timeGetTime
  16. // on Code::Blocks, this needs to be libwinmm.a instead
  17. #pragma comment(lib, "Winmm.lib")
  18. #endif
  19. #endif
  20. #include "GetTime.h"
  21. #if defined(_WIN32)
  22. //DWORD mProcMask;
  23. //DWORD mSysMask;
  24. //HANDLE mThread;
  25. #else
  26. #include <sys/time.h>
  27. #include <unistd.h>
  28. RakNet::TimeUS initialTime;
  29. #endif
  30. static bool initialized=false;
  31. #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  32. #include "SimpleMutex.h"
  33. RakNet::TimeUS lastNormalizedReturnedValue=0;
  34. RakNet::TimeUS lastNormalizedInputValue=0;
  35. /// This constraints timer forward jumps to 1 second, and does not let it jump backwards
  36. /// See http://support.microsoft.com/kb/274323 where the timer can sometimes jump forward by hours or days
  37. /// This also has the effect where debugging a sending system won't treat the time spent halted past 1 second as elapsed network time
  38. RakNet::TimeUS NormalizeTime(RakNet::TimeUS timeIn)
  39. {
  40. RakNet::TimeUS diff, lastNormalizedReturnedValueCopy;
  41. static RakNet::SimpleMutex mutex;
  42. mutex.Lock();
  43. if (timeIn>=lastNormalizedInputValue)
  44. {
  45. diff = timeIn-lastNormalizedInputValue;
  46. if (diff > GET_TIME_SPIKE_LIMIT)
  47. lastNormalizedReturnedValue+=GET_TIME_SPIKE_LIMIT;
  48. else
  49. lastNormalizedReturnedValue+=diff;
  50. }
  51. else
  52. lastNormalizedReturnedValue+=GET_TIME_SPIKE_LIMIT;
  53. lastNormalizedInputValue=timeIn;
  54. lastNormalizedReturnedValueCopy=lastNormalizedReturnedValue;
  55. mutex.Unlock();
  56. return lastNormalizedReturnedValueCopy;
  57. }
  58. #endif // #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  59. RakNet::Time RakNet::GetTime( void )
  60. {
  61. return (RakNet::Time)(GetTimeUS()/1000);
  62. }
  63. RakNet::TimeMS RakNet::GetTimeMS( void )
  64. {
  65. return (RakNet::TimeMS)(GetTimeUS()/1000);
  66. }
  67. #if defined(_WIN32)
  68. RakNet::TimeUS GetTimeUS_Windows( void )
  69. {
  70. if ( initialized == false)
  71. {
  72. initialized = true;
  73. // Save the current process
  74. #if !defined(_WIN32_WCE)
  75. // HANDLE mProc = GetCurrentProcess();
  76. // Get the current Affinity
  77. #if _MSC_VER >= 1400 && defined (_M_X64)
  78. // GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
  79. #else
  80. // GetProcessAffinityMask(mProc, &mProcMask, &mSysMask);
  81. #endif
  82. // mThread = GetCurrentThread();
  83. #endif // _WIN32_WCE
  84. }
  85. // 9/26/2010 In China running LuDaShi, QueryPerformanceFrequency has to be called every time because CPU clock speeds can be different
  86. RakNet::TimeUS curTime;
  87. LARGE_INTEGER PerfVal;
  88. LARGE_INTEGER yo1;
  89. QueryPerformanceFrequency( &yo1 );
  90. QueryPerformanceCounter( &PerfVal );
  91. __int64 quotient, remainder;
  92. quotient=((PerfVal.QuadPart) / yo1.QuadPart);
  93. remainder=((PerfVal.QuadPart) % yo1.QuadPart);
  94. curTime = (RakNet::TimeUS) quotient*(RakNet::TimeUS)1000000 + (remainder*(RakNet::TimeUS)1000000 / yo1.QuadPart);
  95. #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  96. return NormalizeTime(curTime);
  97. #else
  98. return curTime;
  99. #endif // #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  100. }
  101. #elif defined(__GNUC__) || defined(__GCCXML__) || defined(__S3E__)
  102. RakNet::TimeUS GetTimeUS_Linux( void )
  103. {
  104. timeval tp;
  105. if ( initialized == false)
  106. {
  107. gettimeofday( &tp, 0 );
  108. initialized=true;
  109. // I do this because otherwise RakNet::Time in milliseconds won't work as it will underflow when dividing by 1000 to do the conversion
  110. initialTime = ( tp.tv_sec ) * (RakNet::TimeUS) 1000000 + ( tp.tv_usec );
  111. }
  112. // GCC
  113. RakNet::TimeUS curTime;
  114. gettimeofday( &tp, 0 );
  115. curTime = ( tp.tv_sec ) * (RakNet::TimeUS) 1000000 + ( tp.tv_usec );
  116. #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  117. return NormalizeTime(curTime - initialTime);
  118. #else
  119. return curTime - initialTime;
  120. #endif // #if defined(GET_TIME_SPIKE_LIMIT) && GET_TIME_SPIKE_LIMIT>0
  121. }
  122. #endif
  123. RakNet::TimeUS RakNet::GetTimeUS( void )
  124. {
  125. #if defined(_WIN32)
  126. return GetTimeUS_Windows();
  127. #else
  128. return GetTimeUS_Linux();
  129. #endif
  130. }
  131. bool RakNet::GreaterThan(RakNet::Time a, RakNet::Time b)
  132. {
  133. // a > b?
  134. const RakNet::Time halfSpan =(RakNet::Time) (((RakNet::Time)(const RakNet::Time)-1)/(RakNet::Time)2);
  135. return b!=a && b-a>halfSpan;
  136. }
  137. bool RakNet::LessThan(RakNet::Time a, RakNet::Time b)
  138. {
  139. // a < b?
  140. const RakNet::Time halfSpan = ((RakNet::Time)(const RakNet::Time)-1)/(RakNet::Time)2;
  141. return b!=a && b-a<halfSpan;
  142. }
粤ICP备19079148号