Eps*_*tor 43 linux linux-kernel
如何在Linux中手动将jiffies转换为毫秒,反之亦然?我知道内核2.6有一个功能,但我正在研究2.4(作业),虽然我看了代码它使用了很多宏常量我不知道它们是否在2.4中定义.
Eri*_*nen 45
如前面的答案所述,jiffies增量的固定速率.
为接受的函数指定时间的标准方法jiffies是使用常量HZ.
这是Hertz的缩写,或每秒的滴答数.在计时器滴答设置为1ms的系统上,HZ = 1000.某些发行版或体系结构可能使用另一个数字(100曾经是常见的).
指定jiffies函数计数的标准方法是使用HZ,如下所示:
schedule_timeout(HZ / 10); /* Timeout after 1/10 second */
Run Code Online (Sandbox Code Playgroud)
在大多数简单的情况下,这很好.
2*HZ /* 2 seconds in jiffies */
HZ /* 1 second in jiffies */
foo * HZ /* foo seconds in jiffies */
HZ/10 /* 100 milliseconds in jiffies */
HZ/100 /* 10 milliseconds in jiffies */
bar*HZ/1000 /* bar milliseconds in jiffies */
Run Code Online (Sandbox Code Playgroud)
然而,最后两个有一点问题,因为在具有10毫秒计时器滴答的系统上,HZ/100是1,并且精度开始受损.你可能会在0.0001和1.999计时器滴答之间的任何地方得到延迟(基本上是0-2毫秒).如果您尝试HZ/200在10ms刻度系统上使用,则整数除法为您提供0个jiffies!
所以经验法则是,非常小心地使用HZ来获得微小的值(接近1 jiffie).
要转换另一种方式,您将使用:
jiffies / HZ /* jiffies to seconds */
jiffies * 1000 / HZ /* jiffies to milliseconds */
Run Code Online (Sandbox Code Playgroud)
你不应该期望比毫秒精度更好的东西.
ind*_*div 15
Jiffies在Linux 2.4中是硬编码的.检查HZ特定于体系结构中定义的定义param.h.它通常为100 Hz,即每1(1秒/ 100滴*1000毫秒/秒)10毫秒.
这适用于i386,HZ定义于include/asm-i386/param.h.
有函数include/linux/time.h称为timespec_to_jiffies和jiffies_to_timespec在那里你可以来回转换之间struct timespec和jiffies:
#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
static __inline__ unsigned long
timespec_to_jiffies(struct timespec *value)
{
unsigned long sec = value->tv_sec;
long nsec = value->tv_nsec;
if (sec >= (MAX_JIFFY_OFFSET / HZ))
return MAX_JIFFY_OFFSET;
nsec += 1000000000L / HZ - 1;
nsec /= 1000000000L / HZ;
return HZ * sec + nsec;
}
static __inline__ void
jiffies_to_timespec(unsigned long jiffies, struct timespec *value)
{
value->tv_nsec = (jiffies % HZ) * (1000000000L / HZ);
value->tv_sec = jiffies / HZ;
}
Run Code Online (Sandbox Code Playgroud)
注意:我在版本2.4.22中检查了此信息.
我在kernelnewbies上找到了这个示例代码.确保你链接-lrt
#include <unistd.h>
#include <time.h>
#include <stdio.h>
int main()
{
struct timespec res;
double resolution;
printf("UserHZ %ld\n", sysconf(_SC_CLK_TCK));
clock_getres(CLOCK_REALTIME, &res);
resolution = res.tv_sec + (((double)res.tv_nsec)/1.0e9);
printf("SystemHZ %ld\n", (unsigned long)(1/resolution + 0.5));
return 0;
}
Run Code Online (Sandbox Code Playgroud)