Linuxの中には複数の時間の概念があることを最近になって知った。
jiffiesにも綺麗にハメられたことであるし、LinuxとC言語の時間をまとめておく。
※肝心のjiffiesが別記事なったけどw
Linuxの時間概念
Linux Kernelの中には、複数の時間システムが存在する。
- timeval
- timespec
- ktime_t
- jiffies
構造体timeval
POSIX環境での時間構造体。
理由は分からないが、どうやら**非推奨**らしい。
#include <sys/time.h>
struct timeval {
time_t tv_sec; /* Seconds. */
suseconds_t tv_usec; /* Microseconds. */
};
POSIX環境で使用できる時間構造体の一つ。
次に紹介するstruct timespec
と非常によく似た構造体である。
-
tv_sec
time()
の戻り値と同値。 - tv_usec 範囲は0~999,999
gettimeofday()
によってUNIX時間を表現した値が入ったインスタンスが取得できる。
構造体timespec
C11で採用されたらしい新しい時間構造体。
#include <time.h>
struct timespec {
time_t tv_sec; /* Seconds. */
long tv_nsec; /* Nanoseconds. */
};
元々、struct timespec
はPOSIX環境で定義されていた時間構造体らしい(知らん)。
-
tv_sec
time()
の戻り値と同値。 - tv_nsec 範囲は0~999,999,999
こっちの方が、struct timeval
より記録粒度が細かい。
(細かく正確に測定できるとは言ってない。)
さらには、OSのAPIを直接使わなくていいので、移植性が高い。
……誰かstruct timeval
の方の優位性を教えて欲しい、偉い人よ。
あと、これ何でか知らないけどLinux Kernel上でも使えるよね。
#include <linux/time.h>
すればstruct timespec
をstruct tm
に変換したりできる。
変数ktime_t
1/100,000,000(ナノ)秒単位での時間または時刻を格納するために使われる。
粒度はstruct timespec
と同じ。
ただし、こっちはKernel空間の変数。
Linux Kernel内でKerel Timerとして使われる。
#include <linux/ktime.h>
union ktime {
s64 tv64;
#if BITS_PER_LONG != 64 && !defined(CONFIG_KTIME_SCALAR)
struct {
# ifdef __BIG_ENDIAN
s32 sec, nsec;
# else
s32 nsec, sec;
# endif
} tv;
#endif
};
複雑な定義だが、以下に分岐する。
-
64bit環境
64bit長変数1つだけ。 -
32bit Big Endian 環境
32bit長変数2つでメモリ消費量を合わせている。
元がunion定義なので、64bit <--> 32bitの環境差を吸収している。
この定義スゴイよな。俺も仕事でやったわ。 -
32bit Little Endian 環境
32bit Big Endianの定義の順番を入れ替えただけ。
番外編:time_t
C言語は別記事で。
変数Jiffies
ハマったので別記事にしました。