📄 timer.c
字号:
//#include "Timer.h"
#include "Include.h "
//extern WriteMessageToReceiveBuffer(int n, char *message,int Modle);
//---------------------------------------------------------
// 对定时器初始化
// 返回 0 成功
// -1 失败
int Init_TimerQueue()
{
int i;
LONG period=TIMER_MIN_PERIOD,u_range=TIMER_MIN_PERIOD*TIMER_GROUP_STEPS;
// 把定时器控制区清零
memset(&timer_control,0,sizeof(struct timer_control_t));
//读取系统计时频率
if (!QueryPerformanceFrequency(&timer_control.frequency))
return -1;
//置每个定时器链为空
for ( i = 0 ; i < TIMER_GROUPS*TIMER_GROUP_STEPS; i ++)
timer_control.head[i] = -1; //-1是空标识
//空闲定时器数
timer_control.total_count = timer_control.free_count = TIMERS;
//为每个定时器组设定创建时间
for ( i = 0; i < TIMER_GROUPS; i ++)
{
QueryPerformanceCounter(&timer_control.last_time[i]);
timer_control.cur_pos[i] = -1;
}
for ( i = 0 ; i < TIMER_GROUPS; i ++)
{
timer_control.period[i].QuadPart = period ;
timer_control.upper_range[i].QuadPart = u_range;
period = period * 10;
u_range = u_range * 10;
}
// 生成空闲定时器链
for (i=0;i<TIMERS;i++)
timer_node[i].next = i+1;
// 末结点没有后继结点
timer_node[TIMERS -1 ].next = -1;
timer_mutex = CreateMutex(NULL,FALSE,NULL);
//启动定时器扫描例程(线程),
set_timer();
return 0;
}
//启动定时器工作
void set_timer()
{
HANDLE hThread;
DWORD thread_id;
//创建定时器扫描线程,定期唤醒,扫描定时器队列,查找到期的定时器
hThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,0,(LPTHREAD_START_ROUTINE)scan_timer,NULL,0,&thread_id);
}
//----------------------------------------------------------
// 创建一个定时器
// 入口:count: 时长,单位: ms
// 返回值:定时器的句柄
//----------------------------------------------------------
int create_a_timer(ULONG count,int timer_type,char * owner,void * para)
{
int timer_id, i,timer_step,timer_head, first;
ULONG upper,period;
struct timer_node_t *new_timer;
#ifdef OPEN_WARNING
unsigned char cWarningDescription[WARNING_DESC_LEN];
#endif
if (timer_control.free_count <= 0)
{
#ifdef OPEN_WARNING
/* 发送告警给OMP */
memset(cWarningDescription,0,WARNING_DESC_LEN);
sprintf(cWarningDescription,"定时器不能分配");
SendWarningToOmp(SOURCE_SHORTAGE,TIMER_USEUP,cWarningDescription);
#endif
return -1;
}
timer_control.free_count--;
new_timer = &timer_node[timer_control.free_head];
timer_id = timer_control.free_head;
new_timer->owner = *(int *)owner;
new_timer->timer_type = timer_type;
new_timer->flag = TIMER_BUSY;
if (para!=NULL)
{
memcpy(new_timer->para,para,PARA_LEN);
}
if (count <=0)
{
#ifdef OPEN_WARNING
/* 发送告警给OMP */
memset(cWarningDescription,0,WARNING_DESC_LEN);
sprintf(cWarningDescription,"定时器不能分配");
SendWarningToOmp(SOURCE_SHORTAGE,TIMER_USEUP,cWarningDescription);
#endif
return -1;
}
for (i = 0; i < TIMER_GROUPS; i ++) // 寻找合适的组
{
upper =(ULONG) timer_control.upper_range[i].QuadPart;
period =(ULONG) timer_control.period[i].QuadPart;
if (count <= upper)
{
timer_step = count / period + (((count % period)>0 )? 0:-1);
timer_step = (timer_step + timer_control.cur_pos[i]) % TIMER_GROUP_STEPS;
timer_head = i*TIMER_GROUP_STEPS+timer_step;
new_timer->head_ptr = timer_head;
first = timer_control.head[timer_head];
timer_control.head[timer_head] = timer_id;
timer_control.free_head = new_timer->next;
new_timer->next = first;
return timer_id;
}
}
#ifdef OPEN_WARNING
/* 发送告警给OMP */
memset(cWarningDescription,0,WARNING_DESC_LEN);
sprintf(cWarningDescription,"定时器不能分配");
SendWarningToOmp(SOURCE_SHORTAGE,TIMER_USEUP,cWarningDescription);
#endif
return -1;
}
//----------------------------------------------------------
// 释放一个定时器
// id 定时器内部编号 owner 定时器创建者标识
// 返回 >=0 表示成功,即返回实际释放的定时器句柄
// 返回 -1 表示失败
//----------------------------------------------------------
int kill_a_timer(int id,char *owner)
{
int timer_head,head_first,prev,next;
if (id < 0 || id >= TIMERS)
return -1; // 若 ID 非法就返回 -1
// 若它已释放,也返回-1
if (timer_node[id].flag == TIMER_FREE)
return -1;
if (memcmp(owner, &timer_node[id].owner,4)!= 0 )
return -1;
timer_head = timer_node[id].head_ptr; // 链号
head_first = timer_control.head[timer_head]; // 该链首定时器号
if (head_first == -1) return -1; // 如果该链是空的,返回失败
if (head_first == id) // 如果 ID 恰好是首结点就直接取下
timer_control.head[timer_head]=timer_node[id].next;
else
{
// 寻找 ID 的父结点
prev = head_first;
while ((next = timer_node[prev].next)!=-1 && next != id)
prev = next;
if (next == -1) return -1; // 若没有找到返回-1,失败
// 若找到, prev 是父结点,将父结点链至释放节点的下一节点
timer_node[prev].next = timer_node[next].next;
}
//释放节点
timer_node[id].flag = TIMER_FREE;
timer_node[id].next = timer_control.free_head;
timer_control.free_head = id ; //释放节点插入空闲链的头部
timer_control.free_count++; //可用节点数增1
return id;
}
//-----------------------------------------------------------------
// 定时器扫描程序
//-----------------------------------------------------------------
void scan_timer(void *dummy)
{
int i,send_node;
struct timer_expire_message_t send_message;
LARGE_INTEGER cur_count;
//Add for cbc
CBEMESSAGE_t s_CBEMessage;
memset(&send_message,0,sizeof(struct timer_expire_message_t));
send_message.len=sizeof(struct timer_expire_message_t)-2;
send_message.message_area = B; //B区消息
// send_message.message_length = PARA_LEN+sizeof(send_message.flag)
// +sizeof(send_message.timer_id);
send_message.message_length = PARA_LEN+sizeof(send_message.flag)+sizeof(send_message.timer_id);
while(1)
{
WaitForSingleObject(timer_mutex,INFINITE); // 无条件互斥
QueryPerformanceCounter(&cur_count); // 取当前时刻
for (i = 0; i < TIMER_GROUPS; i ++) // 每组都检查一下
if ((cur_count.QuadPart - timer_control.last_time[i].QuadPart) >= timer_control.period[i].QuadPart*FREQUENCY)
{
// 到了一个周期
timer_control.last_time[i] = cur_count;
// 时钟向下走一格
timer_control.cur_pos[i] = (timer_control.cur_pos[i] +1) % TIMER_GROUP_STEPS;
send_node = timer_control.head[i * TIMER_GROUP_STEPS + timer_control.cur_pos[i]];
while(send_node != -1)
{
send_message.timer_id = send_node;
send_message.flag = timer_node[send_node].flag;
send_message.owner= timer_node[send_node].owner;
send_message.message_type = timer_node[send_node].timer_type;
memcpy(send_message.para,timer_node[send_node].para,PARA_LEN);
//发送定时器倒时消息
memcpy(&s_CBEMessage,&send_message,sizeof(struct timer_expire_message_t));
AppendCBERecvMsg(&s_CBEMessage);
// 回发消息, 参数为:消息长度和消息体
// WriteMessageToReceiveBuffer(sizeof(struct timer_expire_message_t),(char*)&send_message,0);
timer_node[send_node].flag = TIMER_OLD;
send_node = timer_node[send_node].next ;
}
}
ReleaseMutex(timer_mutex); //释放临界资源
Sleep(TIMER_MIN_PERIOD); //唤醒周期
}
}
int create_timer(ULONG count,int timer_type,char *owner,void * para)
{
int timer_id;
WaitForSingleObject(timer_mutex,INFINITE); //申请临界资源
timer_id = create_a_timer(count,timer_type,owner,para);
/*Add for statistic--------*/
if (timer_id>=0)
{
s_RuntimeInfo.iTimerCount++;
}
/*-------------------------*/
ReleaseMutex(timer_mutex); //释放临界资源
#ifdef DEBUG_PRINT_PID
printf("Create a Timer,timer_id=%d\n\n",timer_id);
#endif
return timer_id;
}
int kill_timer(int timer_id, char *owner)
{
int killed_timer_id;
WaitForSingleObject(timer_mutex,INFINITE); //申请临界资源
killed_timer_id = kill_a_timer(timer_id, owner);
/*Add for statistic--------*/
if (killed_timer_id>=0)
{
s_RuntimeInfo.iTimerCount--;
}
/*-------------------------*/
ReleaseMutex(timer_mutex); //释放临界资源
#ifdef DEBUG_PRINT_PID
printf("Kill a Timer,timer_id=%d\n\n",timer_id);
#endif
return killed_timer_id;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -