Files
AskaEth 3d70a3dd2c feat: M6.10–M6.19 批量收编 + M6.19 推卡验收
- M7 launcher 重写 5 期(虚拟化宫格/meow_theme 单一权威/横幅动画/自定义 PIN 键盘)
- OOM 通用化(cachegov 上收 SDK)、自动切歌根治、meowpanel jv_free 泄漏修复、Hello 滚动卡顿修复
- ncm 歌词 UI / 媒体通知封面 / 封面分辨率 640
- 5 bug 修复:ncm 后台化 UI 叠层+点击穿透、再进 ncm 桌面叠层、播放页新旧 UI 叠层抢刷脏区(meow_ui_gfx 恢复边沿整帧重画)、PIN 亮屏亮度跳(keys.c meow_panel_on 按 settings_brightness_clamped 恢复)、通知中心封面显歌单封面(cover.c save_cover_raw 加 is_song + 命中块守卫)
- 四 App 统一重链新 meow_ui.a 51caee4a;M6.19=0.8.19 固件 2d2331f2 推卡自刷验收全绿
2026-09-03 12:16:01 +08:00

121 lines
5.2 KiB
C
Raw Permalink 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.
/* bench/mem_release_sim.c — 宿主「彻底释放」路径验证(agent 32bit OOM 专项)。
*
* 目的:验证「32bit(>16bit)→S32 解码 播完/切歌 是否真正释放」——ncm_dec_open(整文件)→
* ncm_dec_read 全量(dr_flac S32 满幅路径)→ ncm_dec_close(dr_flac_close + stream_src_close)
* 循环 N 次,断言进程匿名 RSS(RssAnon,OOM 高危口径)**不单调累积**(播完回落基线),
* 且解码中峰值有界(32bit 解码缓冲存在但有限,非 40MB 级)。
*
* 依赖:仅 app/play 解码层(decoder.c + stream_src.c + dr_flac_impl + minimp3_impl),
* 无 core/SDK/app.c——本 sim 是解码链路的最小区块,直接量「解码器 buff 播完 free」。
* 编译(ncm_app 目录下):
* gcc -O2 -Wall -Wextra -DJSMN_HEADER -I. -Icore -I../sdk -I../meow_launcherd \
* -Ivendor/jsmn -Ivendor/minimp3 -Ivendor/dr_flac -Ivendor/mbedtls/include \
* -c bench/mem_release_sim.c -o /tmp/mr.o
* gcc -O2 -Wall -Wextra ... -c app/play/stream_src.c -o /tmp/mr_ss.o
* gcc -O2 -Wall -Wextra ... -c app/play/decoder.c -o /tmp/mr_dec.o
* gcc -O2 -c -Ivendor/minimp3 app/play/minimp3_impl.c -o /tmp/mr_mp3.o
* gcc -O2 -c -Ivendor/dr_flac app/play/dr_flac_impl.c -o /tmp/mr_flac.o
* gcc -O2 -o mem_release_sim /tmp/mr.o /tmp/mr_ss.o /tmp/mr_dec.o /tmp/mr_mp3.o /tmp/mr_flac.o -lpthread -lm
* 运行:./mem_release_sim <flac 24bit 路径> [iters] (iters 默认 5)
* 断言(PASS 才 exit 0):
* - RssAnon[最后] - RssAnon[基准] < 256KB(播完回落,无累积);
* - 解码中峰值有界(peak - 基准 < 8MB,32bit 解码缓冲不是 40MB 级);
* - 总帧数 > 0 且 bits==32(确实走了 S32 满幅路径——本 sim 只受 24bit 输入触发)。
*/
#include "../app/play/decoder.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define READ_CHUNK_FRAMES 4096
#define ITER_DEFAULT 5
#define SETTLE_TOLERANCE_KB (256) /* 播完回落允许抖动(<256KB 视为无累积) */
#define PEAK_BOUND_KB (8 * 1024) /* 解码中峰值必须 <8MB(区别于 40MB 级异常) */
/* 静默 meow_log(本 sim 不链 core;decoder/stream_src 不调它,仅占位防漏链) */
void meow_log(int lvl, const char *fmt, ...) { (void)lvl; (void)fmt; }
static long rss_anon_kb(void)
{
FILE *f = fopen("/proc/self/status", "r");
if (!f) return -1;
char line[256];
long v = -1;
while (fgets(line, sizeof line, f))
if (!strncmp(line, "RssAnon:", 8)) { v = atol(line + 8); break; }
fclose(f);
return v;
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("usage: mem_release_sim <flac_path> [iters]\n");
return 2;
}
const char *path = argv[1];
int iters = (argc > 2) ? atoi(argv[2]) : ITER_DEFAULT;
if (iters < 2) iters = 2;
long base = rss_anon_kb();
if (base < 0) { printf("FAIL cannot read RssAnon\n"); return 1; }
printf("mem_release[0] baseline RssAnon=%ldKB\n", base);
int first_dec_ok = 0;
long prev_after = 0, last_after = 0; /* 最近两次播完 close 后的 RssAnon */
for (int i = 0; i < iters; i++) {
ncm_decoder_t *dec = NULL;
int rate = 0, ch = 0, bits = 0;
int64_t tf = 0;
if (ncm_dec_open(&dec, path, &rate, &ch, &bits, &tf) != 0) {
printf("FAIL iter%d ncm_dec_open (%s)\n", i, path);
return 1;
}
if (i == 0) {
printf("mem_release: fmt=%s %dHz/%dch/%dbit total_frames=%lld (S32 path=%d)\n",
ncm_dec_format(dec), rate, ch, bits, (long long)tf, bits > 16);
first_dec_ok = 1;
}
/* 全量读(S32 满幅路径),测解码中匿名峰值 */
static int32_t buf[READ_CHUNK_FRAMES * 2];
long peak = 0;
int64_t frames = 0, got = 0;
do {
got = ncm_dec_read(dec, buf, READ_CHUNK_FRAMES);
frames += got;
long r = rss_anon_kb();
if (r > peak) peak = r;
} while (got > 0);
printf("mem_release[%d] after decode: frames=%lld peak_RssAnon=%ldKB\n",
i + 1, (long long)frames, peak);
ncm_dec_close(dec); /* drflac_close + stream_src_close(整文件静态源) */
long r = rss_anon_kb();
prev_after = last_after;
last_after = r;
printf("mem_release[%d] after close RssAnon=%ldKB (delta=%ldKB)\n",
i + 1, r, r - base);
/* 解码中峰值有界:32bit 解码缓冲不是 40MB 级 */
if (peak - base > PEAK_BOUND_KB) {
printf("FAIL iter%d decode peak %ldKB - base %ldKB = %ldKB > %dKB (异常高)\n",
i, peak, base, peak - base, PEAK_BOUND_KB);
return 1;
}
}
/* 累积断言:最后两次播完后的 RssAnon 相对基线的增量都 < 容忍(无单调上升) */
long d1 = last_after - base;
long d2 = prev_after - base;
int no_accum = (d1 < SETTLE_TOLERANCE_KB) && (d2 < SETTLE_TOLERANCE_KB);
printf("mem_release: settle delta last=%ldKB prev=%ldKB -> %s\n",
d1, d2, no_accum ? "PASS(无累积)" : "FAIL(有残留)");
int ok = first_dec_ok && no_accum;
printf("mem_release: %s\n", ok ? "PASS" : "FAIL");
return ok ? 0 : 1;
}