web-dev-qa-db-ja.com

ジフィーをミリ秒に変換する

Linuxでjiffiesをミリ秒に、またはその逆に手動で変換するにはどうすればよいですか?カーネル2.6にはこのための機能があることは知っていますが、2.4(宿題)に取り組んでおり、コードを調べましたが、2.4で定義されているかどうかわからない多くのマクロ定数を使用しています。

43
EpsilonVector

前の回答で述べたように、jiffies増分のレートは固定されています。

jiffiesを受け入れる関数の時間を指定する標準的な方法は、定数HZを使用することです。

これは、Hertzの略語、または1秒あたりのティック数です。タイマーティックが1ミリ秒に設定されているシステムでは、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 */

最後の2つには少し問題がありますが、10ミリ秒のタイマーティックを持つシステムでは、HZ/100は1であり、精度が低下し始めます。 0.0001〜1.999のタイマーティック(0〜2ミリ秒、基本的に)の間で遅延が発生する場合があります。 10msのティックシステムでHZ/200を使用しようとした場合、整数の除算により0 jiffiesが得られます。

したがって、経験則では、小さな値(1ジフィーに近い値)に対してHZを使用する場合は非常に注意してください。

他の方法に変換するには、次を使用します。

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

ミリ秒の精度よりも良いものを期待すべきではありません。

45
Eric Seppanen

Linux 2.4では、Jiffiesはハードコーディングされています。アーキテクチャ固有のparam.hで定義されているHZの定義を確認してください。多くの場合、100 Hzです。これは、10ミリ秒ごとに1ティック(1秒/ 100ティック* 1000ミリ秒/秒)です。

これは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でこの情報を確認しました。

14
indiv

このサンプルコードは 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;
 }
5
Anthony Giorgio

CLIを使用してUSER_HZ値を取得するには(受け入れられた回答の下のコメントを参照):

getconf CLK_TCK
1
P. Cahyna