fix(sdk): 时钟 ABI 根因修复 — meow_ui_time 按 o32 time32 取时并链接期接管

真机 meow_ui_time_ms() 返回「低 32=秒×1000、高 32 随机」的根因不是 SDK 写法,
而是 zig 0.17 自带 musl 在 mipsel 上的 time64 ABI 自相矛盾:
- zig 头(mips-linux-musl/bits/alltypes.h)无条件 64 位 time_t、struct timespec 16 字节;
- zig 的 clang 给 32 位 mips 预定义 __ILP32__,musl 的 time64 回退分支
  `#if defined(SYS_x_time64) && !defined(__ILP32__)`(本意只排除 x32)被编译掉;
- 于是 libc 的 __clock_gettime64 实为 o32 time32 实现(SYS_clock_gettime 4263),
  只写 8 字节 {int32 sec; int32 nsec},与头的 16 字节布局错配。

修复(patch_v2/sdk/meow_ui_time.c):
- meow_ui_time_ms() 直接按内核 o32 ABI 取 8 字节 time32,再升 64 位毫秒;
- 同 TU 强定义 __clock_gettime/__clock_gettime64(归档先于 -lc,链接期接管,
  time()/gettimeofday()/pthread 定时等待的内部取时随之修正);
- 同源缺陷一并修:__nanosleep_time64/__clock_nanosleep(_time64) 转换 time32 后重发
  (修复前 usleep(16000) 等亚秒睡眠立即返回、变忙等空转);
- gfx/sys/input/cachegov 四处重复 now_ms 收敛到 meow_ui_time_ms;
- build_sdk.sh OBJS 增加 meow_ui_time;新增 test_meow_time 宿主单测、
  tools/clock_abi_probe.c 探针、CLOCK_ABI.md 根因/验证/影响面文档;
- 26 个宿主测试的编译注释补 meow_ui_time.c(cachegov 测试补时钟源)。

验证:宿主单测 PASS;anim(32)/view_event 宿主用例全过;build_sdk_host.sh --verify
76 成员全 MIPS32r2、0 warning;探针链接后无 libc cgt_init/__vdsosym,
__time64/__timedwait_cp 的取时指向本 TU,睡眠走 4166/4265 且用本地 8 字节结构。
This commit is contained in:
AskaEth committed 2026-11-05 13:41:52 +08:00
1 parent 8a115f6583
commit 38be5e78bc
37 files changed
+577 -75

No files matched your search

+6 -15
View File
@@ -172,15 +172,6 @@ static void refresh_governor(unsigned long long cost_ms, int period)
}
/* ---- 工具 ---- */
static uint64_t now_ms(void)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint64_t)ts.tv_sec * 1000u + (uint64_t)ts.tv_nsec / 1000000u;
}
uint64_t meow_ui_time_ms(void) { return now_ms(); }
static uint16_t rgb565(uint32_t c)
{
return (uint16_t)(((c >> 8) & 0xF800) | ((c >> 5) & 0x07E0) | ((c >> 3) & 0x001F));
@@ -895,7 +886,7 @@ static void statusbar_collapse_step(void)
int tgt = g_sbar_collapsed ? MUI_SBAR_H : 0;
if (g_sbar_collapse_h == tgt) return;
if (g_sbar_collapse_anim_ms <= 0) { g_sbar_collapse_h = tgt; return; }
unsigned long long now = now_ms();
unsigned long long now = meow_ui_time_ms();
unsigned long long el = now - g_sbar_collapse_start_ms;
int span = g_sbar_collapse_anim_ms;
if ((int)el >= span) { g_sbar_collapse_h = tgt; return; }
@@ -932,7 +923,7 @@ void meow_ui_statusbar_set_collapsed(int on)
if (tgt == g_sbar_collapsed) return;
g_sbar_collapsed = tgt;
g_sbar_collapse_from_h = g_sbar_collapse_h;
g_sbar_collapse_start_ms = now_ms();
g_sbar_collapse_start_ms = meow_ui_time_ms();
dirty_full(); /* 顶栏显隐/上收变化 → 全帧重画 */
meow_ui_sbar_write_mode(); /* App 进程上报顶条模式(launcher 感知全屏/收合,agent-146) */
}
@@ -1012,7 +1003,7 @@ int meow_ui_overlay_suppressed_active(void)
snprintf(s_path, sizeof s_path, "%s", (e && e[0]) ? e : MEOW_NOTIF_ACTIVE_DEFAULT);
s_path_init = 1;
}
unsigned long long now = now_ms();
unsigned long long now = meow_ui_time_ms();
if (s_last_chk && now - s_last_chk < MEOW_OVERLAY_CHK_MS) return s_last_res;
s_last_chk = now;
{
@@ -1066,7 +1057,7 @@ static void present(void)
}
/* 帧率门控(A-1/A-2,从 launcher 迁入):present 距上次 ≥ period(1000/eff_rate) 才呈现;
* 未满周期则保留脏区(不 dirty_reset),下一轮再试。refresh_always_max=1 时跳过门控(恒满速)。 */
unsigned long long now = now_ms();
unsigned long long now = meow_ui_time_ms();
int period = (g_eff_rate > 0) ? (1000 / g_eff_rate) : 16;
if (!g_refresh_always_max) {
if (g_last_present_ms && now - g_last_present_ms < (unsigned long long)period) return;
@@ -1096,7 +1087,7 @@ static void present(void)
}
if (g_fb_mem) {
ioctl(g_fb_fd, FBIO_WAITFORVSYNC, 0); /* 等垂直同步 */
unsigned long long tbg = now_ms();
unsigned long long tbg = meow_ui_time_ms();
/* 「同一个状态栏」闭环:App 进程不渲染状态栏(meow_ui_sys_render_enabled()==0),也绝不向
* 真实 fb 写顶条 inset 区(顶条由 launcher 系统进程叠加绘制)。否则 App 首帧全量拷贝
* (meow_ui_init 置 dirty_full)会把 launcher 刚叠画的顶条冲成未初始化数据——真机
@@ -1133,7 +1124,7 @@ static void present(void)
}
}
}
refresh_governor(now_ms() - tbg, period);
refresh_governor(meow_ui_time_ms() - tbg, period);
}
g_last_present_ms = now;
g_frames_presented++;