⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 CBS(小区广播)程序实现手稿
💻 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 + -