📄 timer.h
字号:
////////////////////////////////////////////////////////////////////////////////
// 定时器
////////////////////////////////////////////////////////////////////////////////
// Author : 黎达文
// Description :
//
// Version : 2.0
//
// Standard include files :
//
// Start Date : 2003年12月4日
//
// Change Log : 2003年12月4日 by 黎达文 -- Created
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_TIMER_H
#define INCLUDED_TIMER_H
#if defined(HAS_PRAGMA_ONCE)
#pragma PRAGMA_ONCE_DECLARE
#endif
namespace kernel
{
//the task base class
class TimerTask
{
public:
virtual void onTimer(unsigned int userdata) = 0;
};
//timer function type
typedef void (*TimerProc)(unsigned int userdata);
enum OwnerType{ OT_TASK, OT_FUNCTION } ;
// 实现定时器算法逻辑,本身不带定时驱动器
// ************************************************************************
// 算法描述:
// TimerLogic实现了一个模拟的时钟,这个时钟的最上一层(类似秒针)是一个256个刻度的盘子,
// 下面四层(类似分钟,时针)有刻度是64的小盘子,上层转一圈之后下一层的刻度就走一个刻度。
// 指示当前盘子走到那个刻度是TimerVec(或TimerVecRoot)的index。
// 添加定时器的时候根据定时的时间将定时器数据(TimerList)放在恰当的盘子的恰当刻度中。
// 时钟开始运转之后每一个滴答就检查第一个盘子的当前刻度是否有数据,如果有则触发该定时器
// 当第一个盘子走完一圈之后就意味着下一个盘子的当前刻度的定时器(如果有)
// 应该转移到第一个盘子上面来了,这时候将下一个盘子的当前刻度定时器全部重新插入第一个盘子
// 然后依次检查第三、第四、第五个盘子是否也要将当前刻度的定时器重新插入上层。
// 检查的依据就是上一层是否已经运转一圈了。
//************************************************************************
struct TimerList
{
TimerList *next; //the next must at first
TimerList *prev;
unsigned int expires; //expire time
OwnerType owner_type; //
TimerTask *task; //the owner is base on TimerTask
TimerProc function; //the owner is a function
unsigned int userdata; //user private data
TimerList()
: next(NULL)
, prev(NULL)
{}
};
// the timer list
typedef TimerList *TimerID;
class TimerLogic
{
public:
enum { NOOF_TVECS = 5 };
enum { TVN_BITS = 6 };
enum { TVR_BITS = 8 };
enum { TVN_SIZE = (1 << TVN_BITS) };
enum { TVR_SIZE = (1 << TVR_BITS) };
enum { TVN_MASK = (TVN_SIZE - 1) };
enum { TVR_MASK = (TVR_SIZE - 1) };
struct TimerVec //small circle
{
int index;
TimerList *vec[TVN_SIZE];
};
struct TimerVecRoot //big circle
{
int index;
TimerList *vec[TVR_SIZE];
};
/////////////////////////////////////////////////////////////////////////////////
TimerLogic();
bool insert (TimerList *timer);
void erase (TimerList *curr);
void cascade(TimerVec *tv);
protected:
unsigned int tickCount;
// 定时器有一个大盘和四个小盘
TimerVec *tvecs[NOOF_TVECS];
TimerVecRoot tv1;
TimerVec tv2, tv3, tv4, tv5;
};
// 定时驱动器,驱动tickCount往前进行。
// 并负责派送消息到TimerTask
// 使用TimerList对象的地址作为定时器的ID
class GeneralTimer : public TimerLogic, public CTThreadExtend
{
public:
enum { MIN_TIMESLICE = 10 }; // ms
enum { DEFAULT_TIMESLICE = 50 }; // ms
GeneralTimer(unsigned int timerslice = DEFAULT_TIMESLICE);
~GeneralTimer();
// 设置一个定时器,定时长度为expires,定时器到达通知owner,通知的时候带回userdata
TimerID set(TimerTask *owner, unsigned int expires, unsigned int userdata);
// 设置一个定时器,定时长度为expires,定时器到达调用function,参数传递userdata
TimerID set(TimerProc function, unsigned int expires, unsigned int userdata);
// 删除一个定时器
void unset(TimerID timerid);
private:
void threadProcess();
private:
volatile bool m_exit_signaled;
unsigned int m_timeslice; //precision of tick
};
// set method will remember the timerid
// and unset method will check the timerid at first
class HashTimer : public GeneralTimer
{
public:
unsigned int set(TimerTask *owner, unsigned int expires, unsigned int userdata);
unsigned int set(TimerProc function, unsigned int expires, unsigned int userdata);
void unset(unsigned int id);
protected:
unsigned int nextid();
private:
typedef std::map<unsigned int, TimerID> IDTYPE;
IDTYPE m_idmap;
CTCriticalSection m_cs;
unsigned int m_id;
enum { MIN_ID = 0 };
enum { MAX_ID = 0xFFFF };
enum { INVALID_ID = ~0 };
};
// 全局方法
unsigned int SetTimer(TimerTask *owner, unsigned int expires, unsigned int userdata);
unsigned int SetTimer(TimerProc function, unsigned int expires, unsigned int userdata);
void KillTimer(unsigned int id);
};
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -