GNU Radio 3.6.0 C++ API
gr_block_detail.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2004,2009,2010,2011 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 detail.
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_BLOCK_DETAIL_H
00024 #define INCLUDED_GR_BLOCK_DETAIL_H
00025 
00026 #include <gr_core_api.h>
00027 #include <gr_runtime_types.h>
00028 #include <gr_tpb_detail.h>
00029 #include <gr_tags.h>
00030 #include <stdexcept>
00031 #include <gruel/thread.h>
00032 #include <map>
00033 #include <queue>
00034 
00035 /*!
00036  * \brief Implementation details to support the signal processing abstraction
00037  * \ingroup internal
00038  *
00039  * This class contains implementation detail that should be "out of sight"
00040  * of almost all users of GNU Radio.  This decoupling also means that
00041  * we can make changes to the guts without having to recompile everything.
00042  */
00043 class GR_CORE_API gr_block_detail {
00044  public:
00045   ~gr_block_detail ();
00046 
00047   int ninputs () const { return d_ninputs; }
00048   int noutputs () const { return d_noutputs; }
00049   bool sink_p () const { return d_noutputs == 0; }
00050   bool source_p () const { return d_ninputs == 0; }
00051 
00052   void set_done (bool done);
00053   bool done () const { return d_done; }
00054 
00055   void set_input (unsigned int which, gr_buffer_reader_sptr reader);
00056   gr_buffer_reader_sptr input (unsigned int which)
00057   {
00058     if (which >= d_ninputs)
00059       throw std::invalid_argument ("gr_block_detail::input");
00060     return d_input[which];
00061   }
00062 
00063   void set_output (unsigned int which, gr_buffer_sptr buffer);
00064   gr_buffer_sptr output (unsigned int which)
00065   {
00066     if (which >= d_noutputs)
00067       throw std::invalid_argument ("gr_block_detail::output");
00068     return d_output[which];
00069   }
00070 
00071   /*!
00072    * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed.
00073    */
00074   void consume (int which_input, int how_many_items);
00075 
00076   /*!
00077    * \brief Tell the scheduler \p how_many_items were consumed on each input stream.
00078    */
00079   void consume_each (int how_many_items);
00080 
00081   /*!
00082    * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output.
00083    */
00084   void produce (int which_output, int how_many_items);
00085 
00086   /*!
00087    * \brief Tell the scheduler \p how_many_items were produced on each output stream.
00088    */
00089   void produce_each (int how_many_items);
00090 
00091   /*!
00092    * Accept msg, place in queue, arrange for thread to be awakened if it's not already.
00093    */
00094   void _post(pmt::pmt_t msg);
00095 
00096   // Return the number of items read on input stream which_input
00097   uint64_t nitems_read(unsigned int which_input);
00098 
00099   // Return the number of items written on output stream which_output
00100   uint64_t nitems_written(unsigned int which_output);
00101 
00102 
00103   /*!
00104    * \brief  Adds a new tag to the given output stream.
00105    *
00106    * This takes the input parameters and builds a PMT tuple
00107    * from it. It then calls gr_buffer::add_item_tag(pmt::pmt_t t),
00108    * which appends the tag onto its deque.
00109    *
00110    * \param which_output  an integer of which output stream to attach the tag
00111    * \param tag the tag object to add
00112    */
00113   void add_item_tag(unsigned int which_output, const gr_tag_t &tag);
00114 
00115   /*!
00116    * \brief Given a [start,end), returns a vector of all tags in the range.
00117    *
00118    * Pass-through function to gr_buffer_reader to get a vector of tags
00119    * in given range. Range of counts is from start to end-1.
00120    *
00121    * Tags are tuples of:
00122    *      (item count, source id, key, value)
00123    *
00124    * \param v            a vector reference to return tags into
00125    * \param which_input  an integer of which input stream to pull from
00126    * \param abs_start    a uint64 count of the start of the range of interest
00127    * \param abs_end      a uint64 count of the end of the range of interest
00128    */
00129   void get_tags_in_range(std::vector<gr_tag_t> &v,
00130                          unsigned int which_input,
00131                          uint64_t abs_start,
00132                          uint64_t abs_end);
00133 
00134   /*!
00135    * \brief Given a [start,end), returns a vector of all tags in the range
00136    * with a given key.
00137    *
00138    * Calls get_tags_in_range(which_input, abs_start, abs_end) to get a vector of
00139    * tags from the buffers. This function then provides a secondary filter to
00140    * the tags to extract only tags with the given 'key'.
00141    *
00142    * Tags are tuples of:
00143    *      (item count, source id, key, value)
00144    *
00145    * \param v            a vector reference to return tags into
00146    * \param which_input  an integer of which input stream to pull from
00147    * \param abs_start    a uint64 count of the start of the range of interest
00148    * \param abs_end      a uint64 count of the end of the range of interest
00149    * \param key          a PMT symbol to select only tags of this key
00150    */
00151   void get_tags_in_range(std::vector<gr_tag_t> &v,
00152                          unsigned int which_input,
00153                          uint64_t abs_start,
00154                          uint64_t abs_end,
00155                          const pmt::pmt_t &key);
00156 
00157   gr_tpb_detail                      d_tpb;     // used by thread-per-block scheduler
00158   int                                d_produce_or;
00159 
00160   //! Enqueue a message into the block
00161   void push_msg_queue(const gr_tag_t &msg);
00162 
00163   //! Is a message available
00164   bool check_msg_queue(void);
00165 
00166   //! Pop a message from the queue
00167   gr_tag_t pop_msg_queue(void);
00168 
00169   //! Map of group names to list of message subscribers
00170   std::map<std::string, std::vector<gr_block_sptr> > d_msg_subscribers;
00171 
00172   //! The queue of incoming messages
00173   std::queue<gr_tag_t> d_msg_queue;
00174   gruel::mutex d_msg_queue_mutex;
00175   gruel::condition_variable d_msg_queue_condition_variable;
00176 
00177   // ----------------------------------------------------------------------------
00178 
00179  private:
00180   unsigned int                       d_ninputs;
00181   unsigned int                       d_noutputs;
00182   std::vector<gr_buffer_reader_sptr> d_input;
00183   std::vector<gr_buffer_sptr>        d_output;
00184   bool                               d_done;
00185 
00186   gr_block_detail (unsigned int ninputs, unsigned int noutputs);
00187 
00188   friend struct gr_tpb_detail;
00189 
00190   friend GR_CORE_API gr_block_detail_sptr
00191   gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
00192 };
00193 
00194 GR_CORE_API gr_block_detail_sptr
00195 gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
00196 
00197 GR_CORE_API long
00198 gr_block_detail_ncurrently_allocated ();
00199 
00200 #endif /* INCLUDED_GR_BLOCK_DETAIL_H */