| 123 | /* ── Pressure logging (hysteresis) ────────────────────────────── */ |
| 124 | |
| 125 | static void check_pressure(size_t rss) { |
| 126 | if (g_budget == 0) { |
| 127 | return; |
| 128 | } |
| 129 | |
| 130 | bool over = rss > g_budget; |
| 131 | int was = atomic_load(&g_was_over); |
| 132 | |
| 133 | if (over && !was) { |
| 134 | atomic_store(&g_was_over, 1); |
| 135 | char rss_mb[CBM_SZ_32]; |
| 136 | char budget_mb[CBM_SZ_32]; |
| 137 | char pct_str[CBM_SZ_16]; |
| 138 | snprintf(rss_mb, sizeof(rss_mb), "%zu", rss / MB_DIVISOR); |
| 139 | snprintf(budget_mb, sizeof(budget_mb), "%zu", g_budget / MB_DIVISOR); |
| 140 | snprintf(pct_str, sizeof(pct_str), "%zu", |
| 141 | g_budget > 0 ? (rss * CBM_PERCENT) / g_budget : 0); |
| 142 | cbm_log_warn("mem.pressure.warn", "rss_mb", rss_mb, "budget_mb", budget_mb, "pct", pct_str); |
| 143 | } else if (!over && was) { |
| 144 | atomic_store(&g_was_over, 0); |
| 145 | char rss_mb[CBM_SZ_32]; |
| 146 | char budget_mb[CBM_SZ_32]; |
| 147 | char pct_str[CBM_SZ_16]; |
| 148 | snprintf(rss_mb, sizeof(rss_mb), "%zu", rss / MB_DIVISOR); |
| 149 | snprintf(budget_mb, sizeof(budget_mb), "%zu", g_budget / MB_DIVISOR); |
| 150 | snprintf(pct_str, sizeof(pct_str), "%zu", |
| 151 | g_budget > 0 ? (rss * CBM_PERCENT) / g_budget : 0); |
| 152 | cbm_log_info("mem.pressure.ok", "rss_mb", rss_mb, "budget_mb", budget_mb, "pct", pct_str); |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | /* Allocator setup is not best-effort. A misconfigured allocator does not |
| 157 | * degrade gracefully — it grows without bound until the OS kills the process |
no outgoing calls
no test coverage detected