Skip to content

Commit cbd4153

Browse files
committed
fix(mem): reconcile peak RSS with live current RSS (Linux statm vs ru_maxrss)
cbm_mem_peak_rss() returned mimalloc's peak_rss (from getrusage ru_maxrss, KB-granular) while on Linux cbm_mem_rss() reads the live /proc/self/statm value (page-granular, the RSS-undercount fallback). The two sources can disagree by a few pages, so a live current read could momentarily exceed the reported peak and break the definitional peak >= current invariant — flaking the mem_peak_rss_gte_rss test on the Linux/ARM CI leg (observed as peak 172KB under current). Reconcile the sources so the reported peak is at least the current RSS. Not observable on macOS, where both come from mimalloc. The mem_peak_rss_gte_rss guard now faults in a 32MB buffer before asserting so the invariant is checked against a non-trivial live current read. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
1 parent 9a03ed3 commit cbd4153

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

src/foundation/mem.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,17 @@ size_t cbm_mem_rss(void) {
212212
size_t cbm_mem_peak_rss(void) {
213213
size_t peak_rss = 0;
214214
mi_process_info(NULL, NULL, NULL, NULL, &peak_rss, NULL, NULL, NULL);
215+
/* Peak RSS is by definition >= current RSS. On Linux cbm_mem_rss() reads the
216+
* live /proc/self/statm value (page-granular), while mimalloc's peak_rss
217+
* comes from getrusage's ru_maxrss (KB-granular, and it can lag the live
218+
* statm read by a few pages). Reading the two sources independently lets a
219+
* fresh current read momentarily exceed the reported peak, breaking the
220+
* peak >= current invariant. Reconcile them: the true peak is at least the
221+
* current RSS. (Not observable on macOS, where both come from mimalloc.) */
222+
size_t current = cbm_mem_rss();
223+
if (current > peak_rss) {
224+
peak_rss = current;
225+
}
215226
if (peak_rss > 0) {
216227
return peak_rss;
217228
}

tests/test_mem.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,23 @@ TEST(mem_rss_positive) {
180180

181181
TEST(mem_peak_rss_gte_rss) {
182182
cbm_mem_init(0.5);
183+
/* peak >= current RSS is definitional. Regression guard for the Linux
184+
* statm-vs-ru_maxrss source mismatch: cbm_mem_rss() reads the live
185+
* /proc/self/statm value (page-granular) while mimalloc's peak comes from
186+
* getrusage ru_maxrss (KB-granular, and it lags), so a live current read
187+
* could momentarily exceed the reported peak by a few pages and break the
188+
* invariant. cbm_mem_peak_rss() now reconciles the two sources. Touch a
189+
* fresh buffer so the check runs against a non-trivial live current read.
190+
* (Linux-only bug — macOS reads both from mimalloc; it flaked on the
191+
* Linux/ARM CI leg, which is the authoritative reproduction tier.) */
192+
size_t n = 32 * 1024 * 1024;
193+
char *p = (char *)malloc(n);
194+
ASSERT_NOT_NULL(p);
195+
memset(p, 0xBE, n); /* fault in all pages so current RSS is non-trivial */
183196
size_t rss = cbm_mem_rss();
184197
size_t peak = cbm_mem_peak_rss();
185-
/* Peak must be >= current RSS */
186198
ASSERT_GTE(peak, rss);
199+
free(p);
187200
PASS();
188201
}
189202

0 commit comments

Comments
 (0)