run.py

Example source referenced by the lesson. It does not run on this site. Learn

#!/usr/bin/env python3
"""Build, validate, and run the first lesson; Python orchestrates, C is timed."""
import pathlib
import platform
import re
import shutil
import statistics
import subprocess
import tempfile

HERE = pathlib.Path(__file__).resolve().parent

def run(args):
    return subprocess.run(args, check=True, capture_output=True, text=True,
                          timeout=15).stdout.strip()

def main():
    if not shutil.which("gcc"):
        raise SystemExit("GCC is required. Read README.md for the validated environment.")
    print("Platform:", platform.platform())
    print("Compiler:", run(["gcc", "--version"]).splitlines()[0])
    with tempfile.TemporaryDirectory(prefix="systems-unpacked-os01-") as temp:
        root = pathlib.Path(temp)
        bins = {}
        for level in ("O0", "O2"):
            exe = root / level
            flags = ["gcc", "-std=c11", "-Wall", "-Wextra", "-Werror", "-" + level]
            run(flags + [str(HERE / "main.c"), str(HERE / "work.c"), "-o", str(exe)])
            # Inspect the isolated function; no link-time optimization is enabled.
            asm = root / (level + ".s")
            run(flags + ["-S", str(HERE / "work.c"), "-o", str(asm)])
            print("\nAssembly", level, "(compiler-generated, architecture-specific):")
            print(asm.read_text())
            for n in (0, 1, 7, 1000):
                output = run([str(exe), str(n)])
                assert f"n={n} result={n} " in output, output
            for invalid in ("-1", "", "abc", "1x", "100000001"):
                result = subprocess.run([str(exe), invalid], capture_output=True,
                                        text=True, timeout=15)
                assert result.returncode == 2, result
            bins[level] = exe
        print("Correctness and input checks: PASS")
        for n in (1_000_000, 10_000_000, 50_000_000):
            samples = {level: [] for level in bins}
            for exe in bins.values():
                run([str(exe), str(n)])  # Untimed-by-the-report warm-up invocation.
            for trial in range(5):
                order = ("O0", "O2") if trial % 2 == 0 else ("O2", "O0")
                for level in order:
                    output = run([str(bins[level]), str(n)])
                    match = re.search(r"elapsed_seconds=([0-9.]+)", output)
                    assert match, output
                    samples[level].append(float(match[1]))
            for level, values in samples.items():
                print(f"n={n} {level}: samples={values}; median={statistics.median(values):.9f}s")
        print("No speed threshold is a pass condition; inspect assembly before explaining timing.")

if __name__ == "__main__":
    main()