Budget the sample buffer in samples per signal, under a hard memory limit

--buffer-samples (k/M/G) replaces --buffer-mb: the request is rounded down to a
power of two for every signal and the shared time ring. A separate memory limit
(--memory-limit-mb, a Preferences row, default 8 GiB) halves the plan until the
real ring bytes fit and says so on stderr and in the status line. The per-source
key buffer_mb becomes buffer_samples; an old buffer_mb is ignored.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-11-03 02:47:04 +01:00
1 parent 616cde5b13
commit 034c82f7d7
20 files changed
+516 -134

No files matched your search

+5 -4
View File
@@ -1182,7 +1182,7 @@ gboolean math_probe(gpointer user) {
// The one state `math_probe` structurally cannot reach: an edit of a graph whose ring has already
// *wrapped*. Every edit that probe makes follows a structural change, which replans the buffer and
// restarts every ring at absolute 0 -- and at `base == 0` the recompute's two renumbering bugs are
// both identities. Run it with a small `--buffer-mb` and give it time to saturate; `base=0` in its
// both identities. Run it with a small `--buffer-samples` and give it time to saturate; `base=0` in its
// second line means the run was too short or the buffer too large to have read anything.
int g_mathwrap_index = -1;
double g_mathwrap_y_before = 0.0;
@@ -1231,7 +1231,7 @@ gboolean mathwrap_probe_wait(gpointer user) {
g_mathwrap_y_before = a->model->live().channel(idx).y_bounds().max;
}
}
// Polled rather than timed: the wrap is a function of the rate and of `--buffer-mb`, and a fixed
// Polled rather than timed: the wrap is a function of the rate and of `--buffer-samples`, and a fixed
// delay that fell short would print a passing line having tested nothing.
if (base == 0 && ++g_mathwrap_polls < 200) return G_SOURCE_CONTINUE;
std::fprintf(stderr, "[mathwrap-probe] wrapped: base=%llu slots=%llu (want base > 0)\n",
@@ -5384,9 +5384,10 @@ gboolean configs_probe(gpointer user) {
const double noise_back = st.measures.empty() ? -1.0 : st.measures.front().options.noise_pct;
const double hf_back = st.measures.empty() ? -1.0 : st.measures.front().options.hf_fc;
std::fprintf(stderr,
"[configs] round trip read=%d comment='%s' buffer_mb=%.6g relative=%d "
"[configs] round trip read=%d comment='%s' buffer_samples=%llu relative=%d "
"capture=%u plots=%zu signals=%d measures=%zu math=%zu noise=%.6g hf=%.6g\n",
read ? 1 : 0, st.comment.c_str(), st.buffer_mb, st.relative_time ? 1 : 0,
read ? 1 : 0, st.comment.c_str(),
static_cast<unsigned long long>(st.buffer_samples), st.relative_time ? 1 : 0,
st.capture_packets, st.rows.size(), signals, st.measures.size(), st.math.size(),
noise_back, hf_back);