AIX中的几个timer相关的kernel servers:
1.time-of-day: 主要是获取当前时间,当前时间的一些设置。
2.Fine granularity高
精度的timer:主要是提供了nanoseconds级的精度,后面会详细介绍
3.Low accuracy低精度的timer:主要由timeout函数和Watchdog的功能
高精度的timer提供了一个结构:struct trb
-
struct trb {
-
struct trb *to_next; /* for the timeout() routines */
-
struct trb *knext; /* next timer in kernel chain */
-
struct trb *kprev; /* previous timer in kern. chain*/
-
ulong id; /* owner process, dev drvrs = -1*/
-
volatile cpu_t cpunum; /* owning processor */
-
unsigned short flags; /* operation flags */
-
ulong timerid; /* timer identifier */
-
tid_t eventlist; /* anchor for awaited event */
-
struct itimerstruc_t timeout; /* timer request */
-
void (*func)(); /* completion handler */
-
union parmunion { /* data for completion handler */
-
ulong data; /* handler unsigned data */
-
int sdata; /* handler signed data */
-
caddr_t addr; /* handler address */
-
} t_union;
-
int ipri; /* int. priority for func() */
-
void (*tof)(); /* timeout function */
-
};
timerid的值可以取下面几个:
#define ITIMER_REAL 0 /* Per-process real time 实时定时器,不管进程在何种模式下或者休眠状态都计数并到期发送信号ALRM */
#define ITIMER_VIRTUAL 1 /* Per-process time 只计算在用户模式下的时间 */
#define ITIMER_PROF 2 /* Per-process user time 同时对用户模式和内核模式都计数,并计算调度消耗的时间到期发送PROF信号*/
flags主要的两个值(其他的可以不用关心,如碰到多核的特定需求会需要):
#define T_ABSOLUTE 0x004 /* timeout is an absolute value 这里是指在指定的时间开始计时,可以通过获取当前时间然后加上一些数值进行操作,如果直接设置成当前时间会有问题,因为在tstart的时候是会判断这个绝对时间和当前时间的值,且不能小于当前时间(在tstart时获得的当前时间当然要大于在设置timeout成员变量时的当前时间)*/
#define T_INCINTERVAL 0x010 /* timer is an incinterval one 一般使用的是这个,表示从当前时间开始,每隔多少时间计一次*/
这里的func原型是 void (*func)(struct trb *)
由于该处理函数是在interrupt环境中的,所以需要pincode起来,并且该处理函数中不能够出现有关打印的信息,例如syslog这种,因为这种会进行文件的读写,违背了中断环境的约定。在写相关实例的时候就是因为添加了log导致整个timer不稳定,会出现coredump的情况。
其他的成员设置大多的资料上都有,这里只是讲解几个需要注意的
一般的AIX kernel timer实例会如下:
talloc
init trb
tstart
处理func -> init trb-> tstart
tstop
tfree
Watchdog 其实和上述高精度的timer是相似的机制,在前期编写实例的时候还是因为在func中使用了syslog导致的,所以这里在强调一下。
最近写了很多AIX kernel extension的实例,后续可以贴上来看看,毕竟这方面code的资料太少了。
阅读(1896) | 评论(0) | 转发(0) |