isearch/comm/timerlist.cc

191 lines
3.7 KiB
C++
Raw Normal View History

2021-03-19 18:38:34 +08:00
#include <stdint.h>
#include "timerlist.h"
#include "log.h"
#if TIMESTAMP_PRECISION < 1000
#error TIMESTAMP_PRECISION must >= 1000
#endif
#ifndef likely
#if __GCC_MAJOR >= 3
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#endif
CTimerObject::~CTimerObject(void) {
}
void CTimerObject::TimerNotify(void) {
log_debug("CTimerObject::TimerNotify start");
delete this;
}
void CTimerObject::AttachTimer(class CTimerList *lst) {
if(lst->timeout > 0)
objexp = lst->GetTimeUnitNowTime() + lst->timeout * (TIMESTAMP_PRECISION/1000);
ListMoveTail(lst->tlist);
}
int CTimerList::CheckExpired(int64_t now) {
int n = 0;
if(now==0) {
now = GetTimeUnitNowTime();
}
while(!tlist.ListEmpty()) {
CTimerObject *tobj = tlist.NextOwner();
if(tobj->objexp > now) break;
tobj->ListDel();
tobj->TimerNotify();
n++;
}
return n;
}
int64_t CTimerList::GetTimeUnitNowTime()
{
if (NULL == timerUnitOwner)
{
return GET_TIMESTAMP();
}
return timerUnitOwner->GetNowTime();
}
void CTimerUnit::UpdateNowTime(int max_wait, int interrupted)
{
int64_t adjustTime = 0;
int64_t deadLineTime = 0;
const int MAX_DELAY_MS = 1000000;/*ǰ<>򲦶<EFBFBD><F2B2A6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
m_SystemTime = GET_TIMESTAMP();
if ( unlikely(max_wait < 0) )
{
m_TimeOffSet = 0;
m_NowTime = m_SystemTime;
return;
}
adjustTime = m_SystemTime + m_TimeOffSet;
/*ʱ<><EFBFBD><E4B1BB><EFBFBD>󲦶<EFBFBD><F3B2A6B6><EFBFBD>*/
if (adjustTime < m_NowTime)
{
adjustTime = interrupted ? (m_NowTime) : (m_NowTime + max_wait * (TIMESTAMP_PRECISION/1000));
m_TimeOffSet = adjustTime - m_SystemTime;
m_NowTime = adjustTime;
return;
}
deadLineTime = m_NowTime + max_wait * (TIMESTAMP_PRECISION/1000) + MAX_DELAY_MS;
if (likely(adjustTime < deadLineTime) )
{
m_NowTime = adjustTime;
return;
}
/*ʱ<><EFBFBD><E4B1BB>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
else
{
adjustTime = interrupted ? (m_NowTime) : (m_NowTime + max_wait * (TIMESTAMP_PRECISION/1000));
m_TimeOffSet = adjustTime - m_SystemTime;
m_NowTime = adjustTime;
return;
}
}
CTimerList *CTimerUnit::GetTimerListByMSeconds(int to) {
CTimerList *tl;
for(tl = next; tl; tl=tl->next) {
if(tl->timeout == to)
return tl;
}
tl = new CTimerList(to, this);
tl->next = next;
next = tl;
return tl;
}
CTimerUnit::CTimerUnit(void) : pending(0), next(NULL),m_TimeOffSet(0)
{
m_SystemTime = GET_TIMESTAMP();
m_NowTime = m_SystemTime;
};
CTimerUnit::~CTimerUnit(void) {
while(next) {
CTimerList *tl = next;
next = tl->next;
delete tl;
}
};
int CTimerUnit::ExpireMicroSeconds(int msec, int msec0) {
int64_t exp;
CTimerList *tl;
int64_t timestamp = GetNowTime() ;
exp = timestamp + msec*(TIMESTAMP_PRECISION/1000);
for(tl = next; tl; tl=tl->next) {
if(tl->tlist.ListEmpty())
continue;
CTimerObject *o = tl->tlist.NextOwner();
if(o->objexp < exp)
exp = o->objexp;
}
exp -= timestamp;
if(exp <= 0)
return 0;
msec = exp / (TIMESTAMP_PRECISION/1000);
return msec >= msec0 ? msec : msec0;
}
int CTimerUnit::CheckReady(void) {
int n = 0;
while(!pending.tlist.ListEmpty()) {
CTimerObject *tobj = pending.tlist.NextOwner();
tobj->ListDel();
tobj->TimerNotify();
n++;
}
return n;
}
int CTimerUnit::CheckExpired(int64_t now) {
if(now==0)
now = GetNowTime();
int n = CheckReady();;
CTimerList *tl;
for(tl = next; tl; tl=tl->next) {
n += tl->CheckExpired(now);
}
return n;
}
void CReadyObject::ReadyNotify(uint64_t now)
{
delete this;
}
int CReadyUnit::CheckReady(uint64_t now)
{
int n = 0;
CListObject<CReadyObject> * tmp;
tmp = pending;
pending = processing;
processing = tmp;
while(!processing->ListEmpty())
{
CReadyObject * robj = processing->NextOwner();
robj->ListDel();
robj->ReadyNotify(now);
n++;
}
return n;
}