Skip to main content

kevy_embedded/
config_tier.rs

1//! The tiering budget spec — split out of
2//! [`crate::config`] for the 500-LOC house rule. Mirrors the server's
3//! `[tiering] budget` forms; resolution happens at open and re-runs on
4//! every reaper tick for the probe-backed forms.
5
6/// One transparent-tiering RAM budget, as configured. Resolution to
7/// bytes probes the OS memory bound through `kevy-sys` (the sanctioned
8/// boundary).
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum TierBudgetSpec {
11    /// 0.70 × the detected memory bound (cgroup v2 `memory.max` /
12    /// `/proc/meminfo MemAvailable` on Linux; `hw.memsize` on macOS).
13    Auto,
14    /// That percent of the detected bound (validated 1..=100 at open).
15    Percent(u8),
16    /// Absolute bytes.
17    Bytes(u64),
18}
19
20#[cfg(not(target_arch = "wasm32"))]
21impl TierBudgetSpec {
22    /// The `auto` form's fraction of the detected bound (RFC §7: 0.70).
23    const AUTO_PCT: u64 = 70;
24
25    /// Resolve to bytes. `None` = the probe found no bound (the open
26    /// path turns that into a named error, never a silent off).
27    pub(crate) fn resolve(self) -> Option<u64> {
28        match self {
29            Self::Bytes(b) => Some(b),
30            Self::Auto => probe().map(|d| d / 100 * Self::AUTO_PCT),
31            Self::Percent(p) => probe().map(|d| d / 100 * u64::from(p)),
32        }
33    }
34}
35
36/// The OS memory-bound probe. On wasm32 there is no OS to ask (and
37/// kevy-sys never links there): auto/percent budgets resolve to `None`,
38/// which the open path reports as a named error.
39#[cfg(not(target_arch = "wasm32"))]
40fn probe() -> Option<u64> {
41    kevy_sys::detected_memory_bound()
42}