当前位置: 首页 > 工具软件 > itimer > 使用案例 >

linux进程多定时器,Linux系统进程间隔定时器Itimer(下)

徐帅
2023-12-01

7.7.3.1 getitimer()系统调用的实现

函数sys_getitimer()有两个参数:(1)which,指定查询调用进程的哪一个间隔定时器,其取值可以是ITIMER_REAL、ITIMER_VIRT和ITIMER_PROF三者之一。(2)value指针,指向用户空间中的一个itimerval结构,用于接收查询结果。该函数的源码如下:

/* SMP: Only we modify our itimer values. */ asmlinkage long sys_getitimer(int which, struct itimerval *value) { int error = -EFAULT; struct itimerval get_buffer; if (value) { error = do_getitimer(which, &get_buffer); if (!error && copy_to_user(value, &get_buffer, sizeof(get_buffer))) error = -EFAULT; } return error; }

显然,sys_getitimer()函数主要通过do_getitimer()函数来查询当前进程的间隔定时器信息,并将查询结果保存在内核空间的结构变量get_buffer中。然后,调用copy_to_usr()宏将get_buffer中结果拷贝到用户空间缓冲区中。

函数do_getitimer()的源码如下(kernel/itimer.c):

int do_getitimer(int which, struct itimerval *value) { register unsigned long val, interval; switch (which) { case ITIMER_REAL: interval = current->it_real_incr; val = 0; /* * FIXME! This needs to be atomic, in case the kernel timer happens! */ if (timer_pending(¤t->real_timer)) { val = current->real_timer.expires - jiffIEs; /* look out for negative/zero itimer.. */ if ((long) val <= 0) val = 1; } break; case ITIMER_VIRTUAL: val = current->it_virt_value; interval = current->it_virt_incr; break; case ITIMER_PROF: val = current->it_prof_value; interval = current->it_prof_incr; break; default: return(-EINVAL); } jiffiestotv(val, &value->it_value); jiffiestotv(interval, &value->it_interval); return 0; }

查询的过程如下:

(1)首先,用局部变量val和interval分别表示待查询间隔定时器的间隔计数器的当前值和初始值。

(2)如果which=ITIMER_REAL,则查询当前进程的ITIMER_REAL间隔定时器。于是从current->it_real_incr中得到ITIMER_REAL间隔定时器的间隔计数器的初始值,并将其保存到interval局部变量中。而对于间隔计数器的当前值,由于ITITMER_REAL间隔定时器是通过real_timer这个内核动态定时器来实现的,因此不能通过current->it_real_value来获得ITIMER_REAL间隔定时器的间隔计数器的当前值,而必须通过real_timer来得到这个值。为此先用timer_pending()函数来判断current->real_timer是否已被起动。如果未启动,则说明ITIMER_REAL间隔定时器也未启动,因此其间隔计数器的当前值肯定是0。因此将val变量简单地置0就可以了。如果已经启动,则间隔计数器的当前值应该等于(timer_real.expires-jiffies)。

(3)如果which=ITIMER_VIRT,则查询当前进程的ITIMER_VIRT间隔定时器。于是简单地将计数器初值it_virt_incr和当前值it_virt_value分别保存到局部变量interval和val中。

(4)如果which=ITIMER_PROF,则查询当前进程的ITIMER_PROF间隔定时器。于是简单地将计数器初值it_prof_incr和当前值it_prof_value分别保存到局部变量interval和val中。

(5)最后,通过转换函数jiffiestotv()将val和interval转换成timeval格式的时间值,并保存到value->it_value和value->it_interval中,作为查询结果返回。

 类似资料: