summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/lib/buffer.cc
diff options
context:
space:
mode:
authorRyan Volz <rvolz@mit.edu>2019-09-18 17:52:41 -0400
committerMartin Braun <martin.braun@ettus.com>2020-01-07 16:22:16 -0800
commita33dec75b97bc168b3a0f91f53a61d49c4bc93ef (patch)
tree08f764f1e4fe379e90e50bcfc2b1de04778206d9 /gnuradio-runtime/lib/buffer.cc
parent507e85722573cfdc3029b4fd7776a75987f332d7 (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.cc13
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) {