Linuxでjiffiesをミリ秒に、またはその逆に手動で変換するにはどうすればよいですか?カーネル2.6にはこのための機能があることは知っていますが、2.4(宿題)に取り組んでおり、コードを調べましたが、2.4で定義されているかどうかわからない多くのマクロ定数を使用しています。
前の回答で述べたように、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 */
ミリ秒の精度よりも良いものを期待すべきではありません。
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_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;
}
注:バージョン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;
}
CLIを使用してUSER_HZ値を取得するには(受け入れられた回答の下のコメントを参照):
getconf CLK_TCK