どうやら、それは不可能です。まず、time()
は 1 つだけです。 Linux での機能、なし time32()
または time64()
.
しばらく調べてみると、libc のせいではなく、実はカーネルに問題があることがわかりました。
libc が現在の時刻を取得するには、システム コールを実行する必要があります:
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
システムコールは次のように定義されます:
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
関数 get_seconds()
unsigned long
を返します 、そのように:
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
そして timekeeper.xtime_sec
は実際には 64 ビットです:
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
C の知識があれば、 unsigned long
のサイズが 実際には実装依存です。ここにある私の 64 ビット マシンでは、64 ビットです。しかし、私の 32 ビット マシンでは 32 ビットです。 おそらく 一部の 32 ビット実装では 64 ビットになる可能性がありますが、保証はありません。
一方、u64
は常に 64 ビットであるため、カーネルは基本的に 64 ビット型で時間を追跡します。これを unsigned long
として返す理由 、64ビット長であることが保証されていないため、私には理解できません。
最後に、libc が time_t
を強制したとしても 64 ビットの値を保持する場合、何も変わりません。
アプリケーションをカーネルに深く結び付けることができますが、それだけの価値はないと思います。
上記の多くの回答は不可能だと言っていますが、それは完全に間違っています . だった 当時は不可能でしたが、人々はそれを修正することについて何年も話し合っていました。最後に、新しい *time64
の追加により、32 ビット プラットフォームでの 64 ビット時間のサポートが Linux 5.1 カーネルに導入されました。 システムコール。この表を見ると、これらの syscall は 32 ビット プラットフォームでのみ使用できることがわかります。 32 ビット システム用のコードを記述している場合は、clock_gettime64
を呼び出すことができます。 直接 (インライン アセンブリまたは syscall()
を使用した C から) ) 現在の時刻を取得する
ただし、その後は完全に独りです。フルユーザースペースが必要な場合 Linux 5.6 以降と musl 1.2+ または glibc 2.32+ を使用している必要があります。コードと time_t
を再構築するだけです 64ビット長になります
すべてのユーザー空間は、64 ビットの
time_t
でコンパイルする必要があります これは、今後の musl-1.2 および glibc-2.32 リリースで、linux-5.6 以降のインストール済みカーネル ヘッダーと共にサポートされる予定です。システム コール インターフェイスを直接使用するアプリケーションは、
time64
を使用するように移植する必要があります。 syscalls は、既存のシステム コールの代わりに linux-5.1 で追加されました。これはfutex()
のほとんどのユーザーに影響します とseccomp()
libc に基づいていない独自のランタイム環境を持つプログラミング言語も同様です。https://lkml.org/lkml/2020/1/29/355?anz=web
詳細については
- カーネル 2038 年エンド ゲームに近づく
- GNU C ライブラリでの 64 ビット時間シンボルの処理
- glibc Y2038 プルーフネス デザイン
- time_t と clock_t を 64 ビットに変更