GNU Radio 3.7.1 C++ API
block.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc.
00004  *
00005  * This file is part of GNU Radio
00006  *
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  *
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_GR_RUNTIME_BLOCK_H
00024 #define INCLUDED_GR_RUNTIME_BLOCK_H
00025 
00026 #include <gnuradio/api.h>
00027 #include <gnuradio/basic_block.h>
00028 #include <gnuradio/tags.h>
00029 #include <gnuradio/logger.h>
00030 
00031 namespace gr {
00032 
00033   /*!
00034    * \brief The abstract base class for all 'terminal' processing blocks.
00035    * \ingroup base_blk
00036    *
00037    * A signal processing flow is constructed by creating a tree of
00038    * hierarchical blocks, which at any level may also contain terminal
00039    * nodes that actually implement signal processing functions. This
00040    * is the base class for all such leaf nodes.
00041    *
00042    * Blocks have a set of input streams and output streams.  The
00043    * input_signature and output_signature define the number of input
00044    * streams and output streams respectively, and the type of the data
00045    * items in each stream.
00046    *
00047    * Although blocks may consume data on each input stream at a
00048    * different rate, all outputs streams must produce data at the same
00049    * rate.  That rate may be different from any of the input rates.
00050    *
00051    * User derived blocks override two methods, forecast and
00052    * general_work, to implement their signal processing
00053    * behavior. forecast is called by the system scheduler to determine
00054    * how many items are required on each input stream in order to
00055    * produce a given number of output items.
00056    *
00057    * general_work is called to perform the signal processing in the
00058    * block.  It reads the input items and writes the output items.
00059    */
00060   class GR_RUNTIME_API block : public basic_block
00061   {
00062   public:
00063 
00064     //! Magic return values from general_work
00065     enum {
00066       WORK_CALLED_PRODUCE = -2,
00067       WORK_DONE = -1
00068     };
00069 
00070     enum tag_propagation_policy_t {
00071       TPP_DONT = 0,
00072       TPP_ALL_TO_ALL = 1,
00073       TPP_ONE_TO_ONE = 2
00074     };
00075 
00076     virtual ~block();
00077 
00078     /*!
00079      * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
00080      * History is the number of x_i's that are examined to produce one y_i.
00081      * This comes in handy for FIR filters, where we use history to
00082      * ensure that our input contains the appropriate "history" for the
00083      * filter. History should be equal to the number of filter taps.
00084      */
00085     unsigned history() const { return d_history; }
00086     void  set_history(unsigned history) { d_history = history; }
00087 
00088     /*!
00089      * \brief Return true if this block has a fixed input to output rate.
00090      *
00091      * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
00092      */
00093     bool fixed_rate() const { return d_fixed_rate; }
00094 
00095     // ----------------------------------------------------------------
00096     //          override these to define your behavior
00097     // ----------------------------------------------------------------
00098 
00099     /*!
00100      * \brief  Estimate input requirements given output request
00101      *
00102      * \param noutput_items           number of output items to produce
00103      * \param ninput_items_required   number of input items required on each input stream
00104      *
00105      * Given a request to product \p noutput_items, estimate the
00106      * number of data items required on each input stream.  The
00107      * estimate doesn't have to be exact, but should be close.
00108      */
00109     virtual void forecast(int noutput_items,
00110                           gr_vector_int &ninput_items_required);
00111 
00112     /*!
00113      * \brief compute output items from input items
00114      *
00115      * \param noutput_items     number of output items to write on each output stream
00116      * \param ninput_items      number of input items available on each input stream
00117      * \param input_items       vector of pointers to the input items, one entry per input stream
00118      * \param output_items      vector of pointers to the output items, one entry per output stream
00119      *
00120      * \returns number of items actually written to each output stream, or -1 on EOF.
00121      * It is OK to return a value less than noutput_items.  -1 <= return value <= noutput_items
00122      *
00123      * general_work must call consume or consume_each to indicate how
00124      * many items were consumed on each input stream.
00125      */
00126     virtual int general_work(int noutput_items,
00127                              gr_vector_int &ninput_items,
00128                              gr_vector_const_void_star &input_items,
00129                              gr_vector_void_star &output_items);
00130 
00131     /*!
00132      * \brief Called to enable drivers, etc for i/o devices.
00133      *
00134      * This allows a block to enable an associated driver to begin
00135      * transfering data just before we start to execute the scheduler.
00136      * The end result is that this reduces latency in the pipeline
00137      * when dealing with audio devices, usrps, etc.
00138      */
00139     virtual bool start();
00140 
00141     /*!
00142      * \brief Called to disable drivers, etc for i/o devices.
00143      */
00144     virtual bool stop();
00145 
00146     // ----------------------------------------------------------------
00147 
00148     /*!
00149      * \brief Constrain the noutput_items argument passed to forecast and general_work
00150      *
00151      * set_output_multiple causes the scheduler to ensure that the
00152      * noutput_items argument passed to forecast and general_work will
00153      * be an integer multiple of \param multiple The default value of
00154      * output multiple is 1.
00155      */
00156     void set_output_multiple(int multiple);
00157     int  output_multiple() const { return d_output_multiple; }
00158     bool output_multiple_set() const { return d_output_multiple_set; }
00159 
00160     /*!
00161      * \brief Constrains buffers to work on a set item alignment (for SIMD)
00162      *
00163      * set_alignment_multiple causes the scheduler to ensure that the
00164      * noutput_items argument passed to forecast and general_work will
00165      * be an integer multiple of \param multiple The default value is
00166      * 1.
00167      *
00168      * This control is similar to the output_multiple setting, except
00169      * that if the number of items passed to the block is less than
00170      * the output_multiple, this value is ignored and the block can
00171      * produce like normal. The d_unaligned value is set to the number
00172      * of items the block is off by. In the next call to general_work,
00173      * the noutput_items is set to d_unaligned or less until
00174      * d_unaligned==0. The buffers are now aligned again and the
00175      * aligned calls can be performed again.
00176      */
00177     void set_alignment(int multiple);
00178     int  alignment() const { return d_output_multiple; }
00179 
00180     void set_unaligned(int na);
00181     int  unaligned() const { return d_unaligned; }
00182     void set_is_unaligned(bool u);
00183     bool is_unaligned() const { return d_is_unaligned; }
00184 
00185     /*!
00186      * \brief Tell the scheduler \p how_many_items of input stream \p
00187      * which_input were consumed.
00188      */
00189     void consume(int which_input, int how_many_items);
00190 
00191     /*!
00192      * \brief Tell the scheduler \p how_many_items were consumed on
00193      * each input stream.
00194      */
00195     void consume_each(int how_many_items);
00196 
00197     /*!
00198      * \brief Tell the scheduler \p how_many_items were produced on
00199      * output stream \p which_output.
00200      *
00201      * If the block's general_work method calls produce, \p
00202      * general_work must return WORK_CALLED_PRODUCE.
00203      */
00204     void produce(int which_output, int how_many_items);
00205 
00206     /*!
00207      * \brief Set the approximate output rate / input rate
00208      *
00209      * Provide a hint to the buffer allocator and scheduler.
00210      * The default relative_rate is 1.0
00211      *
00212      * decimators have relative_rates < 1.0
00213      * interpolators have relative_rates > 1.0
00214      */
00215     void set_relative_rate(double relative_rate);
00216 
00217     /*!
00218      * \brief return the approximate output rate / input rate
00219      */
00220     double relative_rate() const { return d_relative_rate; }
00221 
00222     /*
00223      * The following two methods provide special case info to the
00224      * scheduler in the event that a block has a fixed input to output
00225      * ratio.  sync_block, sync_decimator and
00226      * sync_interpolator override these.  If you're fixed rate,
00227      * subclass one of those.
00228      */
00229     /*!
00230      * \brief Given ninput samples, return number of output samples that will be produced.
00231      * N.B. this is only defined if fixed_rate returns true.
00232      * Generally speaking, you don't need to override this.
00233      */
00234     virtual int fixed_rate_ninput_to_noutput(int ninput);
00235 
00236     /*!
00237      * \brief Given noutput samples, return number of input samples required to produce noutput.
00238      * N.B. this is only defined if fixed_rate returns true.
00239      * Generally speaking, you don't need to override this.
00240      */
00241     virtual int fixed_rate_noutput_to_ninput(int noutput);
00242 
00243     /*!
00244      * \brief Return the number of items read on input stream which_input
00245      */
00246     uint64_t nitems_read(unsigned int which_input);
00247 
00248     /*!
00249      * \brief  Return the number of items written on output stream which_output
00250      */
00251     uint64_t nitems_written(unsigned int which_output);
00252 
00253     /*!
00254      * \brief Asks for the policy used by the scheduler to moved tags downstream.
00255      */
00256     tag_propagation_policy_t tag_propagation_policy();
00257 
00258     /*!
00259      * \brief Set the policy by the scheduler to determine how tags are moved downstream.
00260      */
00261     void set_tag_propagation_policy(tag_propagation_policy_t p);
00262 
00263     /*!
00264      * \brief Return the minimum number of output items this block can
00265      * produce during a call to work.
00266      *
00267      * Should be 0 for most blocks.  Useful if we're dealing with
00268      * packets and the block produces one packet per call to work.
00269      */
00270     int min_noutput_items() const { return d_min_noutput_items; }
00271 
00272     /*!
00273      * \brief Set the minimum number of output items this block can
00274      * produce during a call to work.
00275      *
00276      * \param m the minimum noutput_items this block can produce.
00277      */
00278     void set_min_noutput_items(int m) { d_min_noutput_items = m; }
00279 
00280     /*!
00281      * \brief Return the maximum number of output items this block will
00282      * handle during a call to work.
00283      */
00284     int max_noutput_items();
00285 
00286     /*!
00287      * \brief Set the maximum number of output items this block will
00288      * handle during a call to work.
00289      *
00290      * \param m the maximum noutput_items this block will handle.
00291      */
00292     void set_max_noutput_items(int m);
00293 
00294     /*!
00295      * \brief Clear the switch for using the max_noutput_items value of this block.
00296      *
00297      * When is_set_max_noutput_items() returns 'true', the scheduler
00298      * will use the value returned by max_noutput_items() to limit the
00299      * size of the number of items possible for this block's work
00300      * function. If is_set_max_notput_items() returns 'false', then
00301      * the scheduler ignores the internal value and uses the value set
00302      * globally in the top_block.
00303      *
00304      * Use this value to clear the 'is_set' flag so the scheduler will
00305      * ignore this. Use the set_max_noutput_items(m) call to both set
00306      * a new value for max_noutput_items and to reenable its use in
00307      * the scheduler.
00308      */
00309     void unset_max_noutput_items();
00310 
00311     /*!
00312      * \brief Ask the block if the flag is or is not set to use the
00313      * internal value of max_noutput_items during a call to work.
00314      */
00315     bool is_set_max_noutput_items();
00316 
00317     /*
00318      * Used to expand the vectors that hold the min/max buffer sizes.
00319      *
00320      * Specifically, when -1 is used, the vectors are just initialized
00321      * with 1 value; this is used by the flat_flowgraph to expand when
00322      * required to add a new value for new ports on these blocks.
00323      */
00324     void expand_minmax_buffer(int port);
00325 
00326     /*!
00327      * \brief Returns max buffer size on output port \p i.
00328      */
00329     long max_output_buffer(size_t i);
00330 
00331     /*!
00332      * \brief Sets max buffer size on all output ports.
00333      */
00334     void set_max_output_buffer(long max_output_buffer);
00335 
00336     /*!
00337      * \brief Sets max buffer size on output port \p port.
00338      */
00339     void set_max_output_buffer(int port, long max_output_buffer);
00340 
00341     /*!
00342      * \brief Returns min buffer size on output port \p i.
00343      */
00344     long min_output_buffer(size_t i);
00345 
00346     /*!
00347      * \brief Sets min buffer size on all output ports.
00348      */
00349     void set_min_output_buffer(long min_output_buffer);
00350 
00351     /*!
00352      * \brief Sets min buffer size on output port \p port.
00353      */
00354     void set_min_output_buffer(int port, long min_output_buffer);
00355 
00356     // --------------- Performance counter functions -------------
00357 
00358     /*!
00359      * \brief Gets instantaneous noutput_items performance counter.
00360      */
00361     float pc_noutput_items();
00362 
00363     /*!
00364      * \brief Gets average noutput_items performance counter.
00365      */
00366     float pc_noutput_items_avg();
00367 
00368     /*!
00369      * \brief Gets variance of noutput_items performance counter.
00370      */
00371     float pc_noutput_items_var();
00372 
00373     /*!
00374      * \brief Gets instantaneous num items produced performance counter.
00375      */
00376     float pc_nproduced();
00377 
00378     /*!
00379      * \brief Gets average num items produced performance counter.
00380      */
00381     float pc_nproduced_avg();
00382 
00383     /*!
00384      * \brief Gets variance of  num items produced performance counter.
00385      */
00386     float pc_nproduced_var();
00387 
00388     /*!
00389      * \brief Gets instantaneous fullness of \p which input buffer.
00390      */
00391     float pc_input_buffers_full(int which);
00392 
00393     /*!
00394      * \brief Gets average fullness of \p which input buffer.
00395      */
00396     float pc_input_buffers_full_avg(int which);
00397 
00398     /*!
00399      * \brief Gets variance of fullness of \p which input buffer.
00400      */
00401     float pc_input_buffers_full_var(int which);
00402 
00403     /*!
00404      * \brief Gets instantaneous fullness of all input buffers.
00405      */
00406     std::vector<float> pc_input_buffers_full();
00407 
00408     /*!
00409      * \brief Gets average fullness of all input buffers.
00410      */
00411     std::vector<float> pc_input_buffers_full_avg();
00412 
00413     /*!
00414      * \brief Gets variance of fullness of all input buffers.
00415      */
00416     std::vector<float> pc_input_buffers_full_var();
00417 
00418     /*!
00419      * \brief Gets instantaneous fullness of \p which input buffer.
00420      */
00421     float pc_output_buffers_full(int which);
00422 
00423     /*!
00424      * \brief Gets average fullness of \p which input buffer.
00425      */
00426     float pc_output_buffers_full_avg(int which);
00427 
00428     /*!
00429      * \brief Gets variance of fullness of \p which input buffer.
00430      */
00431     float pc_output_buffers_full_var(int which);
00432 
00433     /*!
00434      * \brief Gets instantaneous fullness of all output buffers.
00435      */
00436     std::vector<float> pc_output_buffers_full();
00437 
00438     /*!
00439      * \brief Gets average fullness of all output buffers.
00440      */
00441     std::vector<float> pc_output_buffers_full_avg();
00442 
00443     /*!
00444      * \brief Gets variance of fullness of all output buffers.
00445      */
00446     std::vector<float> pc_output_buffers_full_var();
00447 
00448     /*!
00449      * \brief Gets instantaneous clock cycles spent in work.
00450      */
00451     float pc_work_time();
00452 
00453     /*!
00454      * \brief Gets average clock cycles spent in work.
00455      */
00456     float pc_work_time_avg();
00457 
00458     /*!
00459      * \brief Gets average clock cycles spent in work.
00460      */
00461     float pc_work_time_var();
00462 
00463     /*!
00464      * \brief Resets the performance counters
00465      */
00466     void reset_perf_counters();
00467 
00468     /*!
00469      * \brief Sets up export of perf. counters to ControlPort. Only
00470      * called by the scheduler.
00471      */
00472     void setup_pc_rpc();
00473 
00474     /*!
00475      * \brief Checks if this block is already exporting perf. counters
00476      * to ControlPort.
00477      */
00478     bool is_pc_rpc_set() { return d_pc_rpc_set; }
00479 
00480     /*!
00481      * \brief If the block calls this in its constructor, it's
00482      * perf. counters will not be exported.
00483      */
00484     void no_pc_rpc() { d_pc_rpc_set = true; }
00485 
00486 
00487     // ----------------------------------------------------------------------------
00488     // Functions to handle thread affinity
00489 
00490     /*!
00491      * \brief Set the thread's affinity to processor core \p n.
00492      *
00493      * \param mask a vector of ints of the core numbers available to this block.
00494      */
00495     void set_processor_affinity(const std::vector<int> &mask);
00496 
00497     /*!
00498      * \brief Remove processor affinity to a specific core.
00499      */
00500     void unset_processor_affinity();
00501 
00502     /*!
00503      * \brief Get the current processor affinity.
00504      */
00505     std::vector<int> processor_affinity() { return d_affinity; }
00506 
00507     /*!
00508      * \brief Get the current thread priority in use
00509      */
00510     int active_thread_priority();
00511 
00512     /*!
00513      * \brief Get the current thread priority stored
00514      */
00515     int thread_priority();
00516 
00517     /*!
00518      * \brief Set the current thread priority
00519      */
00520     int set_thread_priority(int priority);
00521 
00522     // ----------------------------------------------------------------------------
00523 
00524   private:
00525     int                   d_output_multiple;
00526     bool                  d_output_multiple_set;
00527     int                   d_unaligned;
00528     bool                  d_is_unaligned;
00529     double                d_relative_rate;      // approx output_rate / input_rate
00530     block_detail_sptr     d_detail;             // implementation details
00531     unsigned              d_history;
00532     bool                  d_fixed_rate;
00533     bool                  d_max_noutput_items_set;     // if d_max_noutput_items is valid
00534     int                   d_max_noutput_items;         // value of max_noutput_items for this block
00535     int                   d_min_noutput_items;
00536     tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream
00537     std::vector<int>      d_affinity;              // thread affinity proc. mask
00538     int                   d_priority;              // thread priority level
00539     bool                  d_pc_rpc_set;
00540 
00541   protected:
00542     block(void) {} // allows pure virtual interface sub-classes
00543     block(const std::string &name,
00544           gr::io_signature::sptr input_signature,
00545           gr::io_signature::sptr output_signature);
00546 
00547     void set_fixed_rate(bool fixed_rate) { d_fixed_rate = fixed_rate; }
00548 
00549     /*!
00550      * \brief  Adds a new tag onto the given output buffer.
00551      *
00552      * \param which_output an integer of which output stream to attach the tag
00553      * \param abs_offset   a uint64 number of the absolute item number
00554      *                     assicated with the tag. Can get from nitems_written.
00555      * \param key          the tag key as a PMT symbol
00556      * \param value        any PMT holding any value for the given key
00557      * \param srcid        optional source ID specifier; defaults to PMT_F
00558      */
00559     inline void add_item_tag(unsigned int which_output,
00560                              uint64_t abs_offset,
00561                              const pmt::pmt_t &key,
00562                              const pmt::pmt_t &value,
00563                              const pmt::pmt_t &srcid=pmt::PMT_F)
00564     {
00565       tag_t tag;
00566       tag.offset = abs_offset;
00567       tag.key = key;
00568       tag.value = value;
00569       tag.srcid = srcid;
00570       this->add_item_tag(which_output, tag);
00571     }
00572 
00573     /*!
00574      * \brief  Adds a new tag onto the given output buffer.
00575      *
00576      * \param which_output an integer of which output stream to attach the tag
00577      * \param tag the tag object to add
00578      */
00579     void add_item_tag(unsigned int which_output, const tag_t &tag);
00580 
00581     /*!
00582      * \brief  Removes a tag from the given input buffer.
00583      *
00584      * \param which_input an integer of which input stream to remove the tag from
00585      * \param abs_offset   a uint64 number of the absolute item number
00586      *                     assicated with the tag. Can get from nitems_written.
00587      * \param key          the tag key as a PMT symbol
00588      * \param value        any PMT holding any value for the given key
00589      * \param srcid        optional source ID specifier; defaults to PMT_F
00590      *
00591      * If no such tag is found, does nothing.
00592      */
00593     inline void remove_item_tag(unsigned int which_input,
00594                                 uint64_t abs_offset,
00595                                 const pmt::pmt_t &key,
00596                                 const pmt::pmt_t &value,
00597                                 const pmt::pmt_t &srcid=pmt::PMT_F)
00598     {
00599       tag_t tag;
00600       tag.offset = abs_offset;
00601       tag.key = key;
00602       tag.value = value;
00603       tag.srcid = srcid;
00604       this->remove_item_tag(which_input, tag);
00605     }
00606 
00607     /*!
00608      * \brief Removes a tag from the given input buffer.
00609      *
00610      * If no such tag is found, does nothing.
00611      *
00612      * \param which_input an integer of which input stream to remove the tag from
00613      * \param tag the tag object to remove
00614      */
00615     void remove_item_tag(unsigned int which_input, const tag_t &tag);
00616 
00617     /*!
00618      * \brief Given a [start,end), returns a vector of all tags in the range.
00619      *
00620      * Range of counts is from start to end-1.
00621      *
00622      * Tags are tuples of:
00623      *      (item count, source id, key, value)
00624      *
00625      * \param v            a vector reference to return tags into
00626      * \param which_input  an integer of which input stream to pull from
00627      * \param abs_start    a uint64 count of the start of the range of interest
00628      * \param abs_end      a uint64 count of the end of the range of interest
00629      */
00630     void get_tags_in_range(std::vector<tag_t> &v,
00631                            unsigned int which_input,
00632                            uint64_t abs_start,
00633                            uint64_t abs_end);
00634 
00635     /*!
00636      * \brief Given a [start,end), returns a vector of all tags in the
00637      * range with a given key.
00638      *
00639      * Range of counts is from start to end-1.
00640      *
00641      * Tags are tuples of:
00642      *      (item count, source id, key, value)
00643      *
00644      * \param v            a vector reference to return tags into
00645      * \param which_input  an integer of which input stream to pull from
00646      * \param abs_start    a uint64 count of the start of the range of interest
00647      * \param abs_end      a uint64 count of the end of the range of interest
00648      * \param key          a PMT symbol key to filter only tags of this key
00649      */
00650     void get_tags_in_range(std::vector<tag_t> &v,
00651                            unsigned int which_input,
00652                            uint64_t abs_start,
00653                            uint64_t abs_end,
00654                            const pmt::pmt_t &key);
00655 
00656     std::vector<long> d_max_output_buffer;
00657     std::vector<long> d_min_output_buffer;
00658 
00659     /*! Used by block's setters and work functions to make
00660      * setting/resetting of parameters thread-safe.
00661      *
00662      * Used by calling gr::thread::scoped_lock l(d_setlock);
00663      */ 
00664     gr::thread::mutex d_setlock;
00665 
00666     /*! Used by blocks to access the logger system.
00667      */ 
00668     gr::logger_ptr d_logger;
00669     gr::logger_ptr d_debug_logger;
00670 
00671     // These are really only for internal use, but leaving them public avoids
00672     // having to work up an ever-varying list of friend GR_RUNTIME_APIs
00673 
00674   public:
00675     block_detail_sptr detail() const { return d_detail; }
00676     void set_detail(block_detail_sptr detail) { d_detail = detail; }
00677   };
00678 
00679   typedef std::vector<block_sptr> block_vector_t;
00680   typedef std::vector<block_sptr>::iterator block_viter_t;
00681 
00682   inline block_sptr cast_to_block_sptr(basic_block_sptr p)
00683   {
00684     return boost::dynamic_pointer_cast<block, basic_block>(p);
00685   }
00686 
00687   std::ostream&
00688   operator << (std::ostream& os, const block *m);
00689 
00690 } /* namespace gr */
00691 
00692 #endif /* INCLUDED_GR_RUNTIME_BLOCK_H */