summaryrefslogtreecommitdiff
path: root/include/gras/block.hpp
diff options
context:
space:
mode:
authorJosh Blum2012-10-28 22:39:39 -0700
committerJosh Blum2012-10-28 22:39:39 -0700
commit77f79c8e2c45d816a2ecb869b2869825b3293640 (patch)
tree888dfa430241024e0dd47248aa14a8a09394d469 /include/gras/block.hpp
parent9620afa87986645653b171fb2c74c06597edb382 (diff)
downloadsandhi-77f79c8e2c45d816a2ecb869b2869825b3293640.tar.gz
sandhi-77f79c8e2c45d816a2ecb869b2869825b3293640.tar.bz2
sandhi-77f79c8e2c45d816a2ecb869b2869825b3293640.zip
work on stand-alone library build
Diffstat (limited to 'include/gras/block.hpp')
-rw-r--r--include/gras/block.hpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/include/gras/block.hpp b/include/gras/block.hpp
new file mode 100644
index 0000000..983d54a
--- /dev/null
+++ b/include/gras/block.hpp
@@ -0,0 +1,320 @@
+//
+// 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 <http://www.gnu.org/licenses/>.
+
+#ifndef INCLUDED_GRAS_BLOCK_HPP
+#define INCLUDED_GRAS_BLOCK_HPP
+
+#include <gras/element.hpp>
+#include <gras/sbuffer.hpp>
+#include <gras/tags.hpp>
+#include <vector>
+#include <string>
+#include <boost/range.hpp> //iterator range
+
+namespace gras
+{
+
+//! Configuration parameters for an input port
+struct GRAS_API InputPortConfig
+{
+ InputPortConfig(void);
+
+ /*!
+ * Set buffer inlining for this port config.
+ * 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 look-ahead of 0
+ *
+ * Default = false.
+ */
+ bool inline_buffer;
+
+ /*!
+ * Set the number of input buffer look-ahead items.
+ * When num look-ahead items are not consumed,
+ * they will be available for the next work call.
+ * This is used to implement sample memory for
+ * things like sliding dot products/FIR filters.
+ *
+ * Default = 0.
+ */
+ size_t lookahead_items;
+};
+
+//! Configuration parameters for an output port
+struct GRAS_API OutputPortConfig
+{
+ OutputPortConfig(void);
+
+ /*!
+ * Set an output reserve requirement such that work is called
+ * with an output buffer at least reserve items in size.
+ *
+ * Default = 1.
+ */
+ size_t reserve_items;
+
+ /*!
+ * Constrain the maximum number of items that
+ * work can be called with for this port.
+ *
+ * Default = 0 aka disabled.
+ */
+ size_t maximum_items;
+};
+
+template <typename PtrType> 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 <typename T> inline T cast(void) const
+ {
+ return reinterpret_cast<T>(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
+{
+
+ //! Contruct an empty/null block
+ Block(void);
+
+ //! Create a new block given the name
+ Block(const std::string &name);
+
+ /*******************************************************************
+ * Deal with input and output port configuration
+ ******************************************************************/
+
+ //! Get the configuration rules of an input port
+ InputPortConfig input_config(const size_t which_input = 0) const;
+
+ //! Set the configuration rules for an input port
+ void set_input_config(const InputPortConfig &config, const size_t which_input = 0);
+
+ //! Get the configuration rules of an output port
+ OutputPortConfig output_config(const size_t which_output = 0) const;
+
+ //! Set the configuration rules for an output port
+ void set_output_config(const OutputPortConfig &config, const size_t which_output = 0);
+
+ /*!
+ * 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);
+
+ //! Get the fixed rate setting
+ bool fixed_rate(void) const;
+
+ /*!
+ * 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(const double relative_rate);
+
+ //! Get the relative rate setting
+ double relative_rate(void) const;
+
+ /*!
+ * The output multiple setting controls work output buffer sizes.
+ * Buffers will be number of items modulo rounted to the multiple.
+ */
+ void set_output_multiple(const size_t multiple);
+
+ //! Get the output multiple setting
+ size_t output_multiple(void) const;
+
+ /*******************************************************************
+ * Deal with data production and consumption
+ ******************************************************************/
+
+ //! Return options for the work call
+ enum
+ {
+ WORK_CALLED_PRODUCE = -2,
+ WORK_DONE = -1
+ };
+
+ //! Call during work to consume items
+ void consume(const size_t which_input, const size_t how_many_items);
+
+ //! Call during work to consume items
+ void consume_each(const size_t how_many_items);
+
+ //! Call during work to produce items, must return WORK_CALLED_PRODUCE
+ void produce(const size_t which_output, const size_t how_many_items);
+
+ /*******************************************************************
+ * Deal with tag handling and tag configuration
+ ******************************************************************/
+
+ enum tag_propagation_policy_t
+ {
+ TPP_DONT = 0,
+ TPP_ALL_TO_ALL = 1,
+ TPP_ONE_TO_ONE = 2
+ };
+
+ 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);
+
+ //! Send a tag to the downstream on the given output port
+ void post_output_tag(const size_t which_output, const Tag &tag);
+
+ //! Iterator return type get_input_tags - stl and boost compliant
+ typedef boost::iterator_range<std::vector<Tag>::const_iterator> TagIter;
+
+ //! Get an iterator of item tags for the given input
+ TagIter get_input_tags(const size_t which_input = 0);
+
+ /*******************************************************************
+ * 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<WorkBuffer<const void *> > InputItems;
+ typedef std::vector<WorkBuffer<void *> > 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<int> &ninput_items_required
+ );
+
+ //! scheduler calls when the topology is updated, can be overloaded
+ virtual bool check_topology(int ninputs, int noutputs);
+
+ /*!
+ * Set if the work call should be interruptible by stop().
+ * Some work implementations block with the expectation of
+ * getting a boost thread interrupt in a blocking call.
+ * Set set_interruptible_work(true) if this is the case.
+ * By default, work implementations are not interruptible.
+ */
+ void set_interruptible_work(const bool enb);
+
+ /*******************************************************************
+ * 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.
+ * \param affinity a memory node on the system
+ */
+ void set_buffer_affinity(const long 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 gras
+
+#endif /*INCLUDED_GRAS_BLOCK_HPP*/