# C++ harness sample storage before measurement

Continuing the lessons from the [llfix allocation investigation](../../../../internal/docs/bench/RECORD_2026-10-09_llfix-hp-preallocation-results.md),
the common C++ collector now reserves its predictable sample storage before
measurement. Java and .NET already allocate their main sample arrays up front.
This is framework software qualification on BEELINK2, not new engine timing.

## Source change

`HftBenchContext::ReserveSamples(name, count)` reserves a named probe without
recording, clearing or shrinking it. `ReserveRegisteredSamples(count)` covers
every existing probe, retaining any larger task-specific budget. Cached probe
handles remain valid because they point to the vector object, not its storage.
Unexpected extra observations still grow the vector and remain available for
count audits. No clipping, saturation or sample-width change is introduced.

Before each ready barrier, the runner reserves `measuredIterations` samples
for the end-to-end and adaptive probes and, when paced, scheduler delay. The
new cold `BenchTask::PrepareMeasuredRun` hook registers/caches extra probes or
reserves custom larger budgets. The runner then reserves all registered probes.
Preparation runs after warmup drain/reset, while sampling is disabled, before
the ready barrier and measured wall/CPU clocks. Existing `StartMeasuredRun`
remains inside the measured window.

The append methods, pacing/iteration loop and CPU-clock helper are byte-identical
to baseline private main `3ed28ff01`. Engine allocation, store/journal behavior,
clock conversion, sample boundaries, adaptive gates and raw output remain in
their original scopes. A task registering an unknown probe during measurement
can still allocate. Reservation does not prefault all pages and is not an
allocation-free guarantee for engine workloads.

## Verification

Local GCC 15.2.0, `-O3 -std=c++11 -Wall -Wextra -Werror`, maximum two parallel
compilers, no concurrent heavy build observed. All four framework binaries
pass in the development layout. A fresh 17-file standalone framework selection
with no `.git`, engine or root `toolchain.mk` builds and passes the same four
binaries, with outputs outside its source tree. No tests are skipped.

The new sample-storage binary has seven cases:

- Unreserved append detects actual vector-growth allocations and retains values.
- Explicit reservation preserves cached handles, reset capacity and full-width
  `uint64_t` values, with zero append-scope allocations inside the budget.
- Deliberate overflow allocates and retains every extra sample instead of dropping it.
- Zero-warmup paced, zero-warmup closed-loop, nonzero-warmup paced and adaptive
  repeated runs exercise cold preparation and exact sample retention.

The four runner cases execute eight runs / 32,768 iterations and retain 221,184
synthetic measured samples. Global allocation replacements detect **zero
allocations in each prepared measured loop**, while both growth controls detect
allocations. Long custom probe names, two samples per iteration, warmup/setup
exclusion, per-run resets, scheduler counts and original 64-bit sample values
are checked. The three pre-existing test source files remain unchanged.

The first successful six-case run is retained; the final seven-case run adds
the unreserved-growth control. Public scan: four files, zero findings.
[The verification record](evidence/cpp-sample-storage-20261010/verification.json)
binds 18 source/support inputs, compiler identity/flags and both sets of four
binaries. [The verifier](evidence/cpp-sample-storage-20261010/verify.py) checks
input bytes/modes, measured-method identity and cold setup/barrier/clock order.
The [standalone input manifest](evidence/cpp-sample-storage-20261010/standalone-inputs.json)
retains the exact source mapping.

## Generation scope

New harness source requires a fresh build/preparation and its own qualification.
Old llfix reference overlays, installed payloads, prepared source capsules,
Stage 2 campaigns, rankings and sealed evidence keep their original pins.
No SDK source, comparator driver, canonical workload, shared Python clock/build/
layout API, OS setting or other owner's host job is changed. No SDK, physical,
timing, report or release admission follows from these framework tests.
