GNU Radio C++ API Reference g90d26cb
The Free & Open Software Radio Ecosystem
 
Loading...
Searching...
No Matches
buffer_reader.h
Go to the documentation of this file.
1/* -*- c++ -*- */
2/*
3 * Copyright 2004,2009-2011,2013 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU Radio
6 *
7 * SPDX-License-Identifier: GPL-3.0-or-later
8 *
9 */
10
11#ifndef INCLUDED_GR_RUNTIME_BUFFER_READER_H
12#define INCLUDED_GR_RUNTIME_BUFFER_READER_H
13
14#include <gnuradio/api.h>
15#include <gnuradio/buffer.h>
16#include <gnuradio/logger.h>
18#include <gnuradio/tags.h>
20#include <type_traits>
21#include <cstdint>
22#include <memory>
23#include <optional>
24#include <tuple>
25
26namespace gr {
27
28class buffer_reader_sm;
29
30/*!
31 * \brief Create a new gr::buffer_reader and attach it to buffer \p buf
32 * \param buf is the buffer the \p gr::buffer_reader reads from.
33 * \param nzero_preload -- number of zero items to "preload" into buffer.
34 * \param link is the block that reads from the buffer using this gr::buffer_reader.
35 * \param delay Optional setting to declare the buffer's sample delay.
36 */
37GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf,
38 int nzero_preload,
39 block_sptr link = block_sptr(),
40 int delay = 0);
41
42//! returns # of buffers currently allocated
44
45
46// ---------------------------------------------------------------------------
47
48/*!
49 * \brief How we keep track of the readers of a gr::buffer.
50 * \ingroup internal
51 */
53{
54private:
55 //! \brief converts absolute offsets to bounds for tag vectors
56 std::tuple<uint64_t, uint64_t> offsets_to_bounds(uint64_t start, uint64_t end) const;
57
58public:
59#ifdef BUFFER_DEBUG
60 gr::logger_ptr d_logger;
61 gr::logger_ptr d_debug_logger;
62#endif
63
64 virtual ~buffer_reader();
65
66 /*!
67 * Declares the sample delay for this reader.
68 *
69 * See gr::block::declare_sample_delay for details.
70 *
71 * \param delay The new sample delay
72 */
73 void declare_sample_delay(unsigned delay);
74
75 /*!
76 * Gets the sample delay for this reader.
77 *
78 * See gr::block::sample_delay for details.
79 */
80 unsigned sample_delay() const;
81
82 /*!
83 * \brief Return number of items available for reading.
84 */
85 virtual int items_available() const;
86
87 /*!
88 * \brief Return buffer this reader reads from.
89 */
90 buffer_sptr buffer() const { return d_buffer; }
91
92 /*!
93 * \brief Return maximum number of items that could ever be available for reading.
94 * This is used as a sanity check in the scheduler to avoid looping forever.
95 */
96 int max_possible_items_available() const { return d_buffer->bufsize() - 1; }
97
98 /*!
99 * \brief return pointer to read buffer.
100 *
101 * The return value points to items_available() number of items
102 */
103 const void* read_pointer();
104
105 /*
106 * \brief tell buffer we read \p items from it
107 */
108 void update_read_pointer(int nitems);
109
110 void set_done(bool done) { d_buffer->set_done(done); }
111 bool done() const { return d_buffer->done(); }
112
113 gr::thread::mutex* mutex() { return d_buffer->mutex(); }
114
115 uint64_t nitems_read() const { return d_abs_read_offset; }
116
118 {
119 d_read_index = 0;
120 d_abs_read_offset = 0;
121 }
122
123 size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); }
124
125 /*!
126 * \brief Return the block that reads via this reader.
127 *
128 */
129 block_sptr link() const { return block_sptr(d_link); }
130
131 /*!
132 * \brief Given a [start,end), returns a vector all tags in the range.
133 *
134 * Get a vector of tags in given range. Range of counts is from start to end-1.
135 *
136 * Tags are tuples of:
137 * (item count, source id, key, value)
138 *
139 * \param v a vector reference to return tags into
140 * \param abs_start a uint64 count of the start of the range of interest
141 * \param abs_end a uint64 count of the end of the range of interest
142 * \param id the unique ID of the block to make sure already deleted tags
143 * are not returned
144 */
145 void get_tags_in_range(std::vector<tag_t>& v, uint64_t abs_start, uint64_t abs_end);
146
147 /*!
148 * \brief Get the first tag in specified range (if any), fulfilling criterion
149 *
150 * \see gr::block::get_first_tag_in_range
151 *
152 * \details
153 * This function returns the lowest-offset tag in the range for whom the predicate
154 * function returns true.
155 *
156 * The predicate function hence needs to map tags to booleans; its signature is
157 * bool function(const tag_t& tag_to check);
158 *
159 * We're doing this here as a template in the block detail; allows inlining of the
160 * predicate check.
161 *
162 * \param start a uint64 count of the start of the range of interest
163 * \param end a uint64 count of the end of the range of interest
164 * \param predicate a function of tag_t, returning a boolean
165 */
166 template <typename predicate_t>
167 [[nodiscard]] std::optional<gr::tag_t>
168 get_first_tag_in_range(uint64_t start, uint64_t end, predicate_t predicate)
169 {
170 // SFINAE these conditions; constraints/contexts are a C++20 thing, and we're on
171 // C++17; might as well make the compiler error indicative of what's wrong.
172 static_assert(std::is_invocable_v<predicate_t, const gr::tag_t&>,
173 "predicate is not invocable");
174 static_assert(
175 std::is_convertible_v<std::invoke_result_t<predicate_t, const gr::tag_t&>,
176 bool>,
177 "predicate result can't be converted to boolean");
178
179 auto [lower, upper] = offsets_to_bounds(start, end);
180
181 gr::thread::scoped_lock guard(*mutex());
182 for (auto iterator = d_buffer->get_tags_lower_bound(lower);
183 iterator != d_buffer->get_tags_end() && iterator->second.offset <= end;
184 ++iterator) {
185 const gr::tag_t& tag = iterator->second;
186 if (predicate(tag)) {
187 return { tag };
188 }
189 }
190 return std::nullopt;
191 }
192
193 /*!
194 * \brief Returns true when the current thread is ready to call the callback,
195 * false otherwise. Delegate calls to buffer class's input_blkd_cb_ready().
196 * Note if input_blocked_callback is overridden then this function should
197 * also be overridden.
198 */
199 virtual bool input_blkd_cb_ready(int items_required) const { return false; }
200
201 /*!
202 * \brief Callback function that the scheduler will call when it determines
203 * that the input is blocked. Delegate calls to buffer class's
204 * input_blocked_callback(). Override this function if needed.
205 */
206 virtual bool input_blocked_callback(int items_required, int items_avail)
207 {
208 return false;
209 }
210
211 // -------------------------------------------------------------------------
212 unsigned int get_read_index() const { return d_read_index; }
213 uint64_t get_abs_read_offset() const { return d_abs_read_offset; }
214
215protected:
216 friend class buffer;
219 friend class buffer_reader_sm;
220
221 friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf,
222 int nzero_preload,
223 block_sptr link,
224 int delay);
225
226 buffer_sptr d_buffer;
227 unsigned int d_read_index; // in items [0,d->buffer.d_bufsize) ** see NB
228 uint64_t d_abs_read_offset; // num items seen since the start ** see NB
229 std::weak_ptr<block> d_link; // block that reads via this buffer reader
230 unsigned d_attr_delay; // sample delay attribute for tag propagation
231 // ** NB: buffer::d_mutex protects d_read_index and d_abs_read_offset
232
233 //! constructor is private. Use gr::buffer::add_reader to create instances
234 buffer_reader(buffer_sptr buffer, unsigned int read_index, block_sptr link);
235};
236
237//! returns # of buffer_readers currently allocated
239
240} /* namespace gr */
241
242#endif /* INCLUDED_GR_RUNTIME_BUFFER_READER_H */
Single writer, multiple reader fifo.
Definition buffer_double_mapped.h:29
Definition buffer_reader_sm.h:22
How we keep track of the readers of a gr::buffer.
Definition buffer_reader.h:53
uint64_t nitems_read() const
Definition buffer_reader.h:115
virtual ~buffer_reader()
unsigned sample_delay() const
unsigned int get_read_index() const
Definition buffer_reader.h:212
uint64_t d_abs_read_offset
Definition buffer_reader.h:228
std::weak_ptr< block > d_link
Definition buffer_reader.h:229
block_sptr link() const
Return the block that reads via this reader.
Definition buffer_reader.h:129
const void * read_pointer()
return pointer to read buffer.
buffer_sptr d_buffer
Definition buffer_reader.h:226
size_t get_sizeof_item()
Definition buffer_reader.h:123
void set_done(bool done)
Definition buffer_reader.h:110
virtual int items_available() const
Return number of items available for reading.
void declare_sample_delay(unsigned delay)
bool done() const
Definition buffer_reader.h:111
buffer_sptr buffer() const
Return buffer this reader reads from.
Definition buffer_reader.h:90
friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link, int delay)
Create a new gr::buffer_reader and attach it to buffer buf.
uint64_t get_abs_read_offset() const
Definition buffer_reader.h:213
unsigned d_attr_delay
Definition buffer_reader.h:230
unsigned int d_read_index
Definition buffer_reader.h:227
void update_read_pointer(int nitems)
void get_tags_in_range(std::vector< tag_t > &v, uint64_t abs_start, uint64_t abs_end)
Given a [start,end), returns a vector all tags in the range.
buffer_reader(buffer_sptr buffer, unsigned int read_index, block_sptr link)
constructor is private. Use gr::buffer::add_reader to create instances
gr::thread::mutex * mutex()
Definition buffer_reader.h:113
std::optional< gr::tag_t > get_first_tag_in_range(uint64_t start, uint64_t end, predicate_t predicate)
Get the first tag in specified range (if any), fulfilling criterion.
Definition buffer_reader.h:168
void reset_nitem_counter()
Definition buffer_reader.h:117
virtual bool input_blkd_cb_ready(int items_required) const
Returns true when the current thread is ready to call the callback, false otherwise....
Definition buffer_reader.h:199
int max_possible_items_available() const
Return maximum number of items that could ever be available for reading. This is used as a sanity che...
Definition buffer_reader.h:96
virtual bool input_blocked_callback(int items_required, int items_avail)
Callback function that the scheduler will call when it determines that the input is blocked....
Definition buffer_reader.h:206
A single mapped buffer where wrapping conditions are handled explicitly via input/output_blocked_call...
Definition buffer_single_mapped.h:30
Single writer, multiple reader fifo.
Definition buffer.h:67
STL class.
Definition vector_docstub.h:11
#define GR_RUNTIME_API
Definition gnuradio-runtime/include/gnuradio/api.h:18
boost::mutex mutex
Definition thread.h:34
boost::unique_lock< boost::mutex > scoped_lock
Definition thread.h:35
GNU Radio logging wrapper.
Definition basic_block.h:29
std::shared_ptr< logger > logger_ptr
Definition logger.h:248
GR_RUNTIME_API long buffer_reader_ncurrently_allocated()
returns # of buffer_readers currently allocated
GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link=block_sptr(), int delay=0)
Create a new gr::buffer_reader and attach it to buffer buf.
GR_RUNTIME_API long buffer_ncurrently_allocated()
returns # of buffers currently allocated
Definition tags.h:28
Definition cc_common.h:35