Skip to content

proven_c_lib-v0.3.0

Choose a tag to compare

@rubidus-api rubidus-api released this 29 Sep 14:45
· 41 commits to main since this release

A MINOR release: nothing public removed, one build profile added, and one profile's behaviour
changed on purpose. ./nob release now defines NDEBUG, so pool and map misuse checks are out
of release builds (pool teardown was quadratic with them), and the new ./nob hardened keeps them
in an optimised build (B-036). find_last makes the forward search's choices, and its quadratic
tail is gone (B-024). The freestanding runtime contract is stated and link-proven (B-034). ./nob cross reports every target and cannot skip the mandatory ones (B-035). Benchmarks share one row
format and back the published numbers (B-037, B-038). The build rebuilds exactly what a header
change touched, and ./nob clean removes the selected build root safely (B-036). English public
text is ASCII, and a gate keeps it that way.

Added

  • One benchmark row format, and the benchmarks behind the published numbers (B-037, B-038).
    tests/proven_bench.h: warmup, five samples on a monotonic clock, median, spread, raw samples,
    checksum, compiler and profile on one line; every registered benchmark uses it. New
    tests/test_bench_float_host.c (the float-vs-glibc comparison, now checked in, with accuracy
    asserted in the same run) and tests/test_bench_job.c (idle CPU for 1-32 workers, idle / burst
    / saturated wake latency, throughput). Raw results and a claim-to-row map in
    the maintainers' benchmark records, with the job system's latency budget.

Changed

  • The build rebuilds exactly what a change touched (B-036). Objects and test executables are
    built with compiler dependency files (-MMD); the cache key is the exact compile or link command
    plus the contents of every file the dependency file names. Editing include/proven/job.h now
    recompiles job.c alone (1 of 36 objects; the tests relink because they link every object), and
    editing manual/examples/example.h relinks the 92 examples that include it and nothing else -
    before, any header edit rebuilt everything. A missing dependency file means a rebuild, never a
    stale cache hit. The test cache hash is now taken from the exact link command (it used to be a
    hand-kept copy that differed from it), and -ldl is linked only into the test that interposes
    libc with dlsym(RTLD_NEXT, ...) instead of every POSIX test (B-035). The first build after
    updating rebuilds everything once.
  • ./nob clean removes the selected build root, safely (B-036). It honours -build-root and
    PROVEN_BUILD_ROOT instead of always running rm -rf build / rmdir /s /q build through the
    shell, deletes without following symlinks or junctions, refuses ., /, any .. component
    and unusual characters, and removes a root other than the default build only when it carries
    the .proven-build-root marker nob now writes into every build root it creates. Compatibility
    note: a custom build root created by an older nob has no marker, so clean refuses it once
    with a hint; remove it by hand or build into it again first. As for building, a root with a
    drive letter or backslashes (C:\...) is refused; on Windows use a relative root. The Windows
    deletion path is compiled with mingw-w64 (x86-64, i686) but not yet run on Windows.
  • The job system's wake-latency budget states its condition (B-041). The Windows idle-wake p99
    of ~8.9 ms was traced with b041-wake-probe.c: a bare OS semaphore shows the same tail
    whenever CPUs are scarce (the 2-vCPU VM; Linux pinned to 2 CPUs), and neither shows it on a
    quiet 16-CPU host. The job system adds ~1 us at the median. No library change; the budget in
    the job budget in the maintainers' benchmark records now says it assumes free CPUs, and test_bench_job prints the
    host's logical CPU count.
  • ./nob release defines NDEBUG; new ./nob hardened keeps the checks (B-036).
    Compatibility note: a release build no longer traps a pool double free or a foreign pointer, or
    the map's key-overlap misuse - those checks are for debug and hardened builds. They made pool
    teardown quadratic: 20,000 frees took 59.6 ms with the check, 0.05 ms without
    (b036-pool-teardown-benchmark.c). Build with hardened (-O2 -DNDEBUG -DPROVEN_HARDENED=1) to keep them in an optimised build, and use alloc_check.h in tests.
    Every build now logs its safety profile.
  • Published float speed claims follow the checked-in benchmark. Re-measured: parsing is
    faster than glibc on short numbers, level at ~16 digits, ~1.1x slower at 17; shortest formatting
    ~3.6x faster than %.17g; %f/%e faster at every magnitude measured - the June claim that
    they were 3-5x slower at extreme magnitudes did not reproduce. README (both), the float doc and
    primitives-benchmark.md updated.
  • English public text is ASCII, and stays so (B-036). README.md, TEST.md, CHANGELOG.md, the
    English manual and examples, and all C sources and build files were normalised (em dashes,
    section signs, arrows and the like; 48 files), with the Markdown anchors of changed headings
    updated. scripts/ascii_policy.py check, run by project-check, fails on any new non-ASCII byte
    in that scope; Hangul is exempt, and the Korean mirrors are out of scope.
  • ./nob cross reports every target and cannot skip the ones a release needs (B-035). Each
    target ends PASS, FAIL or SKIP with a reason, a failure no longer stops the other targets, and a
    summary is printed. Skipping native-gcc-hosted, native-clang-hosted, windows-x86_64-winapi
    or windows-i686-winapi fails the run; before, a run that skipped nine of eleven targets
    finished green.
  • The freestanding runtime contract is explicit and linked (B-034). A freestanding build needs
    memcpy, memmove, memset, memcmp and the compiler support library, nothing else - stated
    in the freestanding guide and proven by a new ./nob cross stage that links every freestanding
    object with a program supplying only those four (-nostdlib -nostartfiles -static -lgcc) for
    Cortex-M4 and RISC-V. float_format.c no longer calls strlen, which was the one dependency
    outside that set.
  • proven_u8str_view_find_last makes the forward search's choices (B-024). The same entropy
    sample; an anchored backward scan over a new portable proven_sys_mem_rchr on ordinary input;
    backward Shift-Or (<= 64 bytes) or a new reverse Two-Way (> 64) on low-entropy input. Measured
    with b024-find-last-benchmark.c: about 5x faster on ordinary text for 2-64 byte needles
    (0.30 -> 0.055 ns/byte), and the long-needle quadratic tail is gone (a 256-byte needle on a dense
    run: 1,994 -> 0.002 ns/byte). Long needles on ordinary text are slower (0.022 -> 0.055), the price
    of a portable backward scan. Results unchanged: the oracle agrees on 120,000 cases.

Fixed

  • tests/test_regression_fs_perms_and_types builds with clang. It passed _Atomic int
    objects to the GCC __atomic_*_n builtins, which clang rejects; it now uses <stdatomic.h>
    atomic_load_explicit / atomic_store_explicit. The full hosted suite passes under clang.