jiffies变量,是在linux内核源码中经常可以看见的一个变量。jiffies,即jiffy的复数形式,jiffy的汉语解释为瞬间的意思,从变量名上看,jiffies的含义为记录系统的当前时间。查看Linux内核的源码,可以发现,jiffies是一个宏定义,# define jiffies raid6_jiffies(),所以jiffies的值实际上是调用raid6_jiffies()的返回值.
raid6_jiffies()是Linux内核源码中的一个内联函数, 其定义如下:
static inline uint32_t raid6_jiffies(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec*1000 + tv.tv_usec/1000;
}
struct timeval结构体的定义如下:
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
struct timeval中含有两个字段, tv_sec和tv_usec, 一个用于记录秒数, 一个用于记录毫秒数. time_t实质上是long类型, 将long重新定义成了time_t类型; susecong_t与time_t相同, 实质上也是long类型. 在Linux内核源码的实现过程中, 为了能清晰地表示变量的含义和功能,常常会将一些数据类型进行重定义, 使其变得一目了然, 可以从变量类型上判断变量的功能.
gettimeofday(&tv, NULL)方法的实现, 如下所示:
static force_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
{
int ret;
asm volatile("syscall"
: "=a" (ret)
: "0" (__NR_gettimeofday),"D" (tv),"S" (tz) : __syscall_clobber );
return ret;
}
在其中, 内嵌了一段asm汇编代码. asm表示后面的代码为内嵌汇编, volatile表示编译器不需要优化代码, 后面的指令保留原样, 括号里的是汇编指令, asm和volatile分别为__asm__和__volatile__的别名, 含义相同.
内嵌汇编语法如下:
__asm__(汇编语句模板:输出部分:输入部分:破坏描述部分), 四个部分用”:”隔开, 除汇编语句模板外, 其余部分可选.
具体汇编语法可参照博客https://blog.csdn.net/pbymw8iwm/article/details/8227839.
在此函数中, 涉及到syscall指令的用法.
syscall指令, 从操作系统获得服务.
如何使用:
1. 从$0寄存器中读取服务数
2. 从$a0, $a1等寄存器中读取参数值(如果有)
3. 发送syscall指令
4. 从结果寄存器中取回返回值(如果有)
不过syscall指令在此处究竟是如何使用的, 依然不十分清楚. 若有清楚的大神, 希望可以不吝赐教.
通过syscall调用得到系统时间, 并存储在struct timeval类型结构体tv中. 由于在raid6_jiffies()中调用gettimefday(&tv, NULL)时, 传递的是&tv, 所以在gettimeofday()中对tv的操作, 便确确实实地改变了tv的值.
tv.tv_sec存储的是系统当前时间的秒数, 单位为秒, *1000得到毫秒数; tv.tv_usec存储的是微秒数, /1000得到的是毫秒数(此处分析, tv.tv_usec存储的应该为不足1s的部分的微秒数). 两者相加, 得到当前系统时间的毫秒数.