【发布时间】:2015-05-19 01:22:20
【问题描述】:
我已经编译了内核 3.19.1,但time_t 仍然存在问题。只是一个带有cout << sizeof (time_t); 的简单程序就给出了 4 个字节的大小,而不是我的意图的 8 个字节。
我应该在 make menuconfig 期间打开特定选项吗?
【问题讨论】:
标签: linux kernel 64-bit time-t year2038
我已经编译了内核 3.19.1,但time_t 仍然存在问题。只是一个带有cout << sizeof (time_t); 的简单程序就给出了 4 个字节的大小,而不是我的意图的 8 个字节。
我应该在 make menuconfig 期间打开特定选项吗?
【问题讨论】:
标签: linux kernel 64-bit time-t year2038
目前time_t 在内核中只是long:参见__kernel_time_t 类型定义。所以如果你的 CPU 上的 long 类型是 32 位长,time_t 也是 32 位长。基本上,如果您有 32 位 CPU——您系统上的 long 类型也是 32 位长的。如果您有 64 位 CPU -- long 类型将是 64 位长。
如果您需要自己的 64 位类型 - 只需使用 long long。如果您希望内核时间 API 与 time_t 一样的 64 位长类型工作 - 这有点困难(意味着更改内核源代码)。例如看看here。您也可能有兴趣阅读下一个链接:
[1]patchset: "Change time_t and clock_t to 64 bit"
[2]Is there any way to get 64-bit time_t in 32-bit program in Linux
[3]What is ultimately a time_t typedef to?
关于将time_t 更改为long long 后的构建问题(__divdi3 等)。
既然您已将 time_t 的大小更改为 64 位,任何使用 time_t 的代码都将尝试使用 64 位操作。 __divdi3 表示:div对double i整数的ision 操作。 3 代表操作数的数量(如1 = 2 / 3)。有关详细信息,请参阅this。所以这个操作显然没有为你的平台实现。您应该自己实现它(在内核代码中)或以某种方式使用来自gcc 的实现。下一个链接应该对您有所帮助:
[1]__udivdi3 undefined. Howto find code?
【讨论】:
int64_t,因为我知道它会一直是 64 位,甚至不用考虑它。不过,它仅在 C99 之后可用。
include/linux/types.h 中定义了int64_t,所以你不必使用C99+。只需使用#include <linux/types.h>,或者甚至可以通过其他标头隐式包含(通常这样做)。
__divdi3。但是您是对的,它仍然意味着更改用户空间中的所有相关代码。所以最好的选择是现在使用可用的 32 位实现(它仍然有效到 2038 年)并等待内核开发人员在将来的某个时候对其进行更改。
32 位 Linux 上的 64 位时间支持是 first introduced in the 5.1 kernel,所以如果您比这更老,对不起。因为更改旧系统调用的返回类型会破坏旧应用程序,所以必须添加新的*time64 syscalls。检查this table,您会发现这些系统调用仅在 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 或更高版本的内核头文件都将支持该文件。直接使用系统调用接口的应用程序需要移植到使用 linux-5.1 中添加的
time64系统调用来代替现有的系统调用。这会影响futex()和seccomp()的大多数用户以及拥有自己的运行时环境而不基于libc 的编程语言。
更多信息请阅读
【讨论】: