Adds a OnceLock<Mutex<HashSet>> cache in tuning.rs. inference_thread_count
now emits a single tracing::info! line the first time each
(workload, on_battery, gpu_offloaded) tuple is seen in the process,
recording the resolved thread count and which clamps fired (battery, gpu).
Also derives Hash on Workload and tightens the GPU clamp to only record
the "gpu" clamp when it actually reduces chosen. Smoke test added.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds battery-state awareness to the thread-count helper: when
probe_power_state() returns OnBattery, chosen is halved before the
[MIN, MAX] clamp. Also removes the leading underscore from the
workload/gpu_offloaded parameters (they are silenced via let _ = ...
until the GPU-clamp task).
New test battery_halves_thread_count verifies on_battery <= on_ac and
>= MIN when the host has more than MIN physical cores. Restructured
to sequential with_override calls (not nested) to avoid re-entrant
deadlock on power::TEST_LOCK.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without a lock, env_var_bypasses_clamps (set_var + remove_var) and
matches_existing_clamp_when_no_clamps_apply (remove_var) race under
cargo's parallel test runner. Task 2.2 will add another remove_var
call, compounding the race.
Adds a #[cfg(test)] static THREAD_ENV_LOCK and a closure-style
with_thread_env_lock helper, mirroring power::with_override.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds crates/core/src/tuning.rs with MIN/MAX_INFERENCE_THREADS consts,
Workload enum (Llm/Whisper), and inference_thread_count() helper matching
the existing constants::inference_thread_count clamp behaviour. Three unit
tests pass. tracing dep added to Cargo.toml (used by future tasks).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>