//
// 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*/