diff options
author | Ryan Volz <rvolz@mit.edu> | 2019-09-18 17:52:41 -0400 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2020-01-07 16:22:16 -0800 |
commit | a33dec75b97bc168b3a0f91f53a61d49c4bc93ef (patch) | |
tree | 08f764f1e4fe379e90e50bcfc2b1de04778206d9 /gnuradio-runtime/lib/buffer.cc | |
parent | 507e85722573cfdc3029b4fd7776a75987f332d7 (diff) |
runtime: Fix get_tags_in_range for (end - start) > delay.
Previously, stream tags would be lost (not propagated downstream) when a
block has a tag delay set and it is called with a number of input
samples that is less than the delay. Since this happens depending on the
scheduler and the number of samples provided, tags might mostly work or
seemingly randomly disappear. The problem occurs because a wrong
correction is included for underflows in unsigned arithmetic that limits
the tags propagated to a smaller sample window than desired. Correctly
detecting the underflow and setting the value to 0 rather than abs_start
or abs_end fixes the problem.
For a real example, let the d_attr_delay=209, abs_start=0, and
abs_end=200 with a tag at input sample 0. Then tags from min(abs_start,
abs_start - d_attr_delay) == 0 to min(abs_end, abs_end - d_attr_delay)
== 200 are iterated through, including the tag at 0 (item_time == 209),
but it is not propagated to the output yet since item_time >= abs_end
(209 >= 200). On the next call to the block, with abs_start=200 and
abs_end=400, the tag at input sample 0 is ignored because min(abs_start,
abs_start - d_attr_delay) == 200 and the iterator skips it. The correct
calculation for the lower bound of the tag iterator would result in 0
and find the tag since (abs_start - d_attr_delay) == -9 -> 0 when
constrained to unsigned values. With the proper lower bound (and upper
bound corrected as well), the tag at 0 is found with an item_time == 209
which falls between abs_start and abs_end and is propagated to output
sample 209.
Diffstat (limited to 'gnuradio-runtime/lib/buffer.cc')
-rw-r--r-- | gnuradio-runtime/lib/buffer.cc | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/gnuradio-runtime/lib/buffer.cc b/gnuradio-runtime/lib/buffer.cc index cc9d991c95..5c813294ac 100644 --- a/gnuradio-runtime/lib/buffer.cc +++ b/gnuradio-runtime/lib/buffer.cc @@ -340,11 +340,20 @@ void buffer_reader::get_tags_in_range(std::vector<tag_t>& v, { gr::thread::scoped_lock guard(*mutex()); + uint64_t lower_bound = abs_start - d_attr_delay; + // check for underflow and if so saturate at 0 + if (lower_bound > abs_start) + lower_bound = 0; + uint64_t upper_bound = abs_end - d_attr_delay; + // check for underflow and if so saturate at 0 + if (upper_bound > abs_end) + upper_bound = 0; + v.clear(); std::multimap<uint64_t, tag_t>::iterator itr = - d_buffer->get_tags_lower_bound(std::min(abs_start, abs_start - d_attr_delay)); + d_buffer->get_tags_lower_bound(lower_bound); std::multimap<uint64_t, tag_t>::iterator itr_end = - d_buffer->get_tags_upper_bound(std::min(abs_end, abs_end - d_attr_delay)); + d_buffer->get_tags_upper_bound(upper_bound); uint64_t item_time; while (itr != itr_end) { |