/* meow_time32.h — mipsel o32 内核 time32 ABI 兜底(**可独立链接**的公共设施)。 * * 为什么单独成文件(M40): * zig 0.17 给 32 位 mips 预定义 __ILP32__,打穿 musl 的 time64 回退守卫:调用方按 * 16 字节 time64 结构取数,libc 却只发 time32 系统调用(只写前 8 字节)。结果是 * 「秒在低 32 位、毫秒位恒 0、高 32 位是 nsec」的垃圾时间,任何 now_ms()/超时/退避 * 都会失真。meow_ui_time.c 的修复只对**链接 meow_ui.a** 的进程生效;系统组件 * (watchdog / sysui / svcd / bootmenu / amsd / audiod / netmgrd / crash / svc_perf / * powermgr / meowpanel)各自独立静态链接,不链 SDK,因此需要一份不依赖 SDK 的实现。 * * 本 TU 只依赖 libc(stdint/unistd/time/syscall),不引用 meow_ui.a 的任何符号: * - 纯换算函数(与内核结构宽度解耦,宿主可直接单测); * - 内核 o32 time32 取时(meow_time32_clock_gettime / meow_time32_monotonic_ms); * - 亚秒睡眠(meow_time32_sleep_us;usleep 同源受损,见 meow_ui_time.c 注释)。 * * 用法(系统组件的构建脚本): * $CC ... meow_watchdog.c ../sdk/meow_time32.c -o meow_watchdog * 若希望**链接期整体接管 libc 的取时/睡眠入口**(不再逐个改调用点),额外加宏 * -DMEOW_TIME32_LIBC_OVERRIDES * 该宏只在 mipsel o32 上生效;此时**不要**同时链接 meow_ui.a 里的 meow_ui_time.o * (两者都会强定义 __clock_gettime 等符号)。 */ #ifndef MEOW_TIME32_H #define MEOW_TIME32_H #include #ifdef __cplusplus extern "C" { #endif /* mipsel o32 内核结构(与 libc 头里的 time_t 宽度无关): * { int32 tv_sec; int32 tv_nsec; } —— 固定 8 字节。 */ struct meow_time32 { int32_t tv_sec; int32_t tv_nsec; }; struct meow_itimerspec32 { struct meow_time32 it_interval; struct meow_time32 it_value; }; /* 与 libc 结构解耦的 64 位镜像(宿主/交叉两端 time_t 宽度不同,测试不依赖它)。 */ struct meow_time64_spec { int64_t tv_sec; int64_t tv_nsec; }; struct meow_time64_itimerspec { struct meow_time64_spec it_interval; struct meow_time64_spec it_value; }; /* ---- 纯换算(无系统调用;宿主单测直接覆盖)---- */ /* 相对超时(futex / nanosleep 的「等多久」):sec 超出 int32 时饱和 * (正→INT32_MAX、负→INT32_MIN,与 musl CLAMP 一致),nsec 原样。 */ void meow_time32_rel_from_parts(int64_t sec, int64_t nsec, struct meow_time32 *out); /* 绝对时刻(clock_settime / timerfd):sec 落不进 int32 返回 -1,nsec 原样。 */ int meow_time32_abs_from_parts(int64_t sec, int64_t nsec, struct meow_time32 *out); /* itimerspec 转换;任一侧越界返回 -1 且 *out 不变。 */ int meow_time32_itimerspec_from_64(const struct meow_time64_itimerspec *in, struct meow_itimerspec32 *out); void meow_time64_itimerspec_from_32(const struct meow_itimerspec32 *in, struct meow_time64_itimerspec *out); /* 秒/纳秒 → 单调毫秒的唯一换算点。 */ uint64_t meow_time_ms_from_parts(int64_t sec, int64_t nsec); /* ---- 内核取时 / 睡眠 ---- */ /* 按内核 o32 ABI 取时(clk 用 的 CLOCK_*)。返回 0=成功 / -1=失败(errno)。 */ int meow_time32_clock_gettime(int clk, struct meow_time32 *out); /* CLOCK_MONOTONIC 毫秒;失败返回 0。 */ uint64_t meow_time32_monotonic_ms(void); /* 睡眠 usec 微秒(EINTR 自动续睡)。返回 0=正常 / -1=失败(errno)。 */ int meow_time32_sleep_us(unsigned usec); #ifdef __cplusplus } #endif #endif /* MEOW_TIME32_H */