将jiffies转换为毫秒

问题描述 投票:43回答:4

如何在Linux中手动将jiffies转换为毫秒,反之亦然?我知道内核2.6有一个功能,但我正在研究2.4(作业),虽然我看了代码它使用了很多宏常量我不知道它们是否在2.4中定义。

linux linux-kernel
4个回答
45
投票

如前所述,jiffies增量的比率是固定的。

为接受jiffies的函数指定时间的标准方法是使用常量HZ

这是Hertz的缩写,或每秒的滴答数。在计时器滴答设置为1ms的系统上,HZ = 1000。某些发行版或体系结构可能使用另一个数字(100曾经是常见的)。

为函数指定jiffies计数的标准方法是使用HZ,如下所示:

schedule_timeout(HZ / 10);  /* Timeout after 1/10 second */

在大多数简单的情况下,这很好。

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 */

然而,最后两个有一点问题,因为在具有10毫秒计时器滴答的系统上,HZ/100为1,并且精度开始受损。你可能会在0.0001和1.999计时器滴答之间的任何地方得到延迟(基本上是0-2毫秒)。如果您尝试在10ms刻度系统上使用HZ/200,则整数除法为您提供0个jiffies!

所以经验法则是,使用HZ非常小心的微小值(接近1 jiffie)。

要转换另一种方式,您将使用:

jiffies / HZ          /* jiffies to seconds */
jiffies * 1000 / HZ   /* jiffies to milliseconds */

你不应该期望比毫秒精度更好的东西。


14
投票

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_jiffiesjiffies_to_timespec的函数,你可以在struct timespecjiffies之间来回转换:

    #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;
    }

注意:我在版本2.4.22中检查了此信息。


5
投票

我在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;
 }

1
投票

要使用CLI获取USER_HZ值(请参阅接受的答案下的注释):

getconf CLK_TCK
© www.soinside.com 2019 - 2024. All rights reserved.