Files
mir_server/sdk/utils/Tick.cpp

118 lines
3.3 KiB
C++
Raw Normal View History

2025-01-09 17:45:40 +08:00
#include <limits.h>
#ifdef WIN32
#include <time.h>
#include <tchar.h>
#endif
#include "_osdef.h"
#include "Tick.h"
#include "Lock.h"
using namespace wylib::time::tick64;
static TICKCOUNT64 UserSetTick = 0;
#ifndef WIN32
unsigned int timeGetTime()
{
unsigned int uptime = 0;
struct timespec on;
if(clock_gettime(CLOCK_MONOTONIC, &on) == 0)
uptime = on.tv_sec*1000 + on.tv_nsec/1000000;
return uptime;
}
#endif
/***
timeGetTime实现的GetTickCount64具有较高的性能
QueryPerformanceCounter的实现则是timeGetTime版本时间消耗的300倍
***/
//static LONG dwAtomLock = 0;
#ifdef WIN32
static MMRESULT mmPeriod = timeBeginPeriod(1);
#endif
static TICKCOUNT64 llTickBase = 0;
static TICKCOUNT64 llStartTick = timeGetTime();
static DWORD dwLastShortTick = timeGetTime();
TICKCOUNT64 wylib::time::tick64::GetTickCount64()
{
if (UserSetTick)
return UserSetTick;
/*
dwLastShortTick导致保存为局部变量并尝试通过保存的值以锁总线的方式改变dwLastShortTick的值
dwLastShortTick的值的期间线使线线
线线线dwLastShortTick的值线
dwLastShortTick的值将导致错误的结果并会错误的判断为进入了一个49天的循环并修改llTickBase的值
使使
*/
DWORD dwLastTick = dwLastShortTick;
DWORD dwTick = timeGetTime();
#ifdef WIN32
if (InterlockedCompareExchange((volatile long*)&dwLastShortTick, (long)dwTick, (long)dwLastTick) == dwLastTick)
#else
if (__sync_val_compare_and_swap((volatile long*)&dwLastShortTick, (long)dwLastTick, (long)dwTick) == dwLastTick)
#endif
{
if (dwTick < dwLastTick)
{
#ifdef WIN32
if (IsDebuggerPresent())
{
//请手动确认此处是否未发生BUG而是系统真正的经过了49天的循环并按继续键……
OutputDebugString(_T("请手动确认此处是否未发生BUG而是系统真正的经过了49天的循环"));
DebugBreak();
}
llTickBase += 0x1UI64 << 32;
#else
llTickBase += 0x1LL << 32;
#endif
}
}
return llTickBase + dwTick - llStartTick;
}
/*
TICKCOUNT64 wylib::time::tick64::GetTickCount64()
{
if (UserSetTick)
return UserSetTick;
static LARGE_INTEGER Frequency;
static BOOL boSuportPerformanceTick = QueryPerformanceFrequency(&Frequency);
LARGE_INTEGER tick;
TICKCOUNT64 sec, milpart;
if ( !boSuportPerformanceTick )
{
return timeGetTime();
}
QueryPerformanceCounter( &tick );
sec = tick.QuadPart / Frequency.QuadPart;
milpart = tick.QuadPart - (sec * Frequency.QuadPart);
return sec * 1000 + milpart * 1000 / Frequency.QuadPart;
}
*/
TICKCOUNT64 wylib::time::tick64::SetTickCount64(TICKCOUNT64 llValue)
{
//TICKCOUNT64 lOldTick = UserSetTick;
UserSetTick = llValue;
return UserSetTick;
}
TICKCOUNT32 wylib::time::tick64::GetTickCount32()
{
return timeGetTime();
}
TICKCOUNT32 wylib::time::tick64::SetTickCount32(TICKCOUNT32 dwTick)
{
return (TICKCOUNT32)SetTickCount64(dwTick);
}