Linux系统进程间隔定时器Itimer(下)(1)
文章作者 100test 发表时间 2007:03:14 16:45:15
来源 100Test.Com百考试题网
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中,作为查询结果返回。