GNU Radio Manual and C++ API Reference 3.7.14.0
The Free & Open Software Radio Ecosystem
buffer.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 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifndef INCLUDED_GR_RUNTIME_BUFFER_H
24#define INCLUDED_GR_RUNTIME_BUFFER_H
25
26#include <gnuradio/api.h>
28#include <gnuradio/tags.h>
30#include <boost/weak_ptr.hpp>
31#include <map>
32
33namespace gr {
34
35class vmcircbuf;
36
37/*!
38 * \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
39 *
40 * The total size of the buffer will be rounded up to a system
41 * dependent boundary. This is typically the system page size, but
42 * under MS windows is 64KB.
43 *
44 * \param nitems is the minimum number of items the buffer will hold.
45 * \param sizeof_item is the size of an item in bytes.
46 * \param link is the block that writes to this buffer.
47 */
48GR_RUNTIME_API buffer_sptr make_buffer(int nitems,
49 size_t sizeof_item,
50 block_sptr link = block_sptr());
51
52/*!
53 * \brief Single writer, multiple reader fifo.
54 * \ingroup internal
55 */
57{
58public:
59 virtual ~buffer();
60
61 /*!
62 * \brief return number of items worth of space available for writing
63 */
65
66 /*!
67 * \brief return size of this buffer in items
68 */
69 int bufsize() const { return d_bufsize; }
70
71 /*!
72 * \brief return the base address of the buffer
73 */
74 const char* base() const { return static_cast<const char*>(d_base); }
75
76 /*!
77 * \brief return pointer to write buffer.
78 *
79 * The return value points at space that can hold at least
80 * space_available() items.
81 */
83
84 /*!
85 * \brief tell buffer that we wrote \p nitems into it
86 */
87 void update_write_pointer(int nitems);
88
89 void set_done(bool done);
90 bool done() const { return d_done; }
91
92 /*!
93 * \brief Return the block that writes to this buffer.
94 */
95 block_sptr link() { return block_sptr(d_link); }
96
97 size_t nreaders() const { return d_readers.size(); }
98 buffer_reader* reader(size_t index) { return d_readers[index]; }
99
100 gr::thread::mutex* mutex() { return &d_mutex; }
101
102 uint64_t nitems_written() { return d_abs_write_offset; }
103
104 void reset_nitem_counter() { d_abs_write_offset = 0; }
105
106 size_t get_sizeof_item() { return d_sizeof_item; }
107
108 /*!
109 * \brief Adds a new tag to the buffer.
110 *
111 * \param tag the new tag
112 */
113 void add_item_tag(const tag_t& tag);
114
115 /*!
116 * \brief Removes an existing tag from the buffer.
117 *
118 * If no such tag is found, does nothing.
119 * Note: Doesn't actually physically delete the tag, but
120 * marks it as deleted. For the user, this has the same effect:
121 * Any subsequent calls to get_tags_in_range() will not return
122 * the tag.
123 *
124 * \param tag the tag that needs to be removed
125 * \param id the unique ID of the block calling this function
126 */
127 void remove_item_tag(const tag_t& tag, long id);
128
129 /*!
130 * \brief Removes all tags before \p max_time from buffer
131 *
132 * \param max_time the time (item number) to trim up until.
133 */
134 void prune_tags(uint64_t max_time);
135
136 std::multimap<uint64_t, tag_t>::iterator get_tags_begin()
137 {
138 return d_item_tags.begin();
139 }
140 std::multimap<uint64_t, tag_t>::iterator get_tags_end() { return d_item_tags.end(); }
141 std::multimap<uint64_t, tag_t>::iterator get_tags_lower_bound(uint64_t x)
142 {
143 return d_item_tags.lower_bound(x);
144 }
145 std::multimap<uint64_t, tag_t>::iterator get_tags_upper_bound(uint64_t x)
146 {
147 return d_item_tags.upper_bound(x);
148 }
149
150 // -------------------------------------------------------------------------
151
152private:
153 friend class buffer_reader;
154 friend GR_RUNTIME_API buffer_sptr make_buffer(int nitems,
155 size_t sizeof_item,
156 block_sptr link);
157 friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf,
158 int nzero_preload,
159 block_sptr link,
160 int delay);
161
162protected:
163 char* d_base; // base address of buffer
164 unsigned int d_bufsize; // in items
165
166 // Keep track of maximum sample delay of any reader; Only prune tags past this.
168
169private:
170 gr::vmcircbuf* d_vmcircbuf;
171 size_t d_sizeof_item; // in bytes
172 std::vector<buffer_reader*> d_readers;
173 boost::weak_ptr<block> d_link; // block that writes to this buffer
174
175 //
176 // The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags
177 // and the d_read_index's and d_abs_read_offset's in the buffer readers.
178 //
179 gr::thread::mutex d_mutex;
180 unsigned int d_write_index; // in items [0,d_bufsize)
181 uint64_t d_abs_write_offset; // num items written since the start
182 bool d_done;
183 std::multimap<uint64_t, tag_t> d_item_tags;
184 uint64_t d_last_min_items_read;
185
186 unsigned index_add(unsigned a, unsigned b)
187 {
188 unsigned s = a + b;
189
190 if (s >= d_bufsize)
191 s -= d_bufsize;
192
193 assert(s < d_bufsize);
194 return s;
195 }
196
197 unsigned index_sub(unsigned a, unsigned b)
198 {
199 int s = a - b;
200
201 if (s < 0)
202 s += d_bufsize;
203
204 assert((unsigned)s < d_bufsize);
205 return s;
206 }
207
208 virtual bool allocate_buffer(int nitems, size_t sizeof_item);
209
210 /*!
211 * \brief constructor is private. Use gr_make_buffer to create instances.
212 *
213 * Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
214 *
215 * \param nitems is the minimum number of items the buffer will hold.
216 * \param sizeof_item is the size of an item in bytes.
217 * \param link is the block that writes to this buffer.
218 *
219 * The total size of the buffer will be rounded up to a system
220 * dependent boundary. This is typically the system page size, but
221 * under MS windows is 64KB.
222 */
223 buffer(int nitems, size_t sizeof_item, block_sptr link);
224
225 /*!
226 * \brief disassociate \p reader from this buffer
227 */
228 void drop_reader(buffer_reader* reader);
229};
230
231/*!
232 * \brief Create a new gr::buffer_reader and attach it to buffer \p buf
233 * \param buf is the buffer the \p gr::buffer_reader reads from.
234 * \param nzero_preload -- number of zero items to "preload" into buffer.
235 * \param link is the block that reads from the buffer using this gr::buffer_reader.
236 * \param delay Optional setting to declare the buffer's sample delay.
237 */
238GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf,
239 int nzero_preload,
240 block_sptr link = block_sptr(),
241 int delay = 0);
242
243//! returns # of buffers currently allocated
245
246
247// ---------------------------------------------------------------------------
248
249/*!
250 * \brief How we keep track of the readers of a gr::buffer.
251 * \ingroup internal
252 */
254{
255public:
257
258 /*!
259 * Declares the sample delay for this reader.
260 *
261 * See gr::block::declare_sample_delay for details.
262 *
263 * \param delay The new sample delay
264 */
265 void declare_sample_delay(unsigned delay);
266
267 /*!
268 * Gets the sample delay for this reader.
269 *
270 * See gr::block::sample_delay for details.
271 */
272 unsigned sample_delay() const;
273
274 /*!
275 * \brief Return number of items available for reading.
276 */
277 int items_available() const;
278
279 /*!
280 * \brief Return buffer this reader reads from.
281 */
282 buffer_sptr buffer() const { return d_buffer; }
283
284 /*!
285 * \brief Return maximum number of items that could ever be available for reading.
286 * This is used as a sanity check in the scheduler to avoid looping forever.
287 */
288 int max_possible_items_available() const { return d_buffer->d_bufsize - 1; }
289
290 /*!
291 * \brief return pointer to read buffer.
292 *
293 * The return value points to items_available() number of items
294 */
295 const void* read_pointer();
296
297 /*
298 * \brief tell buffer we read \p items from it
299 */
300 void update_read_pointer(int nitems);
301
302 void set_done(bool done) { d_buffer->set_done(done); }
303 bool done() const { return d_buffer->done(); }
304
305 gr::thread::mutex* mutex() { return d_buffer->mutex(); }
306
307 uint64_t nitems_read() { return d_abs_read_offset; }
308
309 void reset_nitem_counter() { d_abs_read_offset = 0; }
310
311 size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); }
312
313 /*!
314 * \brief Return the block that reads via this reader.
315 *
316 */
317 block_sptr link() { return block_sptr(d_link); }
318
319 /*!
320 * \brief Given a [start,end), returns a vector all tags in the range.
321 *
322 * Get a vector of tags in given range. Range of counts is from start to end-1.
323 *
324 * Tags are tuples of:
325 * (item count, source id, key, value)
326 *
327 * \param v a vector reference to return tags into
328 * \param abs_start a uint64 count of the start of the range of interest
329 * \param abs_end a uint64 count of the end of the range of interest
330 * \param id the unique ID of the block to make sure already deleted tags
331 * are not returned
332 */
333 void get_tags_in_range(std::vector<tag_t>& v,
334 uint64_t abs_start,
335 uint64_t abs_end,
336 long id);
337
338 // -------------------------------------------------------------------------
339
340private:
341 friend class buffer;
342 friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf,
343 int nzero_preload,
344 block_sptr link,
345 int delay);
346
347 buffer_sptr d_buffer;
348 unsigned int d_read_index; // in items [0,d->buffer.d_bufsize)
349 uint64_t d_abs_read_offset; // num items seen since the start
350 boost::weak_ptr<block> d_link; // block that reads via this buffer reader
351 unsigned d_attr_delay; // sample delay attribute for tag propagation
352
353 //! constructor is private. Use gr::buffer::add_reader to create instances
354 buffer_reader(buffer_sptr buffer, unsigned int read_index, block_sptr link);
355};
356
357//! returns # of buffer_readers currently allocated
359
360} /* namespace gr */
361
362#endif /* INCLUDED_GR_RUNTIME_BUFFER_H */
How we keep track of the readers of a gr::buffer.
Definition: buffer.h:254
unsigned sample_delay() const
uint64_t nitems_read()
Definition: buffer.h:307
int items_available() const
Return number of items available for reading.
const void * read_pointer()
return pointer to read buffer.
size_t get_sizeof_item()
Definition: buffer.h:311
void set_done(bool done)
Definition: buffer.h:302
void declare_sample_delay(unsigned delay)
bool done() const
Definition: buffer.h:303
buffer_sptr buffer() const
Return buffer this reader reads from.
Definition: buffer.h:282
void get_tags_in_range(std::vector< tag_t > &v, uint64_t abs_start, uint64_t abs_end, long id)
Given a [start,end), returns a vector all tags in the range.
void update_read_pointer(int nitems)
gr::thread::mutex * mutex()
Definition: buffer.h:305
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.
block_sptr link()
Return the block that reads via this reader.
Definition: buffer.h:317
void reset_nitem_counter()
Definition: buffer.h:309
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.h:288
Single writer, multiple reader fifo.
Definition: buffer.h:57
size_t nreaders() const
Definition: buffer.h:97
unsigned d_max_reader_delay
Definition: buffer.h:167
std::multimap< uint64_t, tag_t >::iterator get_tags_lower_bound(uint64_t x)
Definition: buffer.h:141
friend GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item, block_sptr link)
Allocate a buffer that holds at least nitems of size sizeof_item.
std::multimap< uint64_t, tag_t >::iterator get_tags_end()
Definition: buffer.h:140
void remove_item_tag(const tag_t &tag, long id)
Removes an existing tag from the buffer.
void * write_pointer()
return pointer to write buffer.
std::multimap< uint64_t, tag_t >::iterator get_tags_upper_bound(uint64_t x)
Definition: buffer.h:145
void prune_tags(uint64_t max_time)
Removes all tags before max_time from buffer.
bool done() const
Definition: buffer.h:90
void add_item_tag(const tag_t &tag)
Adds a new tag to the buffer.
virtual ~buffer()
unsigned int d_bufsize
Definition: buffer.h:164
buffer_reader * reader(size_t index)
Definition: buffer.h:98
void reset_nitem_counter()
Definition: buffer.h:104
void set_done(bool done)
block_sptr link()
Return the block that writes to this buffer.
Definition: buffer.h:95
int space_available()
return number of items worth of space available for writing
size_t get_sizeof_item()
Definition: buffer.h:106
const char * base() const
return the base address of the buffer
Definition: buffer.h:74
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.
void update_write_pointer(int nitems)
tell buffer that we wrote nitems into it
std::multimap< uint64_t, tag_t >::iterator get_tags_begin()
Definition: buffer.h:136
char * d_base
Definition: buffer.h:163
gr::thread::mutex * mutex()
Definition: buffer.h:100
uint64_t nitems_written()
Definition: buffer.h:102
int bufsize() const
return size of this buffer in items
Definition: buffer.h:69
#define GR_RUNTIME_API
Definition: gnuradio-runtime/include/gnuradio/api.h:30
boost::mutex mutex
Definition: thread.h:48
Include this header to use the message passing features.
Definition: basic_block.h:45
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
GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item, block_sptr link=block_sptr())
Allocate a buffer that holds at least nitems of size sizeof_item.
Definition: tags.h:31
Definition: cc_common.h:45