/* bench/mem_watch_sim.c — 宿主「边播监控取证」阈值/峰值验证(agent 32bit OOM 取证)。 * * 归属演进(2026-09-02 定案,ARCHITECTURE_PRINCIPLES ③混合):**降载决策上收通用层**—— * A + C 分别归 SDK meow_cachegov / meow_svc_perf;本 sim 只验证 mem_watch 的**取证**语义: * 三档 level 标注滞回(normal→high→critical→滞回→normal)+ song_end 重置峰值 + song_begin 起算。 * (旧版「dl_paused/prefetch_paused 降载断言」已随降载上收移除——那由 meow_cachegov_sim * 与 svc_perf test_cachegov_monitor 覆盖。) * * 依赖:仅 app/play/mem_watch.c(+ meow_log 桩)。 * 编译(ncm_app 目录下): * gcc -O2 -Wall -Wextra -DJSMN_HEADER -I. -I../sdk -I../meow_launcherd \ * -c bench/mem_watch_sim.c -o /tmp/mw.o * gcc -O2 -Wall -Wextra -I. -I../sdk -c app/play/mem_watch.c -o /tmp/mw_mod.o * gcc -O2 -o mem_watch_sim /tmp/mw.o /tmp/mw_mod.o -lpthread -lm * 运行:./mem_watch_sim (exit 0=PASS / 1=FAIL) */ #include "../app/play/mem_watch.h" #include #include #include #include #include /* meow_log 桩:打印(便于看阈值过渡;sim 仅验证 mem_watch 逻辑,非真实日志系统) */ void meow_log(int lvl, const char *fmt, ...) { (void)lvl; char b[256]; va_list ap; va_start(ap, fmt); vsnprintf(b, sizeof b, fmt, ap); va_end(ap); printf(" [mem.log] %s\n", b); } static int fails; #define CHECK(cond, msg) do { \ if (!(cond)) { printf("FAIL %s\n", msg); fails++; } \ else { printf("ok %s\n", msg); } } while (0) /* 等监控线程至少走过 2 个周期(feed 后确保已采样) */ static void settle_ms(int m) { usleep((useconds_t)m * 1000u); } int main(void) { /* 用 env 设定短周期(50ms)与干净阈值,加速确定性判定 */ setenv("NCM_MEM_WATCH_PERIOD_MS", "50", 1); setenv("NCM_MEM_WATCH_HIGH_KB", "30720", 1); /* 30MB */ setenv("NCM_MEM_WATCH_LOW_KB", "20480", 1); /* 20MB */ setenv("NCM_MEM_WATCH_CRITICAL_KB", "40960", 1); /* 40MB */ if (mem_watch_start() != 0) { printf("FAIL mem_watch_start\n"); return 1; } printf("started (period=50ms H=30M L=20M C=40M)\n"); /* 1) 正常区 */ mem_watch_set_forced_kb(10000); settle_ms(150); CHECK(mem_watch_level() == NCM_MEM_LVL_NORMAL, "level==NORMAL @10MB"); /* 2) 升到 HIGH */ mem_watch_set_forced_kb(35000); settle_ms(150); CHECK(mem_watch_level() == NCM_MEM_LVL_HIGH, "level==HIGH @35MB"); /* 3) 升到 CRITICAL */ mem_watch_set_forced_kb(45000); settle_ms(150); CHECK(mem_watch_level() == NCM_MEM_LVL_CRITICAL, "level==CRITICAL @45MB"); /* 4) 滞回:落在 LOW..HIGH 之间 -> 保持 CRITICAL(防抖动) */ mem_watch_set_forced_kb(25000); settle_ms(150); CHECK(mem_watch_level() == NCM_MEM_LVL_CRITICAL, "level stays CRITICAL @25MB (hysteresis)"); /* 5) 回到正常:低于 LOW -> NORMAL */ mem_watch_set_forced_kb(15000); settle_ms(150); CHECK(mem_watch_level() == NCM_MEM_LVL_NORMAL, "level==NORMAL @15MB"); /* 6) 调度器释放钩子:song_end 重置峰值 + song_begin 起算 + rss_anon 反映注入值 */ mem_watch_set_forced_kb(20000); settle_ms(100); mem_watch_song_begin(); mem_watch_set_forced_kb(37000); /* 本曲峰值冲到 37MB */ settle_ms(100); long anon = mem_watch_rss_anon_kb(); CHECK(anon == 37000, "rss_anon_kb reflects forced value"); mem_watch_song_end(); /* 释放钩子:落峰值+重置 */ settle_ms(100); mem_watch_song_begin(); mem_watch_set_forced_kb(12000); /* 新曲:峰值应从新起算 */ settle_ms(100); CHECK(mem_watch_level() == NCM_MEM_LVL_NORMAL, "after song_end+begin, level resets to NORMAL"); mem_watch_stop(); printf("mem_watch_sim: %s\n", fails ? "FAIL" : "PASS"); return fails ? 1 : 0; }