DF-2712 / df2712_bench.c
/* * df2712_bench.c -- scheduler sanity microbench for DF-2712 fix validation. * * Measures, in order: * 1. single-thread sched_yield() rate over 2 s * 2. fork/exit x 64 * 3. pipe round-trip latency x 20000 (2 procs) * Prints one line per metric. Run identically on baseline and fixed * kernels; scheduling must keep functioning after the deferred-kick fix. */ #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sched.h> static double now(void) { struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return ts.tv_sec + ts.tv_nsec / 1e9; } int main(void) { volatile unsigned long n; double t0, t1; unsigned long it = 0; int i, pfd[2]; char c = 'x'; pid_t pid; /* 1. yield rate */ n = 0; t0 = now(); while (now() - t0 < 2.0) { n += sched_yield(); ++it; } t1 = now(); printf("YIELD-RATE %.0f /s\n", (double)it / (t1 - t0)); /* 2. fork/exit */ t0 = now(); for (i = 0; i < 64; ++i) { pid = fork(); if (pid == 0) _exit(0); waitpid(pid, NULL, 0); } t1 = now(); printf("FORK64 %.3f s\n", t1 - t0); /* 3. pipe round-trip */ if (pipe(pfd) < 0) { perror("pipe"); return 1; } pid = fork(); if (pid == 0) { for (i = 0; i < 20000; ++i) { if (read(pfd[0], &c, 1) != 1) _exit(1); if (write(pfd[1], &c, 1) != 1) _exit(1); } _exit(0); } t0 = now(); for (i = 0; i < 20000; ++i) { if (write(pfd[1], &c, 1) != 1) break; if (read(pfd[0], &c, 1) != 1) break; } t1 = now(); waitpid(pid, NULL, 0); printf("PIPERT %.2f us/rt\n", (t1 - t0) * 1e6 / 20000.0); printf("BENCH-DONE\n"); return 0; } |