GNU Radio 3.6.4 C++ API
gr_block.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004,2007,2009,2010 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_BLOCK_H
24 #define INCLUDED_GR_BLOCK_H
25 
26 #include <gr_core_api.h>
27 #include <gr_basic_block.h>
28 #include <gr_tags.h>
29 
30 /*!
31  * \brief The abstract base class for all 'terminal' processing blocks.
32  * \ingroup base_blk
33  *
34  * A signal processing flow is constructed by creating a tree of
35  * hierarchical blocks, which at any level may also contain terminal nodes
36  * that actually implement signal processing functions. This is the base
37  * class for all such leaf nodes.
38 
39  * Blocks have a set of input streams and output streams. The
40  * input_signature and output_signature define the number of input
41  * streams and output streams respectively, and the type of the data
42  * items in each stream.
43  *
44  * Although blocks may consume data on each input stream at a
45  * different rate, all outputs streams must produce data at the same
46  * rate. That rate may be different from any of the input rates.
47  *
48  * User derived blocks override two methods, forecast and general_work,
49  * to implement their signal processing behavior. forecast is called
50  * by the system scheduler to determine how many items are required on
51  * each input stream in order to produce a given number of output
52  * items.
53  *
54  * general_work is called to perform the signal processing in the block.
55  * It reads the input items and writes the output items.
56  */
57 
59 
60  public:
61 
62  //! Magic return values from general_work
63  enum {
64  WORK_CALLED_PRODUCE = -2,
65  WORK_DONE = -1
66  };
67 
69  TPP_DONT = 0,
70  TPP_ALL_TO_ALL = 1,
71  TPP_ONE_TO_ONE = 2
72  };
73 
74  virtual ~gr_block ();
75 
76  /*!
77  * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
78  * History is the number of x_i's that are examined to produce one y_i.
79  * This comes in handy for FIR filters, where we use history to
80  * ensure that our input contains the appropriate "history" for the
81  * filter. History should be equal to the number of filter taps.
82  */
83  unsigned history () const { return d_history; }
84  void set_history (unsigned history) { d_history = history; }
85 
86  /*!
87  * \brief Return true if this block has a fixed input to output rate.
88  *
89  * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
90  */
91  bool fixed_rate() const { return d_fixed_rate; }
92 
93  // ----------------------------------------------------------------
94  // override these to define your behavior
95  // ----------------------------------------------------------------
96 
97  /*!
98  * \brief Estimate input requirements given output request
99  *
100  * \param noutput_items number of output items to produce
101  * \param ninput_items_required number of input items required on each input stream
102  *
103  * Given a request to product \p noutput_items, estimate the number of
104  * data items required on each input stream. The estimate doesn't have
105  * to be exact, but should be close.
106  */
107  virtual void forecast (int noutput_items,
108  gr_vector_int &ninput_items_required);
109 
110  /*!
111  * \brief compute output items from input items
112  *
113  * \param noutput_items number of output items to write on each output stream
114  * \param ninput_items number of input items available on each input stream
115  * \param input_items vector of pointers to the input items, one entry per input stream
116  * \param output_items vector of pointers to the output items, one entry per output stream
117  *
118  * \returns number of items actually written to each output stream, or -1 on EOF.
119  * It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items
120  *
121  * general_work must call consume or consume_each to indicate how many items
122  * were consumed on each input stream.
123  */
124  virtual int general_work (int noutput_items,
125  gr_vector_int &ninput_items,
126  gr_vector_const_void_star &input_items,
127  gr_vector_void_star &output_items);
128 
129  /*!
130  * \brief Called to enable drivers, etc for i/o devices.
131  *
132  * This allows a block to enable an associated driver to begin
133  * transfering data just before we start to execute the scheduler.
134  * The end result is that this reduces latency in the pipeline when
135  * dealing with audio devices, usrps, etc.
136  */
137  virtual bool start();
138 
139  /*!
140  * \brief Called to disable drivers, etc for i/o devices.
141  */
142  virtual bool stop();
143 
144  // ----------------------------------------------------------------
145 
146  /*!
147  * \brief Constrain the noutput_items argument passed to forecast and general_work
148  *
149  * set_output_multiple causes the scheduler to ensure that the noutput_items
150  * argument passed to forecast and general_work will be an integer multiple
151  * of \param multiple The default value of output multiple is 1.
152  */
153  void set_output_multiple (int multiple);
154  int output_multiple () const { return d_output_multiple; }
155  bool output_multiple_set () const { return d_output_multiple_set; }
156 
157  /*!
158  * \brief Constrains buffers to work on a set item alignment (for SIMD)
159  *
160  * set_alignment_multiple causes the scheduler to ensure that the noutput_items
161  * argument passed to forecast and general_work will be an integer multiple
162  * of \param multiple The default value is 1.
163  *
164  * This control is similar to the output_multiple setting, except
165  * that if the number of items passed to the block is less than the
166  * output_multiple, this value is ignored and the block can produce
167  * like normal. The d_unaligned value is set to the number of items
168  * the block is off by. In the next call to general_work, the
169  * noutput_items is set to d_unaligned or less until
170  * d_unaligned==0. The buffers are now aligned again and the aligned
171  * calls can be performed again.
172  */
173  void set_alignment (int multiple);
174  int alignment () const { return d_output_multiple; }
175 
176  void set_unaligned (int na);
177  int unaligned () const { return d_unaligned; }
178  void set_is_unaligned (bool u);
179  bool is_unaligned () const { return d_is_unaligned; }
180 
181  /*!
182  * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
183  */
184  void consume (int which_input, int how_many_items);
185 
186  /*!
187  * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
188  */
189  void consume_each (int how_many_items);
190 
191  /*!
192  * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
193  *
194  * If the block's general_work method calls produce, \p general_work must return WORK_CALLED_PRODUCE.
195  */
196  void produce (int which_output, int how_many_items);
197 
198  /*!
199  * \brief Set the approximate output rate / input rate
200  *
201  * Provide a hint to the buffer allocator and scheduler.
202  * The default relative_rate is 1.0
203  *
204  * decimators have relative_rates < 1.0
205  * interpolators have relative_rates > 1.0
206  */
207  void set_relative_rate (double relative_rate);
208 
209  /*!
210  * \brief return the approximate output rate / input rate
211  */
212  double relative_rate () const { return d_relative_rate; }
213 
214  /*
215  * The following two methods provide special case info to the
216  * scheduler in the event that a block has a fixed input to output
217  * ratio. gr_sync_block, gr_sync_decimator and gr_sync_interpolator
218  * override these. If you're fixed rate, subclass one of those.
219  */
220  /*!
221  * \brief Given ninput samples, return number of output samples that will be produced.
222  * N.B. this is only defined if fixed_rate returns true.
223  * Generally speaking, you don't need to override this.
224  */
225  virtual int fixed_rate_ninput_to_noutput(int ninput);
226 
227  /*!
228  * \brief Given noutput samples, return number of input samples required to produce noutput.
229  * N.B. this is only defined if fixed_rate returns true.
230  * Generally speaking, you don't need to override this.
231  */
232  virtual int fixed_rate_noutput_to_ninput(int noutput);
233 
234  /*!
235  * \brief Return the number of items read on input stream which_input
236  */
237  uint64_t nitems_read(unsigned int which_input);
238 
239  /*!
240  * \brief Return the number of items written on output stream which_output
241  */
242  uint64_t nitems_written(unsigned int which_output);
243 
244  /*!
245  * \brief Asks for the policy used by the scheduler to moved tags downstream.
246  */
247  tag_propagation_policy_t tag_propagation_policy();
248 
249  /*!
250  * \brief Set the policy by the scheduler to determine how tags are moved downstream.
251  */
252  void set_tag_propagation_policy(tag_propagation_policy_t p);
253 
254  /*!
255  * \brief Return the minimum number of output items this block can
256  * produce during a call to work.
257  *
258  * Should be 0 for most blocks. Useful if we're dealing with packets and
259  * the block produces one packet per call to work.
260  */
261  int min_noutput_items() const { return d_min_noutput_items; }
262 
263  /*!
264  * \brief Set the minimum number of output items this block can
265  * produce during a call to work.
266  *
267  * \param m the minimum noutput_items this block can produce.
268  */
269  void set_min_noutput_items(int m) { d_min_noutput_items = m; }
270 
271  /*!
272  * \brief Return the maximum number of output items this block will
273  * handle during a call to work.
274  */
275  int max_noutput_items();
276 
277  /*!
278  * \brief Set the maximum number of output items this block will
279  * handle during a call to work.
280  *
281  * \param m the maximum noutput_items this block will handle.
282  */
283  void set_max_noutput_items(int m);
284 
285  /*!
286  * \brief Clear the switch for using the max_noutput_items value of this block.
287  *
288  * When is_set_max_noutput_items() returns 'true', the scheduler
289  * will use the value returned by max_noutput_items() to limit the
290  * size of the number of items possible for this block's work
291  * function. If is_set_max_notput_items() returns 'false', then the
292  * scheduler ignores the internal value and uses the value set
293  * globally in the top_block.
294  *
295  * Use this value to clear the 'is_set' flag so the scheduler will
296  * ignore this. Use the set_max_noutput_items(m) call to both set a
297  * new value for max_noutput_items and to reenable its use in the
298  * scheduler.
299  */
300  void unset_max_noutput_items();
301 
302  /*!
303  * \brief Ask the block if the flag is or is not set to use the
304  * internal value of max_noutput_items during a call to work.
305  */
306  bool is_set_max_noutput_items();
307 
308  /*
309  * Used to expand the vectors that hold the min/max buffer sizes.
310  *
311  * Specifically, when -1 is used, the vectors are just initialized
312  * with 1 value; this is used by the flat_flowgraph to expand when
313  * required to add a new value for new ports on these blocks.
314  */
315  void expand_minmax_buffer(int port) {
316  if((size_t)port >= d_max_output_buffer.size())
317  set_max_output_buffer(port, -1);
318  if((size_t)port >= d_min_output_buffer.size())
319  set_min_output_buffer(port, -1);
320  }
321 
322  /*!
323  * \brief Returns max buffer size on output port \p i.
324  */
325  long max_output_buffer(size_t i) {
326  if(i >= d_max_output_buffer.size())
327  throw std::invalid_argument("gr_basic_block::max_output_buffer: port out of range.");
328  return d_max_output_buffer[i];
329  }
330 
331  /*!
332  * \brief Sets max buffer size on all output ports.
333  */
334  void set_max_output_buffer(long max_output_buffer) {
335  for(int i = 0; i < output_signature()->max_streams(); i++) {
336  set_max_output_buffer(i, max_output_buffer);
337  }
338  }
339 
340  /*!
341  * \brief Sets max buffer size on output port \p port.
342  */
343  void set_max_output_buffer(int port, long max_output_buffer) {
344  if((size_t)port >= d_max_output_buffer.size())
345  d_max_output_buffer.push_back(max_output_buffer);
346  else
347  d_max_output_buffer[port] = max_output_buffer;
348  }
349 
350  /*!
351  * \brief Returns min buffer size on output port \p i.
352  */
353  long min_output_buffer(size_t i) {
354  if(i >= d_min_output_buffer.size())
355  throw std::invalid_argument("gr_basic_block::min_output_buffer: port out of range.");
356  return d_min_output_buffer[i];
357  }
358 
359  /*!
360  * \brief Sets min buffer size on all output ports.
361  */
362  void set_min_output_buffer(long min_output_buffer) {
363  for(int i=0; i<output_signature()->max_streams(); i++) {
364  set_min_output_buffer(i, min_output_buffer);
365  }
366  }
367 
368  /*!
369  * \brief Sets min buffer size on output port \p port.
370  */
371  void set_min_output_buffer(int port, long min_output_buffer) {
372  if((size_t)port >= d_min_output_buffer.size())
373  d_min_output_buffer.push_back(min_output_buffer);
374  else
375  d_min_output_buffer[port] = min_output_buffer;
376  }
377 
378  // --------------- Performance counter functions -------------
379 
380  /*!
381  * \brief Gets average noutput_items performance counter.
382  */
383  float pc_noutput_items();
384 
385  /*!
386  * \brief Gets variance of noutput_items performance counter.
387  */
388  float pc_noutput_items_var();
389 
390  /*!
391  * \brief Gets average num items produced performance counter.
392  */
393  float pc_nproduced();
394 
395  /*!
396  * \brief Gets variance of num items produced performance counter.
397  */
398  float pc_nproduced_var();
399 
400  /*!
401  * \brief Gets average fullness of \p which input buffer.
402  */
403  float pc_input_buffers_full(int which);
404 
405  /*!
406  * \brief Gets variance of fullness of \p which input buffer.
407  */
408  float pc_input_buffers_full_var(int which);
409 
410  /*!
411  * \brief Gets average fullness of all input buffers.
412  */
413  std::vector<float> pc_input_buffers_full();
414 
415  /*!
416  * \brief Gets variance of fullness of all input buffers.
417  */
418  std::vector<float> pc_input_buffers_full_var();
419 
420  /*!
421  * \brief Gets average fullness of \p which input buffer.
422  */
423  float pc_output_buffers_full(int which);
424 
425  /*!
426  * \brief Gets variance of fullness of \p which input buffer.
427  */
428  float pc_output_buffers_full_var(int which);
429 
430  /*!
431  * \brief Gets average fullness of all output buffers.
432  */
433  std::vector<float> pc_output_buffers_full();
434  /*!
435  * \brief Gets variance of fullness of all output buffers.
436  */
437  std::vector<float> pc_output_buffers_full_var();
438 
439  /*!
440  * \brief Gets average clock cycles spent in work.
441  */
442  float pc_work_time();
443 
444  /*!
445  * \brief Gets average clock cycles spent in work.
446  */
447  float pc_work_time_var();
448 
449  /*!
450  * \brief Resets the performance counters
451  */
452  void reset_perf_counters();
453 
454 
455  // ----------------------------------------------------------------------------
456  // Functions to handle thread affinity
457 
458  /*!
459  * \brief Set the thread's affinity to processor core \p n.
460  *
461  * \param mask a vector of unsigned ints of the core numbers available to this block.
462  */
463  void set_processor_affinity(const std::vector<unsigned int> &mask);
464 
465  /*!
466  * \brief Remove processor affinity to a specific core.
467  */
468  void unset_processor_affinity();
469 
470  /*!
471  * \brief Get the current processor affinity.
472  */
473  std::vector<unsigned int> processor_affinity() { return d_affinity; }
474 
475  // ----------------------------------------------------------------------------
476 
477  private:
478 
479  int d_output_multiple;
480  bool d_output_multiple_set;
481  int d_unaligned;
482  bool d_is_unaligned;
483  double d_relative_rate; // approx output_rate / input_rate
484  gr_block_detail_sptr d_detail; // implementation details
485  unsigned d_history;
486  bool d_fixed_rate;
487  bool d_max_noutput_items_set; // if d_max_noutput_items is valid
488  int d_max_noutput_items; // value of max_noutput_items for this block
489  int d_min_noutput_items;
490  tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream
491  std::vector<unsigned int> d_affinity; // thread affinity proc. mask
492 
493  protected:
494  gr_block (void){} //allows pure virtual interface sub-classes
495  gr_block (const std::string &name,
496  gr_io_signature_sptr input_signature,
497  gr_io_signature_sptr output_signature);
498 
499  void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
500 
501 
502  /*!
503  * \brief Adds a new tag onto the given output buffer.
504  *
505  * \param which_output an integer of which output stream to attach the tag
506  * \param abs_offset a uint64 number of the absolute item number
507  * assicated with the tag. Can get from nitems_written.
508  * \param key the tag key as a PMT symbol
509  * \param value any PMT holding any value for the given key
510  * \param srcid optional source ID specifier; defaults to PMT_F
511  */
512  inline void add_item_tag(unsigned int which_output,
513  uint64_t abs_offset,
514  const pmt::pmt_t &key,
515  const pmt::pmt_t &value,
516  const pmt::pmt_t &srcid=pmt::PMT_F)
517  {
518  gr_tag_t tag;
519  tag.offset = abs_offset;
520  tag.key = key;
521  tag.value = value;
522  tag.srcid = srcid;
523  this->add_item_tag(which_output, tag);
524  }
525 
526  /*!
527  * \brief Adds a new tag onto the given output buffer.
528  *
529  * \param which_output an integer of which output stream to attach the tag
530  * \param tag the tag object to add
531  */
532  void add_item_tag(unsigned int which_output, const gr_tag_t &tag);
533 
534  /*!
535  * \brief Removes a tag from the given input buffer.
536  *
537  * \param which_input an integer of which input stream to remove the tag from
538  * \param abs_offset a uint64 number of the absolute item number
539  * assicated with the tag. Can get from nitems_written.
540  * \param key the tag key as a PMT symbol
541  * \param value any PMT holding any value for the given key
542  * \param srcid optional source ID specifier; defaults to PMT_F
543  *
544  * If no such tag is found, does nothing.
545  */
546  inline void remove_item_tag(unsigned int which_input,
547  uint64_t abs_offset,
548  const pmt::pmt_t &key,
549  const pmt::pmt_t &value,
550  const pmt::pmt_t &srcid=pmt::PMT_F)
551  {
552  gr_tag_t tag;
553  tag.offset = abs_offset;
554  tag.key = key;
555  tag.value = value;
556  tag.srcid = srcid;
557  this->remove_item_tag(which_input, tag);
558  }
559 
560  /*!
561  * \brief Removes a tag from the given input buffer.
562  *
563  * If no such tag is found, does nothing.
564  *
565  * \param which_input an integer of which input stream to remove the tag from
566  * \param tag the tag object to remove
567  */
568  void remove_item_tag(unsigned int which_input, const gr_tag_t &tag);
569 
570  /*!
571  * \brief Given a [start,end), returns a vector of all tags in the range.
572  *
573  * Range of counts is from start to end-1.
574  *
575  * Tags are tuples of:
576  * (item count, source id, key, value)
577  *
578  * \param v a vector reference to return tags into
579  * \param which_input an integer of which input stream to pull from
580  * \param abs_start a uint64 count of the start of the range of interest
581  * \param abs_end a uint64 count of the end of the range of interest
582  */
583  void get_tags_in_range(std::vector<gr_tag_t> &v,
584  unsigned int which_input,
585  uint64_t abs_start,
586  uint64_t abs_end);
587 
588  /*!
589  * \brief Given a [start,end), returns a vector of all tags in the range
590  * with a given key.
591  *
592  * Range of counts is from start to end-1.
593  *
594  * Tags are tuples of:
595  * (item count, source id, key, value)
596  *
597  * \param v a vector reference to return tags into
598  * \param which_input an integer of which input stream to pull from
599  * \param abs_start a uint64 count of the start of the range of interest
600  * \param abs_end a uint64 count of the end of the range of interest
601  * \param key a PMT symbol key to filter only tags of this key
602  */
603  void get_tags_in_range(std::vector<gr_tag_t> &v,
604  unsigned int which_input,
605  uint64_t abs_start,
606  uint64_t abs_end,
607  const pmt::pmt_t &key);
608 
609  std::vector<long> d_max_output_buffer;
610  std::vector<long> d_min_output_buffer;
611 
612  /*! Used by block's setters and work functions to make
613  * setting/resetting of parameters thread-safe.
614  *
615  * Used by calling gruel::scoped_lock l(d_setlock);
616  */
618 
619  // These are really only for internal use, but leaving them public avoids
620  // having to work up an ever-varying list of friend GR_CORE_APIs
621 
622  public:
623  gr_block_detail_sptr detail () const { return d_detail; }
624  void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
625 };
626 
627 typedef std::vector<gr_block_sptr> gr_block_vector_t;
628 typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t;
629 
630 inline gr_block_sptr cast_to_block_sptr(gr_basic_block_sptr p)
631 {
632  return boost::dynamic_pointer_cast<gr_block, gr_basic_block>(p);
633 }
634 
635 
636 std::ostream&
637 operator << (std::ostream& os, const gr_block *m);
638 
639 #endif /* INCLUDED_GR_BLOCK_H */