Files
MeowOS-For-R3P2/patch_v2/sdk/meow_time32.c
T
AskaEth 63b278e13e fix(watchdog+launcher+sdk): M40 电源键 time64 ABI + 锁屏/叠加残留链
- sdk/meow_time32: 抽出可独立链接的 o32 time32 取时/睡眠设施(不依赖 meow_ui.a,
  watchdog 等独立静态组件可直接链;可选 -DMEOW_TIME32_LIBC_OVERRIDES 接管 libc 入口)
- watchdog: now_ms/usleep 改走 time32(修复 held 变天文数字→每次单击都弹菜单);
  阈值读 power.longpress_menu_ms/forceoff_ms(缺省 3000/8000),删除
  PWR_TOGGLE_MS==PWR_MENU_MS;新增 wd_power.h 纯判定 + 宿主行为矩阵测试
- launcher: App 前台电源菜单补齐 §10.5(notif 全抑制 + 帧恢复 + SIGCONT 排空 +
  标记翻回前台);show_power_menu 恢复进入前背景帧(关闭后不再停留菜单画面);
  重绘挪到首轮按键采样之后;activity 标记排空窗 + 会话入口清理 + manual_off 去闩锁
- lock_screen: 电源改按下边沿 + 进场 300ms 才熄屏;电源熄屏退出也恢复底层帧;
  launcher 在 SIGCONT 前写 /tmp/meow_app_repaint,SDK present 消费并 dirty_full
- power_menu: 菜单内强关接 power.forceoff_ms(按 longpress 抵扣),日志不再谎称 8s
- 重编 meow_ui.a 并重链 meow_launcherd/ncm/files/hello/reader(picbrowser 无源码)
- fw_content.conf: 同步 launcherd/watchdog 新 md5;顺带修正 M35 遗留的 nyai 失效钉值

Host: test_wd_fw 66/66、test_overlay_gate 40/40、test_meow_time64/time/repaint PASS。
真机未验证(设备关机);未刷机、未写设备。
2026-11-10 22:51:00 +08:00

192 lines
6.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* meow_time32.c — mipsel o32 内核 time32 ABI 兜底(独立链接,不依赖 meow_ui.a)。
*
* 根因与逐项证据:sdk/CLOCK_ABI.md(M11/M16)。核心一句话:
* zig 0.17 的 musl 在 mipsel 上按 `#if defined(SYS_x_time64) && !defined(__ILP32__)`
* 守卫 time64 回退,而 zig clang 又预定义了 __ILP32__,于是「time64 入口」被编成
* 老的 time32 实现:内核只写 8 字节 {int32 sec; int32 nsec;},调用方却按 16 字节
* 结构读。本文件不猜 libc 头的结构宽度,**直接按内核 ABI 取数/睡眠**。
*
* 本 TU 不引用 SDK 符号;系统组件(watchdog 等)可单独链接它。宿主(非 mips o32)
* 自动退回 libc 的 clock_gettime/nanosleep,行为等价,宿主单测可直接编译运行。
*/
#include <errno.h>
#include <stdint.h>
#include <time.h>
#include <unistd.h>
#include "meow_time32.h"
#if defined(__mips__) && !defined(__mips64) && (__SIZEOF_LONG__ == 4)
#define MEOW_TIME32_KERNEL_ABI 1
#include <sys/syscall.h>
#else
#define MEOW_TIME32_KERNEL_ABI 0
#endif
/* ---- 纯换算 ---- */
void meow_time32_rel_from_parts(int64_t sec, int64_t nsec, struct meow_time32 *out)
{
if (sec > INT32_MAX) sec = INT32_MAX;
else if (sec < INT32_MIN) sec = INT32_MIN;
out->tv_sec = (int32_t)sec;
out->tv_nsec = (int32_t)nsec;
}
int meow_time32_abs_from_parts(int64_t sec, int64_t nsec, struct meow_time32 *out)
{
if (sec > INT32_MAX || sec < INT32_MIN) return -1;
out->tv_sec = (int32_t)sec;
out->tv_nsec = (int32_t)nsec;
return 0;
}
int meow_time32_itimerspec_from_64(const struct meow_time64_itimerspec *in,
struct meow_itimerspec32 *out)
{
struct meow_itimerspec32 t;
if (meow_time32_abs_from_parts(in->it_interval.tv_sec, in->it_interval.tv_nsec,
&t.it_interval)) return -1;
if (meow_time32_abs_from_parts(in->it_value.tv_sec, in->it_value.tv_nsec,
&t.it_value)) return -1;
*out = t;
return 0;
}
void meow_time64_itimerspec_from_32(const struct meow_itimerspec32 *in,
struct meow_time64_itimerspec *out)
{
out->it_interval.tv_sec = in->it_interval.tv_sec;
out->it_interval.tv_nsec = in->it_interval.tv_nsec;
out->it_value.tv_sec = in->it_value.tv_sec;
out->it_value.tv_nsec = in->it_value.tv_nsec;
}
uint64_t meow_time_ms_from_parts(int64_t sec, int64_t nsec)
{
return (uint64_t)sec * 1000u + (uint64_t)nsec / 1000000u;
}
/* ---- 内核取时 ---- */
int meow_time32_clock_gettime(int clk, struct meow_time32 *out)
{
if (!out) { errno = EFAULT; return -1; }
#if MEOW_TIME32_KERNEL_ABI
out->tv_sec = 0;
out->tv_nsec = 0;
if (syscall(SYS_clock_gettime32, clk, out) != 0) return -1;
return 0;
#else
struct timespec ts;
if (clock_gettime((clockid_t)clk, &ts) != 0) return -1;
out->tv_sec = (int32_t)ts.tv_sec;
out->tv_nsec = (int32_t)ts.tv_nsec;
return 0;
#endif
}
uint64_t meow_time32_monotonic_ms(void)
{
struct meow_time32 t;
if (meow_time32_clock_gettime(CLOCK_MONOTONIC, &t) != 0) return 0;
return meow_time_ms_from_parts(t.tv_sec, t.tv_nsec);
}
/* ---- 睡眠(usleep 同源受损:16 字节 time64 直接交给 time32 系统调用时 nsec 恒 0,
* 亚秒睡眠立即返回 → 轮询/退避变忙等空转)---- */
int meow_time32_sleep_us(unsigned usec)
{
#if MEOW_TIME32_KERNEL_ABI
struct meow_time32 rq, rm;
rq.tv_sec = (int32_t)(usec / 1000000u);
rq.tv_nsec = (int32_t)((usec % 1000000u) * 1000u);
for (;;) {
long r = syscall(SYS_nanosleep, &rq, &rm);
if (r == 0) return 0;
if (errno != EINTR) return -1;
rq = rm; /* 被信号打断:按剩余时间续睡 */
}
#else
struct timespec rq, rm;
rq.tv_sec = (time_t)(usec / 1000000u);
rq.tv_nsec = (long)((usec % 1000000u) * 1000u);
for (;;) {
if (nanosleep(&rq, &rm) == 0) return 0;
if (errno != EINTR) return -1;
rq = rm;
}
#endif
}
/* ---- 可选:链接期接管 libc 取时/睡眠入口 ----
* 系统组件加 -DMEOW_TIME32_LIBC_OVERRIDES 编译本文件即可让未改写的 clock_gettime()/
* usleep() 调用点也恢复正确(静态链接时本对象的强定义覆盖 libc 归档成员)。
* 不要在同时链接 meow_ui.a(meow_ui_time.o) 的进程里启用——两者符号重复。
* 与 meow_ui_time.c 的差别:这里只接管取时 + nanosleep;futex 相对超时 / timerfd /
* clock_settime 的接管仍在 meow_ui_time.c(SDK 消费方自动获得)。 */
#if MEOW_TIME32_KERNEL_ABI && defined(MEOW_TIME32_LIBC_OVERRIDES)
static int32_t meow_time32_clamp(int64_t v)
{
if (v > INT32_MAX) return INT32_MAX;
if (v < 0) return 0;
return (int32_t)v;
}
int __clock_gettime(clockid_t clk, struct timespec *ts)
{
if (!ts) { errno = EFAULT; return -1; }
struct meow_time32 t;
if (meow_time32_clock_gettime(clk, &t) != 0) return -1;
ts->tv_sec = t.tv_sec;
ts->tv_nsec = t.tv_nsec;
return 0;
}
int __clock_gettime64(clockid_t clk, struct timespec *ts)
{
return __clock_gettime(clk, ts);
}
int __clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
{
struct meow_time32 rq, rm;
long r;
if (clk == CLOCK_THREAD_CPUTIME_ID) return EINVAL;
if (!req) return EFAULT;
if (req->tv_nsec < 0 || req->tv_nsec >= 1000000000L) return EINVAL;
rq.tv_sec = meow_time32_clamp(req->tv_sec);
rq.tv_nsec = (int32_t)req->tv_nsec;
rm.tv_sec = 0;
rm.tv_nsec = 0;
if (clk == CLOCK_REALTIME && !flags)
r = syscall(SYS_nanosleep, &rq, rem ? &rm : 0);
else
r = syscall(SYS_clock_nanosleep_time32, clk, flags, &rq, rem ? &rm : 0);
if (r != 0) return errno;
if (rem) {
rem->tv_sec = rm.tv_sec;
rem->tv_nsec = rm.tv_nsec;
}
return 0;
}
int __clock_nanosleep_time64(clockid_t clk, int flags, const struct timespec *req,
struct timespec *rem)
{
return __clock_nanosleep(clk, flags, req, rem);
}
int __nanosleep_time64(const struct timespec *req, struct timespec *rem)
{
int r = __clock_nanosleep(CLOCK_REALTIME, 0, req, rem);
if (r) { errno = r; return -1; }
return 0;
}
#endif /* MEOW_TIME32_KERNEL_ABI && MEOW_TIME32_LIBC_OVERRIDES */