/***********************************************
Author:Charles Stone
Email:sc8312@qq.com;sc8312@sohu.com
QQ:13148567
Corporation:Pulante Dirigible
Function:Linux下实现毫秒级的软件定时
Notice:该定时器最小延迟依赖于系统HZ,故不一定能满足毫秒级定时
***********************************************/
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<termios.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<sys/time.h>
#include<sys/times.h>
#include<sys/ioctl.h>
#include<signal.h>
#include<string.h>
#include"stimer.h"
static pstimer stimer_head=NULL,stimer_tail=NULL;
static int stimer_mex=0;
static unsigned long stimer_const=1;
void timer_handle(int signo)
{
pstimer tmp;
while(stimer_mex);
stimer_mex=1;
for(tmp=stimer_head;tmp;tmp=tmp->next)
{
if (tmp->enable)
{
if(tmp->msec)tmp->msec--;
if(!tmp->msec)
{
if(tmp->handle)tmp->handle(tmp->timer_id);
if(!tmp->intermsec)tmp->enable=0;
else tmp->msec=tmp->intermsec;
}
}
}
stimer_mex=0;
}
pstimer stimer_create(int stimer_id)
{
pstimer tmp;
for(tmp=stimer_head;tmp;tmp=tmp->next)
{
if(tmp->timer_id==stimer_id)return NULL; /* 定时器 stimer_id 存在返回NULL*/
}
if((tmp=(pstimer)malloc(sizeof(stimer)))==NULL)return NULL; /* 创建定时器结构体,在下面初始化并安装 */
tmp->timer_id=stimer_id;
tmp->next=NULL;
tmp->enable=0;
if(stimer_tail==NULL)
{
tmp->pre=NULL;
stimer_head=stimer_tail=tmp;
}
else
{
tmp->pre=stimer_tail;
stimer_tail->next=tmp;
stimer_tail=tmp;
}
return tmp; /* 创建成功返回pstimer类型指针 */
}
int stimer_set(pstimer pst,unsigned long msec,void (*handle)(int),int mode)
{
if (pst==NULL)return -1;
pst->msec=msec/stimer_const;
if(msec%stimer_const)pst->msec++;
pst->handle=handle;
switch(mode)
{
case STIMER_CYCLE:
pst->intermsec=pst->msec;
break;
case STIMER_ONCE:
pst->intermsec=0;
break;
default:
return -1;
}
pst->enable=1;
return 0;
}
int stimer_reset(pstimer pst)
{
if(pst==NULL)return -1;
pst->msec=pst->intermsec;
return 0;
}
int stimer_pause(pstimer pst)
{
if(pst==NULL)return -1;
pst->enable=0;
return 0;
}
int stimer_continue(pstimer pst)
{
if(pst==NULL)return -1;
pst->enable=1;
return 0;
}
int stimer_del(pstimer pst)
{
if(stimer_mex)return 1;
stimer_mex^=1;
if(stimer_mex==0)return 1;
if(stimer_tail==NULL)return -1;
if(pst->pre==NULL)
{
if((stimer_head=pst->next))
stimer_head->pre=NULL;
}
else
{
pst->pre->next=pst->next;
pst->next->pre=pst->pre;
}
if(pst->next==NULL)stimer_tail=pst->pre;
free(pst);
stimer_mex=0;
return 0;
}
int stimer_init()
{
//unsigned long SYS_HZ;
struct sigaction tact;
struct itimerval value;
//SYS_HZ=sysconf(_SC_CLK_TCK);
//stimer_const=1000/SYS_HZ;
stimer_const=1000ul/sysconf(_SC_CLK_TCK);
//printf("System's HZ=%lu\nstimer_const=%lu\n",SYS_HZ,stimer_const);
tact.sa_handler = timer_handle;
tact.sa_flags = 0;
sigaction(SIGALRM,&tact,NULL);
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 1000;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = 1000;
return setitimer(ITIMER_REAL,&value,NULL);
}
int stimer_release()
{
struct itimerval value;
value.it_value.tv_sec = 0;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = 0;
return setitimer(ITIMER_REAL,&value,NULL);
}
- 1
- 2
- 3
前往页