📄 timer.cpp
字号:
////////////////////////////////////////////////////////////////////////////////
// 定时器
////////////////////////////////////////////////////////////////////////////////
// Author : 黎达文
// Description :
//
// Version : 2.0
//
// Standard include files :
//
// Start Date : 2003年12月4日
//
// Change Log : 2003年12月4日 by 黎达文 -- Created
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "timer.h"
namespace kernel
{
TimerLogic::TimerLogic()
{
memset(&tv1, 0, sizeof(tv1));
memset(&tv2, 0, sizeof(tv2));
memset(&tv3, 0, sizeof(tv3));
memset(&tv4, 0, sizeof(tv4));
memset(&tv5, 0, sizeof(tv5));
tvecs[0] = (TimerVec *)&tv1;
tvecs[1] = &tv2;
tvecs[2] = &tv3;
tvecs[3] = &tv4;
tvecs[4] = &tv5;
tickCount = 0;
}
// 将一个定时器插入到合适的盘子合适的刻度
bool TimerLogic::insert (TimerList *timer)
{
unsigned int expires = timer->expires;
unsigned int idx = expires - tickCount;
TimerList **vec;
if(idx < TVR_SIZE)
{
int i = expires & TVR_MASK;
vec = tv1.vec + i;
}
else if (idx < 1 << (TVR_BITS + TVN_BITS))
{
int i = (expires >> TVR_BITS) & TVN_MASK;
vec = tv2.vec + i;
}
else if (idx < 1 << (TVR_BITS + 2 * TVN_BITS))
{
int i = (expires >> (TVR_BITS + TVN_BITS)) & TVN_MASK;
vec = tv3.vec + i;
}
else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS))
{
int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
vec = tv4.vec + i;
}
else if ((signed long) idx < 0)
{
// can happen if you add a timer with expires == jiffies,
// or you set a timer to go off in the past
vec = tv1.vec + tv1.index;
}
else if (idx <= 0xffffffffUL)
{
int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
vec = tv5.vec + i;
}
else
{
return false;
}
if ((timer->next = *vec)) // 赋值next指针
(*vec)->prev = timer;
*vec = timer;
timer->prev = (TimerList *)vec;
return true;
}
void TimerLogic::erase (TimerList *curr)
{
TimerList *prev = curr->prev;
if (prev)
{
TimerList *next = curr->next;
prev->next = next;
if (next)
next->prev = prev;
curr->next = curr->prev = 0;
}
}
void TimerLogic::cascade(TimerVec *tv)
{
// cascade all the timers from tv up one level
TimerList *timer;
timer = tv->vec[tv->index];
TimerList *tmp = NULL;
while (timer)
{
tmp = timer;
timer = timer->next;
insert(tmp);
}
tv->vec[tv->index] = NULL;
tv->index = (tv->index + 1) & TVN_MASK;
}
GeneralTimer::GeneralTimer(unsigned int timeslice)
: m_exit_signaled(false)
{
if(timeslice < MIN_TIMESLICE)
m_timeslice = MIN_TIMESLICE;
else
m_timeslice = timeslice;
startThread();
}
GeneralTimer::~GeneralTimer()
{
m_exit_signaled = true;
waitFinish(5000);
}
TimerID GeneralTimer::set(TimerTask *owner, unsigned int expires, unsigned int userdata)
{
TimerList *timer = new TimerList;
timer->expires = expires/m_timeslice; // 计算tick数目
timer->owner_type = OT_TASK;
timer->task = owner;
timer->userdata = userdata;
if(!insert(timer))
{
delete timer;
return 0;
}
return timer;
}
TimerID GeneralTimer::set(TimerProc function, unsigned int expires, unsigned int userdata)
{
TimerList *timer = new TimerList;
timer->expires = expires/m_timeslice;
timer->owner_type = OT_FUNCTION;
timer->function = function;
timer->userdata = userdata;
if(!insert(timer))
{
delete timer;
return 0;
}
return timer;
}
void GeneralTimer::unset(TimerID timerid)
{
if(timerid)
erase(timerid);
delete timerid;
}
void GeneralTimer::threadProcess()
{
TimerList *curr = NULL;
TimerList *timer = NULL;
while(!m_exit_signaled)
{
::Sleep(m_timeslice);
// 大盘已经转一周了,将下面的定时器往上移动
if (tv1.index == 0)
{
int n = 1;
do{
cascade(tvecs[n]);
} while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
}
// 检查当前时刻的定时器列表,一一触发他们
while ((curr = tv1.vec[tv1.index]))
{
if(curr->owner_type == OT_TASK)
curr->task->onTimer(curr->userdata);
else if(curr->owner_type == OT_FUNCTION)
curr->function(curr->userdata);
// 移走已经触发的定时器
unset(curr);
curr = NULL;
}
// 时钟计数
tickCount++;
// 时钟刻度走一格
tv1.index = (tv1.index + 1) & TVR_MASK;
}
}
unsigned int HashTimer::set(TimerTask *owner, unsigned int expires, unsigned int userdata)
{
CTScopeCS scopeLock(m_cs);
TimerID timerid = GeneralTimer::set(owner, expires, userdata);
unsigned int id = INVALID_ID;
if(timerid)
{
id = nextid();
m_idmap.insert(std::make_pair(id, timerid));
}
return id;
}
unsigned int HashTimer::set(TimerProc function, unsigned int expires, unsigned int userdata)
{
CTScopeCS scopeLock(m_cs);
TimerID timerid = GeneralTimer::set(function, expires, userdata);
unsigned int id = INVALID_ID;
if(timerid)
{
id = nextid();
m_idmap.insert(std::make_pair(id, timerid));
}
return id;
}
void HashTimer::unset(unsigned int id)
{
CTScopeCS scopeLock(m_cs);
IDTYPE::iterator it = m_idmap.find(id);
if(it != m_idmap.end())
GeneralTimer::unset(it->second);
}
unsigned int HashTimer::nextid()
{
if(m_id++ > MAX_ID)
m_id = MIN_ID;
return m_id;
}
//not implement yet!
unsigned int SetTimer(TimerTask *owner, unsigned int expires, unsigned int userdata)
{
return 0;
}
unsigned int SetTimer(TimerProc function, unsigned int expires, unsigned int userdata)
{
return 0;
}
void KillTimer(unsigned int id)
{
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -