c/test/sleep_api.c · 2232 字节 · 下载原文
/* sleep_api.c —— `sleep` 的**单位**判据(`builtins.c` 毫秒版 vs `dos.c` 秒版)。
* sleep_api.c — criterion for `sleep`'s **unit**.
*
* ## 背景
* ## Background
*
* `sleep` 这个名字在本仓有**两份**定义、单位差 1000 倍:`builtins.c` 的 `sleep(int ms)`
* (现代 API 的真身)与 `dos.c` 的 `sleep(unsigned seconds)`(服务老 DOS 程序)。
* 链接器对重名裸标签是**后链的赢、且不报错** ⇒ 拿秒当毫秒用的是"瞬间返回"、
* 反过来是"卡住 1000 倍那么久"。
*
* 2026-10-08:老 DOS 那份改名 **`sleep_sec`**,`sleep` 只留毫秒版。
*
* ## 判据
* ## Criteria
*
* ⚠ 这条**量的是时间**(不是返回值)—— 这是唯一能钉住"单位"的量法:
* `sleep(1)` 毫秒版应立刻回来;若绑到秒版会睡足 **1000ms**。阈值取 200ms,
* 两边(1ms vs 1000ms)都离得很远,不受调度抖动影响。
*
* 跑法(桌面,秒级):
* dotnet scripts/vmlcli/bin/Release/net10.0/vmlcli.dll third_party/vml/Examples/c/test/sleep_api.c
*/
#include <dos.h> /* `sleep_sec` 在 dos.vml 里 —— 它**不在**默认链接集(老程序兼容层),
* 而这个头带着 `#param lib("dos")`,include 它就链得上 */
void sleep(int ms);
int get_tick(void);
int fails = 0;
int main(void) {
int t0;
int dt;
t0 = get_tick();
sleep(1);
dt = get_tick() - t0;
if (dt < 200) {
printf("OK sleep(1) 是毫秒版(dt=%dms)\n", dt);
} else {
printf("FAIL sleep(1) 疑似绑到秒版:dt=%dms(应为个位数毫秒)\n", dt);
fails = fails + 1;
}
/* `sleep_sec(0)` 应立即返回(它内部 delay(0))—— 顺带证明这个名字**链得上** */
t0 = get_tick();
sleep_sec(0);
dt = get_tick() - t0;
if (dt < 200) {
printf("OK sleep_sec(0) 链得上且立即返回(dt=%dms)\n", dt);
} else {
printf("FAIL sleep_sec(0) 异常:dt=%dms\n", dt);
fails = fails + 1;
}
printf("SLEEP_API %s (fails=%d)\n", fails == 0 ? "PASS" : "FAIL", fails);
return fails;
}