Skip to content

Commit 60e1769

Browse files
authored
Merge pull request DeusData#866 from DeusData/fix/mem-peak-rss-invariant
fix(mem): reconcile peak RSS with live current RSS (Linux statm vs ru_maxrss)
2 parents 9ebe206 + cbd4153 commit 60e1769

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)