← 都来码 / Dolaima← 例程索引c/test/sleep_api.c原文

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;
}