linux 1.0 内核注解 linux/kernel/itimer.c
时间:2009-03-06 来源:taozhijiangscu
/********************************************
*Created By: 陶治江
*Date: 2009-3-3
********************************************/
///////////////////////
//定时器介绍
/////////////////////// //真实间隔定时器ITIMER_REAL:这种间隔定时器在启动后不管进程是否运行,每个时钟滴答都将其间隔计数器减1
//当减到0值时,内核向进程发送SIGALRM信号。it_real_incr则表示间隔定时器的间隔计数器的初始值,
//而it_real_value则表示真实间隔定时器的间隔计数器的当前值 //虚拟间隔定时器ITIMER_VIRT:也称为进程的用户态间隔定时器。it_virt_incr 和it_virt_value分别表示虚拟间隔
//定时器的间隔计数器的初始值和当前值,二者均以时钟滴答次数位计数单位。当虚拟间隔定时器启动
//后,只有当进程在用户态下运行时,一次时钟滴答才能使间隔计数器当前值it_virt_value减1。
//当减到0值时,内核向进程发送SIGVTALRM信号(虚拟闹钟信号),并将it_virt_value重置为
//初值it_virt_incr //间隔定时器ITIMER_PROF:it_prof_value和 it_prof_incr成员分别表示PROF间隔定时器的间隔计数器的
//当前值和初始值。当一个进程的PROF间隔定时器启动后,则只要该进程处于运行中,而不管是在用户态或
//核心态下执行,每个时钟滴答都使间隔计数器it_prof_value值减1。当减到0值时,内核向进程
//发送 SIGPROF信号,并将it_prof_value重置为初值it_prof_incr #include <linux/signal.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/time.h> #include <asm/segment.h> //timevalue to jiffies,将时间值转换为滴答数
static unsigned long tvtojiffies(struct timeval *value)
{
return((unsigned long )value->tv_sec * HZ +
(unsigned long )(value->tv_usec + (1000000 / HZ - 1)) /
(1000000 / HZ));
} static void jiffiestotv(unsigned long jiffies, struct timeval *value)
{
value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
value->tv_sec = jiffies / HZ;
return;
} //struct itimerval {
// struct timeval it_interval; /* timer interval */
// struct timeval it_value; /* current value */
//}; int _getitimer(int which, struct itimerval *value)
{
register unsigned long val, interval; switch (which) {
case ITIMER_REAL:
val = current->it_real_value;
interval = current->it_real_incr;
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);
} asmlinkage int sys_getitimer(int which, struct itimerval *value)
{
int error;
struct itimerval get_buffer; if (!value)
return -EFAULT;
error = _getitimer(which, &get_buffer);
if (error)
return error;
error = verify_area(VERIFY_WRITE, value, sizeof(struct itimerval));
if (error)
return error;
//拷贝到用户空间中
memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
return 0;
} int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
register unsigned long i, j;
int k; //转换为滴答数
i = tvtojiffies(&value->it_interval);
j = tvtojiffies(&value->it_value);
if (ovalue && (k = _getitimer(which, ovalue)) < 0) //If ovalue is
//nonzero, the old value of the timer is stored there
return k;
switch (which) {
//unsigned long itimer_next = ~0;
//定义在sched.c中的,或许同任务的调度有关系~~
case ITIMER_REAL:
if (j) {
j += 1+itimer_ticks;
if (j < itimer_next)
itimer_next = j;
}
current->it_real_value = j;
current->it_real_incr = i;
break;
case ITIMER_VIRTUAL:
if (j)
j++;
current->it_virt_value = j;
current->it_virt_incr = i;
break;
case ITIMER_PROF:
if (j)
j++;
current->it_prof_value = j;
current->it_prof_incr = i;
break;
default:
return -EINVAL;
}
return 0;
} asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
int error;
struct itimerval set_buffer, get_buffer; if (!value)
memset((char *) &set_buffer, 0, sizeof(set_buffer));
else
memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
if (error || !ovalue) //这里的!ovalue不是表示错误的,如果没有提供地址就表示
//不返回旧的,而此处error如果等于0的话仍然成功返回!!
return error;
error = verify_area(VERIFY_WRITE, ovalue, sizeof(struct itimerval));
if (!error)
memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer)); //拷贝返回
return error; // 0 if success!
}
文档地址:http://blogimg.chinaunix.net/blog/upfile2/090306162649.pdf
*Created By: 陶治江
*Date: 2009-3-3
********************************************/
///////////////////////
//定时器介绍
/////////////////////// //真实间隔定时器ITIMER_REAL:这种间隔定时器在启动后不管进程是否运行,每个时钟滴答都将其间隔计数器减1
//当减到0值时,内核向进程发送SIGALRM信号。it_real_incr则表示间隔定时器的间隔计数器的初始值,
//而it_real_value则表示真实间隔定时器的间隔计数器的当前值 //虚拟间隔定时器ITIMER_VIRT:也称为进程的用户态间隔定时器。it_virt_incr 和it_virt_value分别表示虚拟间隔
//定时器的间隔计数器的初始值和当前值,二者均以时钟滴答次数位计数单位。当虚拟间隔定时器启动
//后,只有当进程在用户态下运行时,一次时钟滴答才能使间隔计数器当前值it_virt_value减1。
//当减到0值时,内核向进程发送SIGVTALRM信号(虚拟闹钟信号),并将it_virt_value重置为
//初值it_virt_incr //间隔定时器ITIMER_PROF:it_prof_value和 it_prof_incr成员分别表示PROF间隔定时器的间隔计数器的
//当前值和初始值。当一个进程的PROF间隔定时器启动后,则只要该进程处于运行中,而不管是在用户态或
//核心态下执行,每个时钟滴答都使间隔计数器it_prof_value值减1。当减到0值时,内核向进程
//发送 SIGPROF信号,并将it_prof_value重置为初值it_prof_incr #include <linux/signal.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/time.h> #include <asm/segment.h> //timevalue to jiffies,将时间值转换为滴答数
static unsigned long tvtojiffies(struct timeval *value)
{
return((unsigned long )value->tv_sec * HZ +
(unsigned long )(value->tv_usec + (1000000 / HZ - 1)) /
(1000000 / HZ));
} static void jiffiestotv(unsigned long jiffies, struct timeval *value)
{
value->tv_usec = (jiffies % HZ) * (1000000 / HZ);
value->tv_sec = jiffies / HZ;
return;
} //struct itimerval {
// struct timeval it_interval; /* timer interval */
// struct timeval it_value; /* current value */
//}; int _getitimer(int which, struct itimerval *value)
{
register unsigned long val, interval; switch (which) {
case ITIMER_REAL:
val = current->it_real_value;
interval = current->it_real_incr;
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);
} asmlinkage int sys_getitimer(int which, struct itimerval *value)
{
int error;
struct itimerval get_buffer; if (!value)
return -EFAULT;
error = _getitimer(which, &get_buffer);
if (error)
return error;
error = verify_area(VERIFY_WRITE, value, sizeof(struct itimerval));
if (error)
return error;
//拷贝到用户空间中
memcpy_tofs(value, &get_buffer, sizeof(get_buffer));
return 0;
} int _setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
register unsigned long i, j;
int k; //转换为滴答数
i = tvtojiffies(&value->it_interval);
j = tvtojiffies(&value->it_value);
if (ovalue && (k = _getitimer(which, ovalue)) < 0) //If ovalue is
//nonzero, the old value of the timer is stored there
return k;
switch (which) {
//unsigned long itimer_next = ~0;
//定义在sched.c中的,或许同任务的调度有关系~~
case ITIMER_REAL:
if (j) {
j += 1+itimer_ticks;
if (j < itimer_next)
itimer_next = j;
}
current->it_real_value = j;
current->it_real_incr = i;
break;
case ITIMER_VIRTUAL:
if (j)
j++;
current->it_virt_value = j;
current->it_virt_incr = i;
break;
case ITIMER_PROF:
if (j)
j++;
current->it_prof_value = j;
current->it_prof_incr = i;
break;
default:
return -EINVAL;
}
return 0;
} asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
int error;
struct itimerval set_buffer, get_buffer; if (!value)
memset((char *) &set_buffer, 0, sizeof(set_buffer));
else
memcpy_fromfs(&set_buffer, value, sizeof(set_buffer));
error = _setitimer(which, &set_buffer, ovalue ? &get_buffer : 0);
if (error || !ovalue) //这里的!ovalue不是表示错误的,如果没有提供地址就表示
//不返回旧的,而此处error如果等于0的话仍然成功返回!!
return error;
error = verify_area(VERIFY_WRITE, ovalue, sizeof(struct itimerval));
if (!error)
memcpy_tofs(ovalue, &get_buffer, sizeof(get_buffer)); //拷贝返回
return error; // 0 if success!
}
文档地址:http://blogimg.chinaunix.net/blog/upfile2/090306162649.pdf
相关阅读 更多 +