// // Copyright 2012 Josh Blum // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . #ifndef INCLUDED_GNURADIO_BLOCK_HPP #define INCLUDED_GNURADIO_BLOCK_HPP #include #include #include #include #include #include namespace gnuradio { template struct WorkBuffer { //! get a native pointer type to this buffer inline PtrType get(void) const { return _mem; } //! get a pointer of the desired type to this buffer template inline T cast(void) const { return reinterpret_cast(this->get()); } //! get the number of items in this buffer inline size_t size(void) const { return _len; } //! Get the memory pointer reference inline PtrType &get(void) { return _mem; } //! Get the buffer length reference inline size_t &size(void) { return _len; } PtrType _mem; size_t _len; }; struct GRAS_API Block : Element { enum { WORK_CALLED_PRODUCE = -2, WORK_DONE = -1 }; enum tag_propagation_policy_t { TPP_DONT = 0, TPP_ALL_TO_ALL = 1, TPP_ONE_TO_ONE = 2 }; Block(void); Block(const std::string &name); /******************************************************************* * Basic routines from basic block ******************************************************************/ //! Get the number of history items (default 0) size_t input_history(const size_t which_input = 0) const; /*! * Set the number of items that will be saved from the previous run. * Input buffers will begin with an overlap of the previous's buffer's * num history items. This is used to implement sample memory for * things like sliding dot products/FIR filters. */ void set_input_history(const size_t history, const size_t which_input = 0); void set_output_multiple(const size_t multiple, const size_t which_output = 0); size_t output_multiple(const size_t which_output = 0) const; void consume(const size_t which_input, const size_t how_many_items); void consume_each(const size_t how_many_items); void produce(const size_t which_output, const size_t how_many_items); /*! * Set buffer inlining for this input. * Inlining means that the input buffer can be used as an output buffer. * The goal is to make better use of cache and memory bandwidth. * * By default, inlining is disabled on all input ports. * The user should enable inlining on an input port * when it is understood that the work function will read * before writting to a particular section of the buffer. * * The scheduler will inline a buffer when * * inlining is enabled on the particular input port * * block holds the only buffer reference aka unique * * the input buffer has the same affinity as the block * * the input port has a buffer history of 0 items */ void set_input_inline(const size_t which_input, const bool enb); //! Get the buffer inlining state bool input_inline(const size_t which_input) const; /*! * Enable fixed rate logic. * When enabled, relative rate is assumed to be set, * and forecast is automatically called. * Also, consume will be called automatically. */ void set_fixed_rate(const bool fixed_rate); /*! * The relative rate can be thought of as interpolation/decimation. * In other words, relative rate is the ratio of output items to input items. */ void set_relative_rate(double relative_rate); double relative_rate(void) const; /******************************************************************* * Tag related routines from basic block ******************************************************************/ uint64_t nitems_read(const size_t which_input); uint64_t nitems_written(const size_t which_output); tag_propagation_policy_t tag_propagation_policy(void); void set_tag_propagation_policy(tag_propagation_policy_t p); void add_item_tag( const size_t which_output, const Tag &tag ); void add_item_tag( const size_t which_output, uint64_t abs_offset, const pmt::pmt_t &key, const pmt::pmt_t &value, const pmt::pmt_t &srcid=pmt::PMT_F ); void get_tags_in_range( std::vector &tags, const size_t which_input, uint64_t abs_start, uint64_t abs_end ); void get_tags_in_range( std::vector &tags, const size_t which_input, uint64_t abs_start, uint64_t abs_end, const pmt::pmt_t &key ); /******************************************************************* * Work related routines from basic block ******************************************************************/ //! Called when the flow graph is started, can overload virtual bool start(void); //! Called when the flow graph is stopped, can overload virtual bool stop(void); typedef std::vector > InputItems; typedef std::vector > OutputItems; //! The official call into the work routine (overload please) virtual int Work( const InputItems &input_items, const OutputItems &output_items ) = 0; //! forcast requirements, can be overloaded virtual void forecast( int noutput_items, std::vector &ninput_items_required ); //! scheduler calls when the topology is updated, can be overloaded virtual bool check_topology(int ninputs, int noutputs); /******************************************************************* * routines related to affinity and allocation ******************************************************************/ /*! * Set the node affinity of this block. * This call affects how output buffers are allocated. * By default memory is allocated by malloc. * When the affinity is set, virtual memory * will be locked to a physical CPU/memory node. */ void set_buffer_affinity(const Affinity &affinity); /*! * The output buffer allocator method. * This method is called by the scheduler to allocate output buffers. * The user may overload this method to create a custom allocator. * * Example use case: * //TODO code example * * \param which_output the output port index number * \param token the token for the buffer's returner * \param recommend_length the schedulers recommended length in bytes * \return the token used for the buffer allocation (may be the same) */ virtual SBufferToken output_buffer_allocator( const size_t which_output, const SBufferToken &token, const size_t recommend_length ); /*! * The input buffer allocator method. * This method is special and very different from allocate output buffers. * Typically, blocks do not have control of their input buffers. * When overloaded, an upstream block will ask this block * to allocate its output buffers. This way, this block will get * input buffers which were actually allocated by this method. * * \param which_input the input port index number * \param token the token for the buffer's returner * \param recommend_length the schedulers recommended length in bytes * \return the token used for the buffer allocation (may be the same) */ virtual SBufferToken input_buffer_allocator( const size_t which_input, const SBufferToken &token, const size_t recommend_length ); }; } //namespace gnuradio #endif /*INCLUDED_GNURADIO_BLOCK_HPP*/