linux进程创建时间,linux进程创建时间计算

欢迎访问小站,阅读此文http://www.yandong.org/archives/501

简介

墙上时间,也就是距离1970年1月1日的时间,在linux kernel内部没多大用处,对其的应用多在用户空间。

本文的目的在于在kernel里面计算得到 进程创建的墙上时间

计算公式

xtime.tv_sec-(jiffies/HZ)+300+p->real_start_time.tv_sec

意思就是,当前的墙上时间(xtime) 减去系统启动后的节拍(jiffies)/频率(HZ)   这样得到的是系统启动的墙上时间,即距离1970.1.1的秒数,然后再加上进程结构体中 保存的距离系统启动时间的秒数(p->real_start_time.tv_sec)。

下面分别解释:

task_struct中的时间

p->real_start_time.tv_sec

其中的p是task_struct指针,指向的是进程创建距离系统启动的时间.

task_struct中有两个时间:start_time 和 real_start_time,其中后者包含睡眠时间。

下面是进程创建的部分源码

do_posix_clock_monotonic_gettime(&p->start_time);p->real_start_time=p->start_time;monotonic_to_bootbased(&p->real_start_time);//真实启动时间还须要加上总的睡眠时间

xtime介绍

摘自《深入理解linux内核》

所有的PC都包含一个叫实时时钟(Renl Time Clock RTC)的时钟,它是独立于CPU和所有其他芯片的。

即使当PC呗切断电源,RTC还继续工作,因为它靠一个小电池或蓄电池供电。CMOS RAM和RTC被集成在一个芯片上。

Linux只用RTC来获取时间和日期。不过对/dev/rtc设备文件操作,也允许对RTC编程。

内核利用 get_cmos_time函数从实时时钟上读取字1970.1.1(UTC)午夜以来经过的秒数。

xtime_lock顺序所(seqlock)消除了对xtime变量同时访问而可能发生的竞争条件,

对于2.6内核,其定义为(/include/linux/time.h)

externstructtimespec xtime;

对于3.5内核,其定义为(kernel/time/timekeeping.c)

structtimekeeper{...structtimespec xtime;...};staticstructtimekeeper timekeeper;

xtime的获取

因为很难原子的访问结构体中的两个变量,所以kernel并不鼓励直接访问xtime变量,可以使用相关函数

//include/linux/time.hstructtimespec current_kernel_time(void);externvoiddo_gettimeofday(structtimeval*tv);

所以如果在module里面直接使用 xtime,是不行的。但是可以通过硬编码的方式获取

比如:

long*xtime_ptr=&xtime;或者long*xtimr_ptr=0xc0803980

其中的 0xc0803980这个值,是从System.map中获得的,xtime是个全局符号,所有从sytem.map中可以获得它的地址

root@hyd:/home/l# cat /boot/System.map-2.6 | grep xtimec0156230 T update_xtime_cache

c06e3c00 D xtime_lock

c072f654 D inet_peer_gc_maxtime

c0803980 B xtime

c08039a0 b xtime_cache

jiffies介绍

简介

全局变量jiffies用来记录自系统启动以来产生的节拍的总数。

它被用来记录系统自开机以来,已经过了多少tick。每发生一次timer interrupt,Jiffies变数会被加一。

启动时,内核将该变量初始化为0,此后,每次时钟中断处理程序都会增加该变量的值。

因为一秒内时钟中断的次数等于Hz,所以jiffes一秒内增加的值也就为Hz,系统运行时间以秒为单位计算,就等于jiffes/Hz。

定义

externu64 __jiffy_data jiffies_64;externunsignedlongvolatile__jiffy_data jiffies;

其中,jiffies_64 和 jiffies 的低32位是重合的,因为32为的jiffies 最多50天就溢出了,而jiffies_64则不用关注溢出问题。

初始化

#define INITIAL_JIFFIES((unsignedlong)(unsignedint)(-300*HZ))jiffies=INITIAL_JIFFIES

可以看出 jiffies 被初始化为5分钟后溢出的一个值,这是为了方便内核调试,以便故障早点出来。

获取

由于jiffies_64 是一个符合变量,不能直接获取,需要下面的使用辅助函数

#if(BITS_PER_LONG<64)u64 get_jiffies_64(void);#elsestaticinline u64 get_jiffies_64(void){return(u64)jiffies;}#endif

当然也可以使用硬编码的方式使用  jiffies

root@hy:/home/#cat/boot/System.map|grep"D jiffies"c06e3b00 D jiffies

c06e3b00 D jiffies_64

从中也可以看到 jiffies 与 jiffies_64的地址是相同的

使用

由于jiffies在五分钟之后,便溢出,所以使用jiffies的原则如下

//如果jiffies变量类型是32位无符号intmax_count=0xffffffffor

max_count=0xffffffffffffffff(64-bit)//如果没有溢出,系统启动后运行的节拍数:jiffies-ITIAL_JIFFIES//系统启动来5分钟的节拍数就是(到jiffies溢出的前一拍):max_count-INITIAL_JIFFIES

在我的代码中,我是这样使用的

unsigendlongjiffies_test=jiffies+HZ;if(time_after(jiffies,jiffies_test)){jiffies=MAX_JIFFIES-jiffies;}else{jiffies=jiffies-INITIAL_JIFFIES;}

其中的 time_after 是内核提供的四个比较函数之一

#definetime_after(a,b)\(typecheck(unsignedlong,a)&&\

typecheck(unsignedlong,b)&&\((long)(b)-(long)(a)<0))#definetime_before(a,b)time_after(b,a)#definetime_after_eq(a,b)\(typecheck(unsignedlong,a)&&\

typecheck(unsignedlong,b)&&\((long)(a)-(long)(b)>=0))#definetime_before_eq(a,b)time_after_eq(b,a)

为什么time_after能判断溢出呢?

待续,或者 参考下面链接

链接

http://book.51cto.com/art/200810/93773.htm

http://blog.csdn.net/michaelcao1980/article/details/7826326

http://lxr.oss.org.cn/source/include/linux/jiffies.h?v=2.6.30#L167

http://blog.csdn.net/chchchdx123/article/details/6270022

http://linux.gongxiang8.com/456430/

如果您喜欢这篇文章,欢迎分享订阅。本文内容遵CC版权协议 转载请注明出处www.yandong.org

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值