Files
LayaNative2.0/Conch/source/common/misc/JCGetClockExact.cpp
T
2020-11-11 16:17:13 +08:00

182 lines
3.1 KiB
C++

/**
@file JCGetClockExact.cpp
@brief
@author James
@version 1.0
@date 2016_5_12
*/
#include "JCGetClockExact.h"
#include <atomic>
#ifdef WIN32
#include <windows.h>
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")
HANDLE _l_hTimerEvent = 0;
UINT64 _l_u64_machine_cpu_freq = 0;
UINT _l_dwTimerRes = 0;
UINT64 _l_u64CurrentTime = 0;
UINT64 _l_u64StartupTime = 0;
DWORD _l_dwTimerID = 0;
inline void _GetCurrentTime()
{
::QueryPerformanceCounter( (LARGE_INTEGER *)&_l_u64CurrentTime );
_l_u64CurrentTime = _l_u64CurrentTime * 1000 / _l_u64_machine_cpu_freq;
}
static bool __InitWindowsTimer()
{
TIMECAPS tc;
if(::timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
{
return false;
}
if( tc.wPeriodMin > 1 )
_l_dwTimerRes = tc.wPeriodMin;
else
_l_dwTimerRes = 1;
if( ::timeBeginPeriod( _l_dwTimerRes ) != TIMERR_NOERROR )
{
_l_dwTimerRes = 0;
return false;
}
::QueryPerformanceFrequency( (LARGE_INTEGER *)&_l_u64_machine_cpu_freq );
if( NULL == (_l_hTimerEvent = ::CreateEvent( NULL, FALSE, FALSE, NULL )) )
{
return false;
}
_GetCurrentTime();
_l_u64StartupTime = _l_u64CurrentTime;
if( (_l_dwTimerID = ::timeSetEvent(
5, // 延时
_l_dwTimerRes, // 分辨率
(LPTIMECALLBACK)_l_hTimerEvent, // 事件接收句柄
(DWORD)0,
TIME_PERIODIC|TIME_CALLBACK_EVENT_SET )) == NULL )
{
return false;
}
return true;
}
static void __ReleaseWindowsTimer()
{
if( 0 != _l_dwTimerID )
{
::timeKillEvent( _l_dwTimerID );
_l_dwTimerID = 0;
}
if( 0 != _l_hTimerEvent )
{
::CloseHandle( _l_hTimerEvent );
_l_hTimerEvent = 0;
}
if( 0 != _l_dwTimerRes )
{
::timeEndPeriod( _l_dwTimerRes );
_l_dwTimerRes = 0;
}
}
#else // WIN32
#include <unistd.h>
#endif // WIN32
JCGetClockExact::JCGetClockExact()
{
m_CurTime_ms = 0;
m_pThread = 0;
m_bWantStop = false;
}
JCGetClockExact::~JCGetClockExact()
{
}
bool JCGetClockExact::Init()
{
if( 0 != m_pThread )
return false;
#ifdef WIN32
if( !__InitWindowsTimer() )
return false;
#endif
m_bWantStop = false;
m_pThread = new std::thread( std::bind(&JCGetClockExact::__WorkThread, this) );
return true;
}
void JCGetClockExact::Stop()
{
m_bWantStop = true;
if( 0 != m_pThread )
{
m_pThread->join();
delete m_pThread;
m_pThread = 0;
}
#ifdef WIN32
__ReleaseWindowsTimer();
#endif
}
void JCGetClockExact::__WorkThread()
{
#ifdef WIN32
__WindowsTimeThread();
#else
__LinuxTimeThread();
#endif
}
#ifdef WIN32
void JCGetClockExact::__WindowsTimeThread()
{
std::uint32_t ulCur;
for(;!m_bWantStop;)
{
::WaitForSingleObject( _l_hTimerEvent, INFINITE );
_GetCurrentTime();
ulCur = (std::uint32_t)(_l_u64CurrentTime - _l_u64StartupTime);
m_CurTime_ms = ulCur;
}
}
#else
void JCGetClockExact::__LinuxTimeThread()
{
std::uint32_t _TmpCurTime = m_CurTime_ms;
for(;!m_bWantStop;)
{
usleep( 5000 );
_TmpCurTime += 5;
// std::interprocess::ipcdetail::atomic_inc32( &m_CurTime_ms );
m_CurTime_ms = _TmpCurTime;
}
}
#endif
//------------------------------------------------------------------------------
//-----------------------------END FILE--------------------------------