fix: a truncated scan stays truncated, so a hit list with a hole is not reported clean

This commit is contained in:
Martino Ferrari committed 2026-10-08 10:03:46 +02:00
1 parent 415fceca87
commit 8ee4effb70
3 files changed
+8 -7

No files matched your search

+7 -5
View File
@@ -37,6 +37,7 @@ void BufferSearch::cancel() noexcept {
void BufferSearch::clear() noexcept { void BufferSearch::clear() noexcept {
state_ = State::Idle; state_ = State::Idle;
started_ = false; started_ = false;
truncated_ = false;
at_ = 0; at_ = 0;
end_ = 0; end_ = 0;
first_s_ = 0.0; first_s_ = 0.0;
@@ -74,7 +75,6 @@ bool BufferSearch::prev() noexcept {
bool BufferSearch::pump(ScopeModel& model) { bool BufferSearch::pump(ScopeModel& model) {
if (state_ != State::Running) return false; if (state_ != State::Running) return false;
const auto chunk_t0 = std::chrono::steady_clock::now(); const auto chunk_t0 = std::chrono::steady_clock::now();
bool truncated = false;
u64 n = 0; u64 n = 0;
{ {
std::lock_guard<std::mutex> lock(model.mutex()); std::lock_guard<std::mutex> lock(model.mutex());
@@ -108,11 +108,11 @@ bool BufferSearch::pump(ScopeModel& model) {
const u64 base = store.time().base(); const u64 base = store.time().base();
if (base > at_) { if (base > at_) {
at_ = base; at_ = base;
truncated = true; truncated_ = true;
detector_.reset(); // the sequence has a gap in it; no pulse spans it detector_.reset(); // the sequence has a gap in it; no pulse spans it
} }
if (at_ >= end_) { if (at_ >= end_) {
state_ = truncated ? State::Truncated : State::Done; state_ = truncated_ ? State::Truncated : State::Done;
total_ms_ += ms_since(chunk_t0); total_ms_ += ms_since(chunk_t0);
return false; return false;
} }
@@ -133,7 +133,9 @@ bool BufferSearch::pump(ScopeModel& model) {
scanned_s_ = t - first_s_; scanned_s_ = t - first_s_;
state_ = State::Capped; state_ = State::Capped;
++chunks_; ++chunks_;
total_ms_ += ms_since(chunk_t0); const double cost = ms_since(chunk_t0);
if (cost > worst_chunk_ms_) worst_chunk_ms_ = cost;
total_ms_ += cost;
return false; return false;
} }
} }
@@ -145,7 +147,7 @@ bool BufferSearch::pump(ScopeModel& model) {
if (cost > worst_chunk_ms_) worst_chunk_ms_ = cost; if (cost > worst_chunk_ms_) worst_chunk_ms_ = cost;
total_ms_ += cost; total_ms_ += cost;
if (at_ >= end_) { if (at_ >= end_) {
state_ = truncated ? State::Truncated : State::Done; state_ = truncated_ ? State::Truncated : State::Done;
return false; return false;
} }
return true; return true;
+1
View File
@@ -81,6 +81,7 @@ class BufferSearch {
int channel_ = -1; int channel_ = -1;
State state_ = State::Idle; State state_ = State::Idle;
bool started_ = false; ///< the index range has been established. bool started_ = false; ///< the index range has been established.
bool truncated_ = false; ///< the producer overtook the scan at least once; sticky for the whole scan.
u64 at_ = 0; ///< next absolute index to scan. u64 at_ = 0; ///< next absolute index to scan.
u64 end_ = 0; ///< one past the last absolute index to scan. u64 end_ = 0; ///< one past the last absolute index to scan.
double first_s_ = 0.0; ///< stamp of `at_` when the scan began. double first_s_ = 0.0; ///< stamp of `at_` when the scan began.
-2
View File
@@ -9015,7 +9015,6 @@ gboolean condition_probe(gpointer user) {
/// scanned hit. `agree=1` is the assertion; `agree=0` means the two evaluators have drifted /// scanned hit. `agree=1` is the assertion; `agree=0` means the two evaluators have drifted
/// apart, which is the whole failure mode separating `EventDetector` out was meant to /// apart, which is the whole failure mode separating `EventDetector` out was meant to
/// prevent. It then steps to a hit and reports the pinned axis against it. /// prevent. It then steps to a hit and reports the pinned axis against it.
int g_search_phase = 0;
double g_search_t0 = 0.0; double g_search_t0 = 0.0;
gboolean search_probe_report(gpointer user) { gboolean search_probe_report(gpointer user) {
@@ -9085,7 +9084,6 @@ gboolean search_probe(gpointer user) {
if (a->window == nullptr) return G_SOURCE_REMOVE; if (a->window == nullptr) return G_SOURCE_REMOVE;
// Reuse the condition probe's arming entirely: the point is that one condition gives two // Reuse the condition probe's arming entirely: the point is that one condition gives two
// evaluators the same answer, so the condition must be set in exactly one place. // evaluators the same answer, so the condition must be set in exactly one place.
g_search_phase = 0;
condition_probe(a); condition_probe(a);
g_timeout_add(6000, search_probe_run, a); g_timeout_add(6000, search_probe_run, a);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;