diff options
Diffstat (limited to 'gnuradio-runtime/include')
86 files changed, 10603 insertions, 0 deletions
diff --git a/gnuradio-runtime/include/CMakeLists.txt b/gnuradio-runtime/include/CMakeLists.txt new file mode 100644 index 0000000000..832522f92c --- /dev/null +++ b/gnuradio-runtime/include/CMakeLists.txt @@ -0,0 +1,100 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +add_subdirectory(messages) +add_subdirectory(pmt) +add_subdirectory(thread) + +######################################################################## +# Install header files +######################################################################## +install(FILES + gr_basic_block.h + gr_block_detail.h + gr_block.h + gr_block_registry.h + gr_buffer.h + gr_complex.h + gr_constants.h + gr_dispatcher.h + gr_endianness.h + gr_error_handler.h + gr_expj.h + gr_feval.h + gr_flowgraph.h + gr_fxpt.h + gr_fxpt_nco.h + gr_fxpt_vco.h + gr_hier_block2.h + gr_io_signature.h + gr_logger.h + gr_math.h + gr_message.h + gr_misc.h + gr_msg_accepter.h + gr_msg_handler.h + gr_msg_queue.h + gr_nco.h + gr_preferences.h + gr_prefs.h + gr_py_feval.h + gr_random.h + gr_realtime.h + gr_runtime_api.h + gr_runtime_types.h + gr_select_handler.h + gr_sincos.h + gr_single_threaded_scheduler.h + gr_sptr_magic.h + gr_sync_block.h + gr_sync_decimator.h + gr_sync_interpolator.h + gr_sys_paths.h + gr_tagged_stream_block.h + gr_tags.h + gr_timer.h + gr_top_block.h + gr_tpb_detail.h + gr_types.h + gr_unittests.h + ice_application_base.h + IcePy_Communicator.h + ice_server_template.h + pycallback_object.h + random.h + rpccallbackregister_base.h + rpcmanager_base.h + rpcmanager.h + rpcpmtconverters_ice.h + rpcregisterhelpers.h + rpcserver_aggregator.h + rpcserver_base.h + rpcserver_booter_aggregator.h + rpcserver_booter_base.h + rpcserver_booter_ice.h + rpcserver_ice.h + rpcserver_selector.h + runtime_block_gateway.h + attributes.h + high_res_timer.h + realtime.h + sys_pri.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio + COMPONENT "runtime_devel" +) diff --git a/gnuradio-runtime/include/IcePy_Communicator.h b/gnuradio-runtime/include/IcePy_Communicator.h new file mode 100644 index 0000000000..aae4378229 --- /dev/null +++ b/gnuradio-runtime/include/IcePy_Communicator.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2011 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_COMMUNICATOR_H +#define ICEPY_COMMUNICATOR_H + +#include <Ice/CommunicatorF.h> +#include <gr_runtime_api.h> + +namespace IcePy +{ + +extern PyTypeObject CommunicatorType; + +GR_RUNTIME_API bool initCommunicator(PyObject*); + +GR_RUNTIME_API Ice::CommunicatorPtr getCommunicator(PyObject*); + +GR_RUNTIME_API PyObject* createCommunicator(const Ice::CommunicatorPtr&); +GR_RUNTIME_API PyObject* getCommunicatorWrapper(const Ice::CommunicatorPtr&); + +} + +extern "C" PyObject* IcePy_initialize(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithProperties(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithLogger(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithPropertiesAndLogger(PyObject*, PyObject*); + +#endif diff --git a/gnuradio-runtime/include/attributes.h b/gnuradio-runtime/include/attributes.h new file mode 100644 index 0000000000..5baa52e7d3 --- /dev/null +++ b/gnuradio-runtime/include/attributes.h @@ -0,0 +1,74 @@ +/* + * Copyright 2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GNURADIO_ATTRIBUTES_H +#define INCLUDED_GNURADIO_ATTRIBUTES_H + +//////////////////////////////////////////////////////////////////////// +// Cross-platform attribute macros +//////////////////////////////////////////////////////////////////////// +#if defined __GNUC__ +# define __GR_ATTR_ALIGNED(x) __attribute__((aligned(x))) +# define __GR_ATTR_UNUSED __attribute__((unused)) +# define __GR_ATTR_INLINE __attribute__((always_inline)) +# define __GR_ATTR_DEPRECATED __attribute__((deprecated)) +# if __GNUC__ >= 4 +# define __GR_ATTR_EXPORT __attribute__((visibility("default"))) +# define __GR_ATTR_IMPORT __attribute__((visibility("default"))) +# else +# define __GR_ATTR_EXPORT +# define __GR_ATTR_IMPORT +# endif +#elif _MSC_VER +# define __GR_ATTR_ALIGNED(x) __declspec(align(x)) +# define __GR_ATTR_UNUSED +# define __GR_ATTR_INLINE __forceinline +# define __GR_ATTR_DEPRECATED __declspec(deprecated) +# define __GR_ATTR_EXPORT __declspec(dllexport) +# define __GR_ATTR_IMPORT __declspec(dllimport) +#else +# define __GR_ATTR_ALIGNED(x) +# define __GR_ATTR_UNUSED +# define __GR_ATTR_INLINE +# define __GR_ATTR_DEPRECATED +# define __GR_ATTR_EXPORT +# define __GR_ATTR_IMPORT +#endif + +//////////////////////////////////////////////////////////////////////// +// define inline when building C +//////////////////////////////////////////////////////////////////////// +#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline) +# define inline __inline +#endif + +//////////////////////////////////////////////////////////////////////// +// suppress warnings +//////////////////////////////////////////////////////////////////////// +#ifdef _MSC_VER +# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B' +# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ... +# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data +# pragma warning(disable: 4305) // 'initializing' : truncation from 'double' to 'float' +# pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +#endif /* INCLUDED_GNURADIO_ATTRIBUTES_H */ diff --git a/gnuradio-runtime/include/gr_basic_block.h b/gnuradio-runtime/include/gr_basic_block.h new file mode 100644 index 0000000000..beb54dbb6b --- /dev/null +++ b/gnuradio-runtime/include/gr_basic_block.h @@ -0,0 +1,344 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2008,2009,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BASIC_BLOCK_H +#define INCLUDED_GR_BASIC_BLOCK_H + +#include <gr_runtime_api.h> +#include <gr_runtime_types.h> +#include <gr_sptr_magic.h> +#include <boost/enable_shared_from_this.hpp> +#include <boost/function.hpp> +#include <gr_msg_accepter.h> +#include <string> +#include <deque> +#include <map> +#include <gr_io_signature.h> +#include <thread/thread.h> +#include <boost/foreach.hpp> +#include <boost/thread/condition_variable.hpp> +#include <iostream> + +#ifdef GR_CTRLPORT +#include <rpcregisterhelpers.h> +#endif + +/*! + * \brief The abstract base class for all signal processing blocks. + * \ingroup internal + * + * Basic blocks are the bare abstraction of an entity that has a name, + * a set of inputs and outputs, and a message queue. These are never instantiated + * directly; rather, this is the abstract parent class of both gr_hier_block, + * which is a recursive container, and gr_block, which implements actual + * signal processing functions. + */ + +class GR_RUNTIME_API gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block> +{ + typedef boost::function<void(pmt::pmt_t)> msg_handler_t; + + private: + + //msg_handler_t d_msg_handler; + typedef std::map<pmt::pmt_t , msg_handler_t, pmt::comperator> d_msg_handlers_t; + d_msg_handlers_t d_msg_handlers; + + typedef std::deque<pmt::pmt_t> msg_queue_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comperator> msg_queue_map_t; + typedef std::map<pmt::pmt_t, msg_queue_t, pmt::comperator>::iterator msg_queue_map_itr; + std::map<pmt::pmt_t, boost::shared_ptr<boost::condition_variable>, pmt::comperator> msg_queue_ready; + + gr::thread::mutex mutex; //< protects all vars + + protected: + friend class gr_flowgraph; + friend class gr_flat_flowgraph; // TODO: will be redundant + friend class gr_tpb_thread_body; + + enum vcolor { WHITE, GREY, BLACK }; + + std::string d_name; + gr_io_signature_sptr d_input_signature; + gr_io_signature_sptr d_output_signature; + long d_unique_id; + long d_symbolic_id; + std::string d_symbol_name; + std::string d_symbol_alias; + vcolor d_color; + bool d_rpc_set; + + msg_queue_map_t msg_queue; + std::vector<boost::any> d_rpc_vars; // container for all RPC variables + + gr_basic_block(void){} //allows pure virtual interface sub-classes + + //! Protected constructor prevents instantiation by non-derived classes + gr_basic_block(const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + + //! may only be called during constructor + void set_input_signature(gr_io_signature_sptr iosig) { + d_input_signature = iosig; + } + + //! may only be called during constructor + void set_output_signature(gr_io_signature_sptr iosig) { + d_output_signature = iosig; + } + + /*! + * \brief Allow the flowgraph to set for sorting and partitioning + */ + void set_color(vcolor color) { d_color = color; } + vcolor color() const { return d_color; } + + /*! + * \brief Tests if there is a handler attached to port \p which_port + */ + bool has_msg_handler(pmt::pmt_t which_port) { + return (d_msg_handlers.find(which_port) != d_msg_handlers.end()); + } + + /* + * This function is called by the runtime system to dispatch messages. + * + * The thread-safety guarantees mentioned in set_msg_handler are implemented + * by the callers of this method. + */ + virtual void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg) + { + // AA Update this + if(has_msg_handler(which_port)) { // Is there a handler? + d_msg_handlers[which_port](msg); // Yes, invoke it. + } + } + + // Message passing interface + pmt::pmt_t message_subscribers; + + public: + virtual ~gr_basic_block(); + long unique_id() const { return d_unique_id; } + long symbolic_id() const { return d_symbolic_id; } + std::string name() const { return d_name; } + std::string symbol_name() const { return d_symbol_name; } + gr_io_signature_sptr input_signature() const { return d_input_signature; } + gr_io_signature_sptr output_signature() const { return d_output_signature; } + gr_basic_block_sptr to_basic_block(); // Needed for Python type coercion + bool alias_set() { return !d_symbol_alias.empty(); } + std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); } + pmt::pmt_t alias_pmt(){ return pmt::intern(alias()); } + void set_block_alias(std::string name); + + // ** Message passing interface ** + void message_port_register_in(pmt::pmt_t port_id); + void message_port_register_out(pmt::pmt_t port_id); + void message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg); + void message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target); + void message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target); + + virtual bool message_port_is_hier(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier\n"; return false; } + virtual bool message_port_is_hier_in(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_in\n"; return false; } + virtual bool message_port_is_hier_out(pmt::pmt_t port_id) { (void) port_id; std::cout << "is_hier_out\n"; return false; } + + /*! + * \brief Get input message port names. + * + * Returns the available input message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_in(); + + /*! + * \brief Get output message port names. + * + * Returns the available output message ports for a block. The + * return object is a PMT vector that is filled with PMT symbols. + */ + pmt::pmt_t message_ports_out(); + + /*! + * Accept msg, place in queue, arrange for thread to be awakened if it's not already. + */ + void _post(pmt::pmt_t which_port, pmt::pmt_t msg); + + //! is the queue empty? + //bool empty_p(const pmt::pmt_t &which_port) const { return msg_queue[which_port].empty(); } + bool empty_p(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) == msg_queue.end()) + throw std::runtime_error("port does not exist!"); + return msg_queue[which_port].empty(); + } + bool empty_p() { + bool rv = true; + BOOST_FOREACH(msg_queue_map_t::value_type &i, msg_queue) { + rv &= msg_queue[i.first].empty(); + } + return rv; + } + + //! How many messages in the queue? + size_t nmsgs(pmt::pmt_t which_port) { + if(msg_queue.find(which_port) == msg_queue.end()) + throw std::runtime_error("port does not exist!"); + return msg_queue[which_port].size(); + } + + //| Acquires and release the mutex + void insert_tail( pmt::pmt_t which_port, pmt::pmt_t msg); + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + */ + pmt::pmt_t delete_head_nowait( pmt::pmt_t which_port); + + /*! + * \returns returns pmt at head of queue or pmt_t() if empty. + */ + pmt::pmt_t delete_head_blocking( pmt::pmt_t which_port); + + msg_queue_t::iterator get_iterator(pmt::pmt_t which_port){ + return msg_queue[which_port].begin(); + } + + void erase_msg(pmt::pmt_t which_port, msg_queue_t::iterator it){ + msg_queue[which_port].erase(it); + } + + virtual bool has_msg_port(pmt::pmt_t which_port){ + if(msg_queue.find(which_port) != msg_queue.end()){ + return true; + } + if(pmt::dict_has_key(message_subscribers, which_port)){ + return true; + } + return false; + } + +#ifdef GR_CTRLPORT + /*! + * \brief Add an RPC variable (get or set). + * + * Using controlport, we create new getters/setters and need to + * store them. Each block has a vector to do this, and these never + * need to be accessed again once they are registered with the RPC + * backend. This function takes a + * boost::shared_sptr<rpcbasic_base> so that when the block is + * deleted, all RPC registered variables are cleaned up. + * + * \param s an rpcbasic_sptr of the new RPC variable register to store. + */ + void add_rpc_variable(rpcbasic_sptr s) + { + d_rpc_vars.push_back(s); + } +#endif /* GR_CTRLPORT */ + + /*! + * \brief Set up the RPC registered variables. + * + * This must be overloaded by a block that wants to use + * controlport. This is where rpcbasic_register_{get,set} pointers + * are created, which then get wrapped as shared pointers + * (rpcbasic_sptr(...)) and stored using add_rpc_variable. + */ + virtual void setup_rpc() {}; + + /*! + * \brief Ask if this block has been registered to the RPC. + * + * We can only register a block once, so we use this to protect us + * from calling it multiple times. + */ + bool is_rpc_set() { return d_rpc_set; } + + /*! + * \brief When the block is registered with the RPC, set this. + */ + void rpc_set() { d_rpc_set = true; } + + /*! + * \brief Confirm that ninputs and noutputs is an acceptable combination. + * + * \param ninputs number of input streams connected + * \param noutputs number of output streams connected + * + * \returns true if this is a valid configuration for this block. + * + * This function is called by the runtime system whenever the + * topology changes. Most classes do not need to override this. + * This check is in addition to the constraints specified by the input + * and output gr_io_signatures. + */ + virtual bool check_topology(int ninputs, int noutputs) { (void) ninputs; (void) noutputs; return true; } + + /*! + * \brief Set the callback that is fired when messages are available. + * + * \p msg_handler can be any kind of function pointer or function object + * that has the signature: + * <pre> + * void msg_handler(pmt::pmt msg); + * </pre> + * + * (You may want to use boost::bind to massage your callable into + * the correct form. See gr::blocks::nop for an example that sets + * up a class method as the callback.) + * + * Blocks that desire to handle messages must call this method in their + * constructors to register the handler that will be invoked when messages + * are available. + * + * If the block inherits from gr_block, the runtime system will ensure that + * msg_handler is called in a thread-safe manner, such that work and + * msg_handler will never be called concurrently. This allows msg_handler + * to update state variables without having to worry about thread-safety + * issues with work, general_work or another invocation of msg_handler. + * + * If the block inherits from gr_hier_block2, the runtime system will + * ensure that no reentrant calls are made to msg_handler. + */ + template <typename T> void set_msg_handler(pmt::pmt_t which_port, T msg_handler){ + if(msg_queue.find(which_port) == msg_queue.end()){ + throw std::runtime_error("attempt to set_msg_handler() on bad input message port!"); } + d_msg_handlers[which_port] = msg_handler_t(msg_handler); + } +}; + +inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs) +{ + return lhs->unique_id() < rhs->unique_id(); +} + +typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t; +typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t; + +GR_RUNTIME_API long gr_basic_block_ncurrently_allocated(); + +inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block) +{ + os << basic_block->name() << "(" << basic_block->unique_id() << ")"; + return os; +} + +#endif /* INCLUDED_GR_BASIC_BLOCK_H */ diff --git a/gnuradio-runtime/include/gr_block.h b/gnuradio-runtime/include/gr_block.h new file mode 100644 index 0000000000..77ca3f3f72 --- /dev/null +++ b/gnuradio-runtime/include/gr_block.h @@ -0,0 +1,700 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007,2009,2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BLOCK_H +#define INCLUDED_GR_BLOCK_H + +#include <gr_runtime_api.h> +#include <gr_basic_block.h> +#include <gr_tags.h> +#include <gr_logger.h> + +/*! + * \brief The abstract base class for all 'terminal' processing blocks. + * \ingroup base_blk + * + * A signal processing flow is constructed by creating a tree of + * hierarchical blocks, which at any level may also contain terminal nodes + * that actually implement signal processing functions. This is the base + * class for all such leaf nodes. + + * Blocks have a set of input streams and output streams. The + * input_signature and output_signature define the number of input + * streams and output streams respectively, and the type of the data + * items in each stream. + * + * Although blocks may consume data on each input stream at a + * different rate, all outputs streams must produce data at the same + * rate. That rate may be different from any of the input rates. + * + * User derived blocks override two methods, forecast and general_work, + * to implement their signal processing behavior. forecast is called + * by the system scheduler to determine how many items are required on + * each input stream in order to produce a given number of output + * items. + * + * general_work is called to perform the signal processing in the block. + * It reads the input items and writes the output items. + */ + +class GR_RUNTIME_API gr_block : public gr_basic_block { + + public: + + //! Magic return values from general_work + 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 + }; + + virtual ~gr_block (); + + /*! + * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...) + * History is the number of x_i's that are examined to produce one y_i. + * This comes in handy for FIR filters, where we use history to + * ensure that our input contains the appropriate "history" for the + * filter. History should be equal to the number of filter taps. + */ + unsigned history () const { return d_history; } + void set_history (unsigned history) { d_history = history; } + + /*! + * \brief Return true if this block has a fixed input to output rate. + * + * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called. + */ + bool fixed_rate() const { return d_fixed_rate; } + + // ---------------------------------------------------------------- + // override these to define your behavior + // ---------------------------------------------------------------- + + /*! + * \brief Estimate input requirements given output request + * + * \param noutput_items number of output items to produce + * \param ninput_items_required number of input items required on each input stream + * + * Given a request to product \p noutput_items, estimate the number of + * data items required on each input stream. The estimate doesn't have + * to be exact, but should be close. + */ + virtual void forecast (int noutput_items, + gr_vector_int &ninput_items_required); + + /*! + * \brief compute output items from input items + * + * \param noutput_items number of output items to write on each output stream + * \param ninput_items number of input items available on each input stream + * \param input_items vector of pointers to the input items, one entry per input stream + * \param output_items vector of pointers to the output items, one entry per output stream + * + * \returns number of items actually written to each output stream, or -1 on EOF. + * It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items + * + * general_work must call consume or consume_each to indicate how many items + * were consumed on each input stream. + */ + virtual int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + /*! + * \brief Called to enable drivers, etc for i/o devices. + * + * This allows a block to enable an associated driver to begin + * transfering data just before we start to execute the scheduler. + * The end result is that this reduces latency in the pipeline when + * dealing with audio devices, usrps, etc. + */ + virtual bool start(); + + /*! + * \brief Called to disable drivers, etc for i/o devices. + */ + virtual bool stop(); + + // ---------------------------------------------------------------- + + /*! + * \brief Constrain the noutput_items argument passed to forecast and general_work + * + * set_output_multiple causes the scheduler to ensure that the noutput_items + * argument passed to forecast and general_work will be an integer multiple + * of \param multiple The default value of output multiple is 1. + */ + void set_output_multiple (int multiple); + int output_multiple () const { return d_output_multiple; } + bool output_multiple_set () const { return d_output_multiple_set; } + + /*! + * \brief Constrains buffers to work on a set item alignment (for SIMD) + * + * set_alignment_multiple causes the scheduler to ensure that the noutput_items + * argument passed to forecast and general_work will be an integer multiple + * of \param multiple The default value is 1. + * + * This control is similar to the output_multiple setting, except + * that if the number of items passed to the block is less than the + * output_multiple, this value is ignored and the block can produce + * like normal. The d_unaligned value is set to the number of items + * the block is off by. In the next call to general_work, the + * noutput_items is set to d_unaligned or less until + * d_unaligned==0. The buffers are now aligned again and the aligned + * calls can be performed again. + */ + void set_alignment (int multiple); + int alignment () const { return d_output_multiple; } + + void set_unaligned (int na); + int unaligned () const { return d_unaligned; } + void set_is_unaligned (bool u); + bool is_unaligned () const { return d_is_unaligned; } + + /*! + * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed. + */ + void consume (int which_input, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were consumed on each input stream. + */ + void consume_each (int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output. + * + * If the block's general_work method calls produce, \p general_work must return WORK_CALLED_PRODUCE. + */ + void produce (int which_output, int how_many_items); + + /*! + * \brief Set the approximate output rate / input rate + * + * Provide a hint to the buffer allocator and scheduler. + * The default relative_rate is 1.0 + * + * decimators have relative_rates < 1.0 + * interpolators have relative_rates > 1.0 + */ + void set_relative_rate (double relative_rate); + + /*! + * \brief return the approximate output rate / input rate + */ + double relative_rate () const { return d_relative_rate; } + + /* + * The following two methods provide special case info to the + * scheduler in the event that a block has a fixed input to output + * ratio. gr_sync_block, gr_sync_decimator and gr_sync_interpolator + * override these. If you're fixed rate, subclass one of those. + */ + /*! + * \brief Given ninput samples, return number of output samples that will be produced. + * N.B. this is only defined if fixed_rate returns true. + * Generally speaking, you don't need to override this. + */ + virtual int fixed_rate_ninput_to_noutput(int ninput); + + /*! + * \brief Given noutput samples, return number of input samples required to produce noutput. + * N.B. this is only defined if fixed_rate returns true. + * Generally speaking, you don't need to override this. + */ + virtual int fixed_rate_noutput_to_ninput(int noutput); + + /*! + * \brief Return the number of items read on input stream which_input + */ + uint64_t nitems_read(unsigned int which_input); + + /*! + * \brief Return the number of items written on output stream which_output + */ + uint64_t nitems_written(unsigned int which_output); + + /*! + * \brief Asks for the policy used by the scheduler to moved tags downstream. + */ + tag_propagation_policy_t tag_propagation_policy(); + + /*! + * \brief Set the policy by the scheduler to determine how tags are moved downstream. + */ + void set_tag_propagation_policy(tag_propagation_policy_t p); + + /*! + * \brief Return the minimum number of output items this block can + * produce during a call to work. + * + * Should be 0 for most blocks. Useful if we're dealing with packets and + * the block produces one packet per call to work. + */ + int min_noutput_items() const { return d_min_noutput_items; } + + /*! + * \brief Set the minimum number of output items this block can + * produce during a call to work. + * + * \param m the minimum noutput_items this block can produce. + */ + void set_min_noutput_items(int m) { d_min_noutput_items = m; } + + /*! + * \brief Return the maximum number of output items this block will + * handle during a call to work. + */ + int max_noutput_items(); + + /*! + * \brief Set the maximum number of output items this block will + * handle during a call to work. + * + * \param m the maximum noutput_items this block will handle. + */ + void set_max_noutput_items(int m); + + /*! + * \brief Clear the switch for using the max_noutput_items value of this block. + * + * When is_set_max_noutput_items() returns 'true', the scheduler + * will use the value returned by max_noutput_items() to limit the + * size of the number of items possible for this block's work + * function. If is_set_max_notput_items() returns 'false', then the + * scheduler ignores the internal value and uses the value set + * globally in the top_block. + * + * Use this value to clear the 'is_set' flag so the scheduler will + * ignore this. Use the set_max_noutput_items(m) call to both set a + * new value for max_noutput_items and to reenable its use in the + * scheduler. + */ + void unset_max_noutput_items(); + + /*! + * \brief Ask the block if the flag is or is not set to use the + * internal value of max_noutput_items during a call to work. + */ + bool is_set_max_noutput_items(); + + /* + * Used to expand the vectors that hold the min/max buffer sizes. + * + * Specifically, when -1 is used, the vectors are just initialized + * with 1 value; this is used by the flat_flowgraph to expand when + * required to add a new value for new ports on these blocks. + */ + void expand_minmax_buffer(int port) { + if((size_t)port >= d_max_output_buffer.size()) + set_max_output_buffer(port, -1); + if((size_t)port >= d_min_output_buffer.size()) + set_min_output_buffer(port, -1); + } + + /*! + * \brief Returns max buffer size on output port \p i. + */ + long max_output_buffer(size_t i) { + if(i >= d_max_output_buffer.size()) + throw std::invalid_argument("gr_basic_block::max_output_buffer: port out of range."); + return d_max_output_buffer[i]; + } + + /*! + * \brief Sets max buffer size on all output ports. + */ + void set_max_output_buffer(long max_output_buffer) { + for(int i = 0; i < output_signature()->max_streams(); i++) { + set_max_output_buffer(i, max_output_buffer); + } + } + + /*! + * \brief Sets max buffer size on output port \p port. + */ + void set_max_output_buffer(int port, long max_output_buffer) { + if((size_t)port >= d_max_output_buffer.size()) + d_max_output_buffer.push_back(max_output_buffer); + else + d_max_output_buffer[port] = max_output_buffer; + } + + /*! + * \brief Returns min buffer size on output port \p i. + */ + long min_output_buffer(size_t i) { + if(i >= d_min_output_buffer.size()) + throw std::invalid_argument("gr_basic_block::min_output_buffer: port out of range."); + return d_min_output_buffer[i]; + } + + /*! + * \brief Sets min buffer size on all output ports. + */ + void set_min_output_buffer(long min_output_buffer) { + for(int i=0; i<output_signature()->max_streams(); i++) { + set_min_output_buffer(i, min_output_buffer); + } + } + + /*! + * \brief Sets min buffer size on output port \p port. + */ + void set_min_output_buffer(int port, long min_output_buffer) { + if((size_t)port >= d_min_output_buffer.size()) + d_min_output_buffer.push_back(min_output_buffer); + else + d_min_output_buffer[port] = min_output_buffer; + } + + // --------------- Performance counter functions ------------- + + /*! + * \brief Gets instantaneous noutput_items performance counter. + */ + float pc_noutput_items(); + + /*! + * \brief Gets average noutput_items performance counter. + */ + float pc_noutput_items_avg(); + + /*! + * \brief Gets variance of noutput_items performance counter. + */ + float pc_noutput_items_var(); + + /*! + * \brief Gets instantaneous num items produced performance counter. + */ + float pc_nproduced(); + + /*! + * \brief Gets average num items produced performance counter. + */ + float pc_nproduced_avg(); + + /*! + * \brief Gets variance of num items produced performance counter. + */ + float pc_nproduced_var(); + + /*! + * \brief Gets instantaneous fullness of \p which input buffer. + */ + float pc_input_buffers_full(int which); + + /*! + * \brief Gets average fullness of \p which input buffer. + */ + float pc_input_buffers_full_avg(int which); + + /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_input_buffers_full_var(int which); + + /*! + * \brief Gets instantaneous fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full(); + + /*! + * \brief Gets average fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full_avg(); + + /*! + * \brief Gets variance of fullness of all input buffers. + */ + std::vector<float> pc_input_buffers_full_var(); + + /*! + * \brief Gets instantaneous fullness of \p which input buffer. + */ + float pc_output_buffers_full(int which); + + /*! + * \brief Gets average fullness of \p which input buffer. + */ + float pc_output_buffers_full_avg(int which); + + /*! + * \brief Gets variance of fullness of \p which input buffer. + */ + float pc_output_buffers_full_var(int which); + + /*! + * \brief Gets instantaneous fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full(); + + /*! + * \brief Gets average fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full_avg(); + + /*! + * \brief Gets variance of fullness of all output buffers. + */ + std::vector<float> pc_output_buffers_full_var(); + + /*! + * \brief Gets instantaneous clock cycles spent in work. + */ + float pc_work_time(); + + /*! + * \brief Gets average clock cycles spent in work. + */ + float pc_work_time_avg(); + + /*! + * \brief Gets average clock cycles spent in work. + */ + float pc_work_time_var(); + + /*! + * \brief Resets the performance counters + */ + void reset_perf_counters(); + + /*! + * \brief Sets up export of perf. counters to ControlPort. Only + * called by the scheduler. + */ + void setup_pc_rpc(); + + /*! + * \brief Checks if this block is already exporting perf. counters + * to ControlPort. + */ + bool is_pc_rpc_set() { return d_pc_rpc_set; } + + /*! + * \brief If the block calls this in its constructor, it's + * perf. counters will not be exported. + */ + void no_pc_rpc() { d_pc_rpc_set = true; } + + + // ---------------------------------------------------------------------------- + // Functions to handle thread affinity + + /*! + * \brief Set the thread's affinity to processor core \p n. + * + * \param mask a vector of ints of the core numbers available to this block. + */ + void set_processor_affinity(const std::vector<int> &mask); + + /*! + * \brief Remove processor affinity to a specific core. + */ + void unset_processor_affinity(); + + /*! + * \brief Get the current processor affinity. + */ + std::vector<int> processor_affinity() { return d_affinity; } + + // ---------------------------------------------------------------------------- + + private: + + int d_output_multiple; + bool d_output_multiple_set; + int d_unaligned; + bool d_is_unaligned; + double d_relative_rate; // approx output_rate / input_rate + gr_block_detail_sptr d_detail; // implementation details + unsigned d_history; + bool d_fixed_rate; + bool d_max_noutput_items_set; // if d_max_noutput_items is valid + int d_max_noutput_items; // value of max_noutput_items for this block + int d_min_noutput_items; + tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream + std::vector<int> d_affinity; // thread affinity proc. mask + bool d_pc_rpc_set; + + protected: + gr_block (void){} //allows pure virtual interface sub-classes + gr_block (const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + + void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; } + + + /*! + * \brief Adds a new tag onto the given output buffer. + * + * \param which_output an integer of which output stream to attach the tag + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid optional source ID specifier; defaults to PMT_F + */ + inline void add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F) + { + gr_tag_t tag; + tag.offset = abs_offset; + tag.key = key; + tag.value = value; + tag.srcid = srcid; + this->add_item_tag(which_output, tag); + } + + /*! + * \brief Adds a new tag onto the given output buffer. + * + * \param which_output an integer of which output stream to attach the tag + * \param tag the tag object to add + */ + void add_item_tag(unsigned int which_output, const gr_tag_t &tag); + + /*! + * \brief Removes a tag from the given input buffer. + * + * \param which_input an integer of which input stream to remove the tag from + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid optional source ID specifier; defaults to PMT_F + * + * If no such tag is found, does nothing. + */ + inline void remove_item_tag(unsigned int which_input, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F) + { + gr_tag_t tag; + tag.offset = abs_offset; + tag.key = key; + tag.value = value; + tag.srcid = srcid; + this->remove_item_tag(which_input, tag); + } + + /*! + * \brief Removes a tag from the given input buffer. + * + * If no such tag is found, does nothing. + * + * \param which_input an integer of which input stream to remove the tag from + * \param tag the tag object to remove + */ + void remove_item_tag(unsigned int which_input, const gr_tag_t &tag); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<gr_tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range + * with a given key. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol key to filter only tags of this key + */ + void get_tags_in_range(std::vector<gr_tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + + std::vector<long> d_max_output_buffer; + std::vector<long> d_min_output_buffer; + + /*! Used by block's setters and work functions to make + * setting/resetting of parameters thread-safe. + * + * Used by calling gr::thread::scoped_lock l(d_setlock); + */ + gr::thread::mutex d_setlock; + + /*! Used by blocks to access the logger system. + */ + gr_logger_ptr d_logger; + gr_logger_ptr d_debug_logger; + + // These are really only for internal use, but leaving them public avoids + // having to work up an ever-varying list of friend GR_RUNTIME_APIs + + public: + gr_block_detail_sptr detail () const { return d_detail; } + void set_detail (gr_block_detail_sptr detail) { d_detail = detail; } +}; + +typedef std::vector<gr_block_sptr> gr_block_vector_t; +typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t; + +inline gr_block_sptr cast_to_block_sptr(gr_basic_block_sptr p) +{ + return boost::dynamic_pointer_cast<gr_block, gr_basic_block>(p); +} + + +std::ostream& +operator << (std::ostream& os, const gr_block *m); + +#endif /* INCLUDED_GR_BLOCK_H */ diff --git a/gnuradio-runtime/include/gr_block_detail.h b/gnuradio-runtime/include/gr_block_detail.h new file mode 100644 index 0000000000..14886c0a74 --- /dev/null +++ b/gnuradio-runtime/include/gr_block_detail.h @@ -0,0 +1,248 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more detail. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BLOCK_DETAIL_H +#define INCLUDED_GR_BLOCK_DETAIL_H + +#include <gr_runtime_api.h> +#include <gr_runtime_types.h> +#include <gr_tpb_detail.h> +#include <gr_tags.h> +#include <high_res_timer.h> +#include <stdexcept> + +/*! + * \brief Implementation details to support the signal processing abstraction + * \ingroup internal + * + * This class contains implementation detail that should be "out of sight" + * of almost all users of GNU Radio. This decoupling also means that + * we can make changes to the guts without having to recompile everything. + */ +class GR_RUNTIME_API gr_block_detail { + public: + ~gr_block_detail (); + + int ninputs () const { return d_ninputs; } + int noutputs () const { return d_noutputs; } + bool sink_p () const { return d_noutputs == 0; } + bool source_p () const { return d_ninputs == 0; } + + void set_done (bool done); + bool done () const { return d_done; } + + void set_input (unsigned int which, gr_buffer_reader_sptr reader); + gr_buffer_reader_sptr input (unsigned int which) + { + if (which >= d_ninputs) + throw std::invalid_argument ("gr_block_detail::input"); + return d_input[which]; + } + + void set_output (unsigned int which, gr_buffer_sptr buffer); + gr_buffer_sptr output (unsigned int which) + { + if (which >= d_noutputs) + throw std::invalid_argument ("gr_block_detail::output"); + return d_output[which]; + } + + /*! + * \brief Tell the scheduler \p how_many_items of input stream \p which_input were consumed. + */ + void consume (int which_input, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were consumed on each input stream. + */ + void consume_each (int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on output stream \p which_output. + */ + void produce (int which_output, int how_many_items); + + /*! + * \brief Tell the scheduler \p how_many_items were produced on each output stream. + */ + void produce_each (int how_many_items); + + // Return the number of items read on input stream which_input + uint64_t nitems_read(unsigned int which_input); + + // Return the number of items written on output stream which_output + uint64_t nitems_written(unsigned int which_output); + + + /*! + * \brief Adds a new tag to the given output stream. + * + * Calls gr_buffer::add_item_tag(), + * which appends the tag onto its deque. + * + * \param which_output an integer of which output stream to attach the tag + * \param tag the tag object to add + */ + void add_item_tag(unsigned int which_output, const gr_tag_t &tag); + + /*! + * \brief Removes a tag from the given input stream. + * + * Calls gr_buffer::remove_item_tag(), which removes the tag from its deque. + * + * \param which_input an integer of which input stream to remove the tag from + * \param tag the tag object to add + */ + void remove_item_tag(unsigned int which_input, const gr_tag_t &tag); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Pass-through function to gr_buffer_reader to get a vector of tags + * in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<gr_tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range + * with a given key. + * + * Calls get_tags_in_range(which_input, abs_start, abs_end) to get a vector of + * tags from the buffers. This function then provides a secondary filter to + * the tags to extract only tags with the given 'key'. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol to select only tags of this key + */ + void get_tags_in_range(std::vector<gr_tag_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + + /*! + * \brief Set core affinity of block to the cores in the vector mask. + * + * \param mask a vector of ints of the core numbers available to this block. + */ + void set_processor_affinity(const std::vector<int> &mask); + + /*! + * \brief Unset core affinity. + */ + void unset_processor_affinity(); + + bool threaded; // set if thread is currently running. + gr::thread::gr_thread_t thread; // portable thread handle + + void start_perf_counters(); + void stop_perf_counters(int noutput_items, int nproduced); + void reset_perf_counters(); + + // Calls to get performance counter items + float pc_noutput_items(); + float pc_nproduced(); + float pc_input_buffers_full(size_t which); + std::vector<float> pc_input_buffers_full(); + float pc_output_buffers_full(size_t which); + std::vector<float> pc_output_buffers_full(); + float pc_work_time(); + + float pc_noutput_items_avg(); + float pc_nproduced_avg(); + float pc_input_buffers_full_avg(size_t which); + std::vector<float> pc_input_buffers_full_avg(); + float pc_output_buffers_full_avg(size_t which); + std::vector<float> pc_output_buffers_full_avg(); + float pc_work_time_avg(); + + float pc_noutput_items_var(); + float pc_nproduced_var(); + float pc_input_buffers_full_var(size_t which); + std::vector<float> pc_input_buffers_full_var(); + float pc_output_buffers_full_var(size_t which); + std::vector<float> pc_output_buffers_full_var(); + float pc_work_time_var(); + + gr_tpb_detail d_tpb; // used by thread-per-block scheduler + int d_produce_or; + + // ---------------------------------------------------------------------------- + + private: + unsigned int d_ninputs; + unsigned int d_noutputs; + std::vector<gr_buffer_reader_sptr> d_input; + std::vector<gr_buffer_sptr> d_output; + bool d_done; + + // Performance counters + float d_ins_noutput_items; + float d_avg_noutput_items; + float d_var_noutput_items; + float d_ins_nproduced; + float d_avg_nproduced; + float d_var_nproduced; + std::vector<float> d_ins_input_buffers_full; + std::vector<float> d_avg_input_buffers_full; + std::vector<float> d_var_input_buffers_full; + std::vector<float> d_ins_output_buffers_full; + std::vector<float> d_avg_output_buffers_full; + std::vector<float> d_var_output_buffers_full; + gr::high_res_timer_type d_start_of_work, d_end_of_work; + float d_ins_work_time; + float d_avg_work_time; + float d_var_work_time; + float d_pc_counter; + + gr_block_detail (unsigned int ninputs, unsigned int noutputs); + + friend struct gr_tpb_detail; + + friend GR_RUNTIME_API gr_block_detail_sptr + gr_make_block_detail (unsigned int ninputs, unsigned int noutputs); +}; + +GR_RUNTIME_API gr_block_detail_sptr +gr_make_block_detail (unsigned int ninputs, unsigned int noutputs); + +GR_RUNTIME_API long +gr_block_detail_ncurrently_allocated (); + +#endif /* INCLUDED_GR_BLOCK_DETAIL_H */ diff --git a/gnuradio-runtime/include/gr_block_registry.h b/gnuradio-runtime/include/gr_block_registry.h new file mode 100644 index 0000000000..9b038287bc --- /dev/null +++ b/gnuradio-runtime/include/gr_block_registry.h @@ -0,0 +1,44 @@ +#ifndef GR_BLOCK_REGISTRY_H +#define GR_BLOCK_REGISTRY_H + +#include <gr_runtime_api.h> +#include <map> +#include <gr_basic_block.h> + +#ifndef GR_BASIC_BLOCK_H +class gr_basic_block; +class gr_block; +#endif + +class GR_RUNTIME_API gr_block_registry { + public: + gr_block_registry(); + + long block_register(gr_basic_block* block); + void block_unregister(gr_basic_block* block); + + std::string register_symbolic_name(gr_basic_block* block); + void register_symbolic_name(gr_basic_block* block, std::string name); + + gr_basic_block_sptr block_lookup(pmt::pmt_t symbol); + + void register_primitive(std::string blk, gr_block* ref); + void unregister_primitive(std::string blk); + void notify_blk(std::string blk); + + private: + + //typedef std::map< long, gr_basic_block_sptr > blocksubmap_t; + typedef std::map< long, gr_basic_block* > blocksubmap_t; + typedef std::map< std::string, blocksubmap_t > blockmap_t; + + blockmap_t d_map; + pmt::pmt_t d_ref_map; + std::map< std::string, gr_block*> primitive_map; + +}; + +GR_RUNTIME_API extern gr_block_registry global_block_registry; + +#endif + diff --git a/gnuradio-runtime/include/gr_buffer.h b/gnuradio-runtime/include/gr_buffer.h new file mode 100644 index 0000000000..810879b7ea --- /dev/null +++ b/gnuradio-runtime/include/gr_buffer.h @@ -0,0 +1,309 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2009,2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BUFFER_H +#define INCLUDED_GR_BUFFER_H + +#include <gr_runtime_api.h> +#include <gr_runtime_types.h> +#include <boost/weak_ptr.hpp> +#include <thread/thread.h> +#include <gr_tags.h> +#include <deque> + +class gr_vmcircbuf; + +/*! + * \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item. + * + * The total size of the buffer will be rounded up to a system + * dependent boundary. This is typically the system page size, but + * under MS windows is 64KB. + * + * \param nitems is the minimum number of items the buffer will hold. + * \param sizeof_item is the size of an item in bytes. + * \param link is the block that writes to this buffer. + */ +GR_RUNTIME_API gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link=gr_block_sptr()); + + +/*! + * \brief Single writer, multiple reader fifo. + * \ingroup internal + */ +class GR_RUNTIME_API gr_buffer { + public: + + virtual ~gr_buffer (); + + /*! + * \brief return number of items worth of space available for writing + */ + int space_available (); + + /*! + * \brief return size of this buffer in items + */ + int bufsize() const { return d_bufsize; } + + /*! + * \brief return pointer to write buffer. + * + * The return value points at space that can hold at least + * space_available() items. + */ + void *write_pointer (); + + /*! + * \brief tell buffer that we wrote \p nitems into it + */ + void update_write_pointer (int nitems); + + void set_done (bool done); + bool done () const { return d_done; } + + /*! + * \brief Return the block that writes to this buffer. + */ + gr_block_sptr link() { return gr_block_sptr(d_link); } + + size_t nreaders() const { return d_readers.size(); } + gr_buffer_reader* reader(size_t index) { return d_readers[index]; } + + gr::thread::mutex *mutex() { return &d_mutex; } + + uint64_t nitems_written() { return d_abs_write_offset; } + + size_t get_sizeof_item() { return d_sizeof_item; } + + /*! + * \brief Adds a new tag to the buffer. + * + * \param tag the new tag + */ + void add_item_tag(const gr_tag_t &tag); + + /*! + * \brief Removes an existing tag from the buffer. + * + * If no such tag is found, does nothing. + * + * \param tag the tag that needs to be removed + */ + void remove_item_tag(const gr_tag_t &tag); + + /*! + * \brief Removes all tags before \p max_time from buffer + * + * \param max_time the time (item number) to trim up until. + */ + void prune_tags(uint64_t max_time); + + std::deque<gr_tag_t>::iterator get_tags_begin() { return d_item_tags.begin(); } + std::deque<gr_tag_t>::iterator get_tags_end() { return d_item_tags.end(); } + + // ------------------------------------------------------------------------- + + private: + + friend class gr_buffer_reader; + friend GR_RUNTIME_API gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); + friend GR_RUNTIME_API gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link); + + protected: + char *d_base; // base address of buffer + unsigned int d_bufsize; // in items + private: + gr_vmcircbuf *d_vmcircbuf; + size_t d_sizeof_item; // in bytes + std::vector<gr_buffer_reader *> d_readers; + boost::weak_ptr<gr_block> d_link; // block that writes to this buffer + + // + // The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags + // and the d_read_index's and d_abs_read_offset's in the buffer readers. + // + gr::thread::mutex d_mutex; + unsigned int d_write_index; // in items [0,d_bufsize) + uint64_t d_abs_write_offset; // num items written since the start + bool d_done; + std::deque<gr_tag_t> d_item_tags; + uint64_t d_last_min_items_read; + + unsigned + index_add (unsigned a, unsigned b) + { + unsigned s = a + b; + + if (s >= d_bufsize) + s -= d_bufsize; + + assert (s < d_bufsize); + return s; + } + + unsigned + index_sub (unsigned a, unsigned b) + { + int s = a - b; + + if (s < 0) + s += d_bufsize; + + assert ((unsigned) s < d_bufsize); + return s; + } + + virtual bool allocate_buffer (int nitems, size_t sizeof_item); + + /*! + * \brief constructor is private. Use gr_make_buffer to create instances. + * + * Allocate a buffer that holds at least \p nitems of size \p sizeof_item. + * + * \param nitems is the minimum number of items the buffer will hold. + * \param sizeof_item is the size of an item in bytes. + * \param link is the block that writes to this buffer. + * + * The total size of the buffer will be rounded up to a system + * dependent boundary. This is typically the system page size, but + * under MS windows is 64KB. + */ + gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); + + /*! + * \brief disassociate \p reader from this buffer + */ + void drop_reader (gr_buffer_reader *reader); + +}; + +/*! + * \brief Create a new gr_buffer_reader and attach it to buffer \p buf + * \param buf is the buffer the \p gr_buffer_reader reads from. + * \param nzero_preload -- number of zero items to "preload" into buffer. + * \param link is the block that reads from the buffer using this gr_buffer_reader. + */ +GR_RUNTIME_API gr_buffer_reader_sptr +gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link=gr_block_sptr()); + +//! returns # of gr_buffers currently allocated +GR_RUNTIME_API long gr_buffer_ncurrently_allocated (); + + +// --------------------------------------------------------------------------- + +/*! + * \brief How we keep track of the readers of a gr_buffer. + * \ingroup internal + */ + +class GR_RUNTIME_API gr_buffer_reader { + public: + + ~gr_buffer_reader (); + + /*! + * \brief Return number of items available for reading. + */ + int items_available () const; + + /*! + * \brief Return buffer this reader reads from. + */ + gr_buffer_sptr buffer () const { return d_buffer; } + + + /*! + * \brief Return maximum number of items that could ever be available for reading. + * This is used as a sanity check in the scheduler to avoid looping forever. + */ + int max_possible_items_available () const { return d_buffer->d_bufsize - 1; } + + /*! + * \brief return pointer to read buffer. + * + * The return value points to items_available() number of items + */ + const void *read_pointer (); + + /* + * \brief tell buffer we read \p items from it + */ + void update_read_pointer (int nitems); + + void set_done (bool done) { d_buffer->set_done (done); } + bool done () const { return d_buffer->done (); } + + gr::thread::mutex *mutex() { return d_buffer->mutex(); } + + + uint64_t nitems_read() { return d_abs_read_offset; } + + size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); } + + /*! + * \brief Return the block that reads via this reader. + * + */ + gr_block_sptr link() { return gr_block_sptr(d_link); } + + + /*! + * \brief Given a [start,end), returns a vector all tags in the range. + * + * Get a vector of tags in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<gr_tag_t> &v, + uint64_t abs_start, + uint64_t abs_end); + + // ------------------------------------------------------------------------- + + private: + + friend class gr_buffer; + friend GR_RUNTIME_API gr_buffer_reader_sptr + gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link); + + + gr_buffer_sptr d_buffer; + unsigned int d_read_index; // in items [0,d->buffer.d_bufsize) + uint64_t d_abs_read_offset; // num items seen since the start + boost::weak_ptr<gr_block> d_link; // block that reads via this buffer reader + + //! constructor is private. Use gr_buffer::add_reader to create instances + gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link); +}; + +//! returns # of gr_buffer_readers currently allocated +GR_RUNTIME_API long gr_buffer_reader_ncurrently_allocated (); + + +#endif /* INCLUDED_GR_BUFFER_H */ diff --git a/gnuradio-runtime/include/gr_complex.h b/gnuradio-runtime/include/gr_complex.h new file mode 100644 index 0000000000..6166c0b142 --- /dev/null +++ b/gnuradio-runtime/include/gr_complex.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_COMPLEX_H +#define INCLUDED_GR_COMPLEX_H + +#include <complex> +typedef std::complex<float> gr_complex; +typedef std::complex<double> gr_complexd; + +inline bool is_complex (gr_complex x) { (void) x; return true;} +inline bool is_complex (gr_complexd x) { (void) x; return true;} +inline bool is_complex (float x) { (void) x; return false;} +inline bool is_complex (double x) { (void) x; return false;} +inline bool is_complex (int x) { (void) x; return false;} +inline bool is_complex (char x) { (void) x; return false;} +inline bool is_complex (short x) { (void) x; return false;} + +// this doesn't really belong here, but there are worse places for it... + +#define CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected,actual,delta) \ + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.real(), actual.real(), delta); \ + CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.imag(), actual.imag(), delta); + +#endif /* INCLUDED_GR_COMPLEX_H */ + diff --git a/gnuradio-runtime/include/gr_constants.h b/gnuradio-runtime/include/gr_constants.h new file mode 100644 index 0000000000..3534166bc0 --- /dev/null +++ b/gnuradio-runtime/include/gr_constants.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_CONSTANTS_H +#define INCLUDED_GR_CONSTANTS_H + +#include <gr_runtime_api.h> +#include <string> + +/*! + * \brief return ./configure --prefix argument. Typically /usr/local + */ +GR_RUNTIME_API const std::string gr_prefix(); + +/*! + * \brief return ./configure --sysconfdir argument. Typically $prefix/etc or /etc + */ +GR_RUNTIME_API const std::string gr_sysconfdir(); + +/*! + * \brief return preferences file directory. Typically $sysconfdir/etc/conf.d + */ +GR_RUNTIME_API const std::string gr_prefsdir(); + +/*! + * \brief return date/time of build, as set when 'bootstrap' is run + */ +GR_RUNTIME_API const std::string gr_build_date(); + +/*! + * \brief return version string defined in configure.ac + */ +GR_RUNTIME_API const std::string gr_version(); + +#endif /* INCLUDED_GR_CONSTANTS_H */ diff --git a/gnuradio-runtime/include/gr_dispatcher.h b/gnuradio-runtime/include/gr_dispatcher.h new file mode 100644 index 0000000000..7a9e80c9fe --- /dev/null +++ b/gnuradio-runtime/include/gr_dispatcher.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_DISPATCHER_H +#define INCLUDED_GR_DISPATCHER_H + +#include <gr_runtime_api.h> +#include <gr_select_handler.h> +#include <vector> + +class gr_dispatcher; +typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr; + +GR_RUNTIME_API gr_dispatcher_sptr gr_dispatcher_singleton(); +GR_RUNTIME_API gr_dispatcher_sptr gr_make_dispatcher(); + +/*! + * \brief invoke callbacks based on select. + * \ingroup internal + * + * \sa gr_select_handler + */ +class GR_RUNTIME_API gr_dispatcher +{ + gr_dispatcher(); + friend GR_RUNTIME_API gr_dispatcher_sptr gr_make_dispatcher(); + + std::vector<gr_select_handler_sptr> d_handler; + int d_max_index; + +public: + ~gr_dispatcher(); + + bool add_handler(gr_select_handler_sptr handler); + bool del_handler(gr_select_handler_sptr handler); + bool del_handler(gr_select_handler *handler); + + /*! + * \brief Event dispatching loop. + * + * Enter a polling loop that only terminates after all gr_select_handlers + * have been removed. \p timeout sets the timeout parameter to the select() + * call, measured in seconds. + * + * \param timeout maximum number of seconds to block in select. + */ + void loop(double timeout=10); +}; + +#endif /* INCLUDED_GR_DISPATCHER_H */ diff --git a/gnuradio-runtime/include/gr_endianness.h b/gnuradio-runtime/include/gr_endianness.h new file mode 100644 index 0000000000..c4ecb1383e --- /dev/null +++ b/gnuradio-runtime/include/gr_endianness.h @@ -0,0 +1,27 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_ENDIANNESS_H +#define INCLUDED_GR_ENDIANNESS_H + +typedef enum {GR_MSB_FIRST, GR_LSB_FIRST} gr_endianness_t; + +#endif /* INCLUDED_GR_ENDIANNESS_H */ diff --git a/gnuradio-runtime/include/gr_error_handler.h b/gnuradio-runtime/include/gr_error_handler.h new file mode 100644 index 0000000000..4d326a6ba1 --- /dev/null +++ b/gnuradio-runtime/include/gr_error_handler.h @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +/* + * This code is based on error.hh from the "Click Modular Router". + * Original copyright follows: + */ +/* + * error.{cc,hh} -- flexible classes for error reporting + * Eddie Kohler + * + * Copyright (c) 1999-2000 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, subject to the conditions + * listed in the Click LICENSE file. These conditions include: you must + * preserve this copyright notice, and you cannot mention the copyright + * holders in advertising related to the Software without their permission. + * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This + * notice is a summary of the Click LICENSE file; the license in that file is + * legally binding. + */ + +#ifndef INCLUDED_GR_ERROR_HANDLER_H +#define INCLUDED_GR_ERROR_HANDLER_H + +#include <gr_runtime_api.h> +#include <stdarg.h> +#include <string> +#include <cstdio> // for FILE + +/*! + * \brief abstract error handler + * \ingroup base + */ +class GR_RUNTIME_API gr_error_handler { +public: + enum seriousness { + ERR_DEBUG = 0x00000000, + ERR_MESSAGE = 0x00010000, + ERR_WARNING = 0x00020000, + ERR_ERROR = 0x00030000, + ERR_FATAL = 0x00040000 + }; + + gr_error_handler() {} + virtual ~gr_error_handler(); + + static gr_error_handler *default_handler(); + static gr_error_handler *silent_handler(); + + static bool has_default_handler(); + static void set_default_handler(gr_error_handler *errh); + + void debug(const char *format, ...); + void message(const char *format, ...); + void warning(const char *format, ...); + void error(const char *format, ...); + void fatal(const char *format, ...); + + virtual int nwarnings() const = 0; + virtual int nerrors() const = 0; + virtual void reset_counts() = 0; + + void verror(seriousness s, const char *format, va_list); + void verror_text(seriousness s, const std::string &text); + +protected: + virtual void count_error(seriousness s) = 0; + virtual void handle_text(seriousness s, const std::string &str) = 0; + std::string make_text(seriousness s, const char *format, va_list); +}; + + +class GR_RUNTIME_API gr_base_error_handler : public gr_error_handler { + int d_nwarnings; + int d_nerrors; + +public: + gr_base_error_handler() : d_nwarnings(0), d_nerrors(0) {} + int nwarnings() const { return d_nwarnings; } + int nerrors() const { return d_nerrors; } + void reset_counts() { d_nwarnings = d_nerrors = 0; } + void count_error(seriousness s); +}; + +class GR_RUNTIME_API gr_file_error_handler : public gr_base_error_handler { + FILE *d_file; + int d_fd; +public: + gr_file_error_handler(FILE *file); + gr_file_error_handler(int file_descriptor); + ~gr_file_error_handler(); + + void handle_text(seriousness s, const std::string &str); +}; + +#endif /* INCLUDED_GR_ERROR_HANDLER_H */ diff --git a/gnuradio-runtime/include/gr_expj.h b/gnuradio-runtime/include/gr_expj.h new file mode 100644 index 0000000000..56291a0a6a --- /dev/null +++ b/gnuradio-runtime/include/gr_expj.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_EXPJ_H +#define INCLUDED_GR_EXPJ_H + +#include <gr_runtime_api.h> +#include <gr_sincos.h> +#include <gr_types.h> + +static inline gr_complex +gr_expj(float phase) +{ + float t_imag, t_real; + gr_sincosf(phase, &t_imag, &t_real); + return gr_complex(t_real, t_imag); +} + + +#endif /* INCLUDED_GR_EXPJ_H */ diff --git a/gnuradio-runtime/include/gr_feval.h b/gnuradio-runtime/include/gr_feval.h new file mode 100644 index 0000000000..07df592e58 --- /dev/null +++ b/gnuradio-runtime/include/gr_feval.h @@ -0,0 +1,177 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_FEVAL_H +#define INCLUDED_GR_FEVAL_H + +#include <gr_runtime_api.h> +#include <gr_complex.h> +#include <pmt/pmt.h> + +/*! + * \brief base class for evaluating a function: double -> double + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ + * and is callable from both places. It uses SWIG's + * "director" feature to implement the magic. + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ +class GR_RUNTIME_API gr_feval_dd +{ +protected: + /*! + * \brief override this to define the function + */ + virtual double eval(double x); + +public: + gr_feval_dd() {} + virtual ~gr_feval_dd(); + + virtual double calleval(double x); // invoke "eval" +}; + +/*! + * \brief base class for evaluating a function: complex -> complex + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ + * and is callable from both places. It uses SWIG's + * "director" feature to implement the magic. + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ +class GR_RUNTIME_API gr_feval_cc +{ +protected: + /*! + * \brief override this to define the function + */ + virtual gr_complex eval(gr_complex x); + +public: + gr_feval_cc() {} + virtual ~gr_feval_cc(); + + virtual gr_complex calleval(gr_complex x); // invoke "eval" +}; + +/*! + * \brief base class for evaluating a function: long -> long + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ + * and is callable from both places. It uses SWIG's + * "director" feature to implement the magic. + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ +class GR_RUNTIME_API gr_feval_ll +{ +protected: + /*! + * \brief override this to define the function + */ + virtual long eval(long x); + +public: + gr_feval_ll() {} + virtual ~gr_feval_ll(); + + virtual long calleval(long x); // invoke "eval" +}; + +/*! + * \brief base class for evaluating a function: void -> void + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ + * and is callable from both places. It uses SWIG's + * "director" feature to implement the magic. + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ +class GR_RUNTIME_API gr_feval +{ +protected: + /*! + * \brief override this to define the function + */ + virtual void eval(); + +public: + gr_feval() {} + virtual ~gr_feval(); + + virtual void calleval(); // invoke "eval" +}; + +/*! + * \brief base class for evaluating a function: pmt -> void + * \ingroup misc + * + * This class is designed to be subclassed in Python or C++ + * and is callable from both places. It uses SWIG's + * "director" feature to implement the magic. + * It's slow. Don't use it in a performance critical path. + * + * Override eval to define the behavior. + * Use calleval to invoke eval (this kludge is required to allow a + * python specific "shim" to be inserted. + */ +class GR_RUNTIME_API gr_feval_p +{ +protected: + /*! + * \brief override this to define the function + */ + virtual void eval(pmt::pmt_t x); + +public: + gr_feval_p() {} + virtual ~gr_feval_p(); + + virtual void calleval(pmt::pmt_t x); // invoke "eval" +}; + +/*! + * \brief trivial examples / test cases showing C++ calling Python code + */ +GR_RUNTIME_API double gr_feval_dd_example(gr_feval_dd *f, double x); +GR_RUNTIME_API gr_complex gr_feval_cc_example(gr_feval_cc *f, gr_complex x); +GR_RUNTIME_API long gr_feval_ll_example(gr_feval_ll *f, long x); +GR_RUNTIME_API void gr_feval_example(gr_feval *f); + +#endif /* INCLUDED_GR_FEVAL_H */ diff --git a/gnuradio-runtime/include/gr_flowgraph.h b/gnuradio-runtime/include/gr_flowgraph.h new file mode 100644 index 0000000000..107c50b7b6 --- /dev/null +++ b/gnuradio-runtime/include/gr_flowgraph.h @@ -0,0 +1,251 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_FLOWGRAPH_H +#define INCLUDED_GR_FLOWGRAPH_H + +#include <gr_runtime_api.h> +#include <gr_basic_block.h> +#include <iostream> + +/*! + * \brief Class representing a specific input or output graph endpoint + * \ingroup internal + */ +class GR_RUNTIME_API gr_endpoint +{ +private: + gr_basic_block_sptr d_basic_block; + int d_port; + +public: + gr_endpoint() : d_basic_block(), d_port(0) { } + gr_endpoint(gr_basic_block_sptr block, int port) { d_basic_block = block; d_port = port; } + gr_basic_block_sptr block() const { return d_basic_block; } + int port() const { return d_port; } + + bool operator==(const gr_endpoint &other) const; +}; + +inline bool gr_endpoint::operator==(const gr_endpoint &other) const +{ + return (d_basic_block == other.d_basic_block && + d_port == other.d_port); +} + +class GR_RUNTIME_API gr_msg_endpoint +{ +private: + gr_basic_block_sptr d_basic_block; + pmt::pmt_t d_port; + bool d_is_hier; +public: + gr_msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) { } + gr_msg_endpoint(gr_basic_block_sptr block, pmt::pmt_t port, bool is_hier=false){ d_basic_block = block; d_port = port; d_is_hier = is_hier;} + gr_basic_block_sptr block() const { return d_basic_block; } + pmt::pmt_t port() const { return d_port; } + bool is_hier() const { return d_is_hier; } + void set_hier(bool h) { d_is_hier = h; } + + bool operator==(const gr_msg_endpoint &other) const; + +}; + +inline bool gr_msg_endpoint::operator==(const gr_msg_endpoint &other) const +{ + return (d_basic_block == other.d_basic_block && + pmt::equal(d_port, other.d_port)); +} + + +// Hold vectors of gr_endpoint objects +typedef std::vector<gr_endpoint> gr_endpoint_vector_t; +typedef std::vector<gr_endpoint>::iterator gr_endpoint_viter_t; + +/*! + *\brief Class representing a connection between to graph endpoints + * + */ +class GR_RUNTIME_API gr_edge +{ +public: + gr_edge() : d_src(), d_dst() { }; + gr_edge(const gr_endpoint &src, const gr_endpoint &dst) : d_src(src), d_dst(dst) { } + ~gr_edge(); + + const gr_endpoint &src() const { return d_src; } + const gr_endpoint &dst() const { return d_dst; } + +private: + gr_endpoint d_src; + gr_endpoint d_dst; +}; + + +// Hold vectors of gr_edge objects +typedef std::vector<gr_edge> gr_edge_vector_t; +typedef std::vector<gr_edge>::iterator gr_edge_viter_t; + + +/*! + *\brief Class representing a msg connection between to graph msg endpoints + * + */ +class GR_RUNTIME_API gr_msg_edge +{ +public: + gr_msg_edge() : d_src(), d_dst() { }; + gr_msg_edge(const gr_msg_endpoint &src, const gr_msg_endpoint &dst) : d_src(src), d_dst(dst) { } + ~gr_msg_edge() {} + + const gr_msg_endpoint &src() const { return d_src; } + const gr_msg_endpoint &dst() const { return d_dst; } + +private: + gr_msg_endpoint d_src; + gr_msg_endpoint d_dst; +}; + +// Hold vectors of gr_edge objects +typedef std::vector<gr_msg_edge> gr_msg_edge_vector_t; +typedef std::vector<gr_msg_edge>::iterator gr_msg_edge_viter_t; + +// Create a shared pointer to a heap allocated flowgraph +// (types defined in gr_runtime_types.h) +GR_RUNTIME_API gr_flowgraph_sptr gr_make_flowgraph(); + +/*! + * \brief Class representing a directed, acyclic graph of basic blocks + * \ingroup internal + */ +class GR_RUNTIME_API gr_flowgraph +{ +public: + friend GR_RUNTIME_API gr_flowgraph_sptr gr_make_flowgraph(); + + // Destruct an arbitrary flowgraph + ~gr_flowgraph(); + + // Connect two endpoints + void connect(const gr_endpoint &src, const gr_endpoint &dst); + + // Disconnect two endpoints + void disconnect(const gr_endpoint &src, const gr_endpoint &dst); + + // Connect an output port to an input port (convenience) + void connect(gr_basic_block_sptr src_block, int src_port, + gr_basic_block_sptr dst_block, int dst_port); + + // Disconnect an input port from an output port (convenience) + void disconnect(gr_basic_block_sptr src_block, int src_port, + gr_basic_block_sptr dst_block, int dst_port); + + // Connect two msg endpoints + void connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst); + + // Disconnect two msg endpoints + void disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst); + + // Validate connectivity, raise exception if invalid + void validate(); + + // Clear existing flowgraph + void clear(); + + // Return vector of edges + const gr_edge_vector_t &edges() const { return d_edges; } + + // Return vector of msg edges + const gr_msg_edge_vector_t &msg_edges() const { return d_msg_edges; } + + // Return vector of connected blocks + gr_basic_block_vector_t calc_used_blocks(); + + // Return toplogically sorted vector of blocks. All the sources come first. + gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks); + + // Return vector of vectors of disjointly connected blocks, topologically + // sorted. + std::vector<gr_basic_block_vector_t> partition(); + +protected: + gr_basic_block_vector_t d_blocks; + gr_edge_vector_t d_edges; + gr_msg_edge_vector_t d_msg_edges; + + gr_flowgraph(); + std::vector<int> calc_used_ports(gr_basic_block_sptr block, bool check_inputs); + gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, int port); + gr_edge_vector_t calc_upstream_edges(gr_basic_block_sptr block); + bool has_block_p(gr_basic_block_sptr block); + gr_edge calc_upstream_edge(gr_basic_block_sptr block, int port); + +private: + + void check_valid_port(gr_io_signature_sptr sig, int port); + void check_valid_port(const gr_msg_endpoint &e); + void check_dst_not_used(const gr_endpoint &dst); + void check_type_match(const gr_endpoint &src, const gr_endpoint &dst); + gr_edge_vector_t calc_connections(gr_basic_block_sptr block, bool check_inputs); // false=use outputs + void check_contiguity(gr_basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs); + + gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block); + gr_basic_block_vector_t calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); + void reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); + gr_basic_block_vector_t calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); + gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks); + bool source_p(gr_basic_block_sptr block); + void topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output); +}; + +// Convenience functions +inline +void gr_flowgraph::connect(gr_basic_block_sptr src_block, int src_port, + gr_basic_block_sptr dst_block, int dst_port) +{ + connect(gr_endpoint(src_block, src_port), + gr_endpoint(dst_block, dst_port)); +} + +inline +void gr_flowgraph::disconnect(gr_basic_block_sptr src_block, int src_port, + gr_basic_block_sptr dst_block, int dst_port) +{ + disconnect(gr_endpoint(src_block, src_port), + gr_endpoint(dst_block, dst_port)); +} + +inline std::ostream& +operator <<(std::ostream &os, const gr_endpoint endp) +{ + os << endp.block()->alias() << ":" << endp.port(); + return os; +} + +inline std::ostream& +operator <<(std::ostream &os, const gr_edge edge) +{ + os << edge.src() << "->" << edge.dst(); + return os; +} + +#endif /* INCLUDED_GR_FLOWGRAPH_H */ diff --git a/gnuradio-runtime/include/gr_fxpt.h b/gnuradio-runtime/include/gr_fxpt.h new file mode 100644 index 0000000000..b7e3518ffb --- /dev/null +++ b/gnuradio-runtime/include/gr_fxpt.h @@ -0,0 +1,104 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_FXPT_H +#define INCLUDED_GR_FXPT_H + +#include <gr_runtime_api.h> +#include <gr_types.h> + +/*! + * \brief fixed point sine and cosine and friends. + * \ingroup misc + * + * fixed pt radians + * --------- -------- + * -2**31 -pi + * 0 0 + * 2**31-1 pi - epsilon + * + */ +class GR_RUNTIME_API gr_fxpt +{ + static const int WORDBITS = 32; + static const int NBITS = 10; + static const float s_sine_table[1 << NBITS][2]; + static const float PI; + static const float TWO_TO_THE_31; +public: + + static gr_int32 + float_to_fixed (float x) + { + // Fold x into -PI to PI. + int d = (int)floor(x/2/PI+0.5); + x -= d*2*PI; + // And convert to an integer. + return (gr_int32) ((float) x * TWO_TO_THE_31 / PI); + } + + static float + fixed_to_float (gr_int32 x) + { + return x * (PI / TWO_TO_THE_31); + } + + /*! + * \brief Given a fixed point angle x, return float sine (x) + */ + static float + sin (gr_int32 x) + { + gr_uint32 ux = x; + int index = ux >> (WORDBITS - NBITS); + return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; + } + + /* + * \brief Given a fixed point angle x, return float cosine (x) + */ + static float + cos (gr_int32 x) + { + gr_uint32 ux = x + 0x40000000; + int index = ux >> (WORDBITS - NBITS); + return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1]; + } + + /* + * \brief Given a fixedpoint angle x, return float cos(x) and sin (x) + */ + static void sincos(gr_int32 x, float *s, float *c) + { + gr_uint32 ux = x; + int sin_index = ux >> (WORDBITS - NBITS); + *s = s_sine_table[sin_index][0] * (ux >> 1) + s_sine_table[sin_index][1]; + + ux = x + 0x40000000; + int cos_index = ux >> (WORDBITS - NBITS); + *c = s_sine_table[cos_index][0] * (ux >> 1) + s_sine_table[cos_index][1]; + + return; + } + +}; + +#endif /* INCLUDED_GR_FXPT_H */ diff --git a/gnuradio-runtime/include/gr_fxpt_nco.h b/gnuradio-runtime/include/gr_fxpt_nco.h new file mode 100644 index 0000000000..36b99ee132 --- /dev/null +++ b/gnuradio-runtime/include/gr_fxpt_nco.h @@ -0,0 +1,153 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_FXPT_NCO_H +#define INCLUDED_GR_FXPT_NCO_H + +#include <gr_runtime_api.h> +#include <gr_fxpt.h> +#include <gr_complex.h> + +/*! + * \brief Numerically Controlled Oscillator (NCO) + * \ingroup misc + */ +class /*GR_RUNTIME_API*/ gr_fxpt_nco { + gr_uint32 d_phase; + gr_int32 d_phase_inc; + +public: + gr_fxpt_nco () : d_phase (0), d_phase_inc (0) {} + + ~gr_fxpt_nco () {} + + // radians + void set_phase (float angle) { + d_phase = gr_fxpt::float_to_fixed (angle); + } + + void adjust_phase (float delta_phase) { + d_phase += gr_fxpt::float_to_fixed (delta_phase); + } + + // angle_rate is in radians / step + void set_freq (float angle_rate){ + d_phase_inc = gr_fxpt::float_to_fixed (angle_rate); + } + + // angle_rate is a delta in radians / step + void adjust_freq (float delta_angle_rate) + { + d_phase_inc += gr_fxpt::float_to_fixed (delta_angle_rate); + } + + // increment current phase angle + + void step () + { + d_phase += d_phase_inc; + } + + void step (int n) + { + d_phase += d_phase_inc * n; + } + + // units are radians / step + float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); } + float get_freq () const { return gr_fxpt::fixed_to_float (d_phase_inc); } + + // compute sin and cos for current phase angle + void sincos (float *sinx, float *cosx) const + { + *sinx = gr_fxpt::sin (d_phase); + *cosx = gr_fxpt::cos (d_phase); + } + + // compute cos and sin for a block of phase angles + void sincos (gr_complex *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = gr_complex(gr_fxpt::cos (d_phase) * ampl, gr_fxpt::sin (d_phase) * ampl); + step (); + } + } + + // compute sin for a block of phase angles + void sin (float *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (float)(gr_fxpt::sin (d_phase) * ampl); + step (); + } + } + + // compute cos for a block of phase angles + void cos (float *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (float)(gr_fxpt::cos (d_phase) * ampl); + step (); + } + } + + // compute sin for a block of phase angles + void sin (short *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (short)(gr_fxpt::sin (d_phase) * ampl); + step (); + } + } + + // compute cos for a block of phase angles + void cos (short *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (short)(gr_fxpt::cos (d_phase) * ampl); + step (); + } + } + + // compute sin for a block of phase angles + void sin (int *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (int)(gr_fxpt::sin (d_phase) * ampl); + step (); + } + } + + // compute cos for a block of phase angles + void cos (int *output, int noutput_items, double ampl=1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (int)(gr_fxpt::cos (d_phase) * ampl); + step (); + } + } + + // compute cos or sin for current phase angle + float cos () const { return gr_fxpt::cos (d_phase); } + float sin () const { return gr_fxpt::sin (d_phase); } +}; + +#endif /* INCLUDED_GR_FXPT_NCO_H */ diff --git a/gnuradio-runtime/include/gr_fxpt_vco.h b/gnuradio-runtime/include/gr_fxpt_vco.h new file mode 100644 index 0000000000..15e7327f79 --- /dev/null +++ b/gnuradio-runtime/include/gr_fxpt_vco.h @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004,2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_FXPT_VCO_H +#define INCLUDED_GR_FXPT_VCO_H + +#include <gr_runtime_api.h> +#include <gr_fxpt.h> +#include <gr_complex.h> + +/*! + * \brief Voltage Controlled Oscillator (VCO) + * \ingroup misc + */ +class /*GR_RUNTIME_API*/ gr_fxpt_vco { + gr_int32 d_phase; + +public: + gr_fxpt_vco () : d_phase (0) {} + + ~gr_fxpt_vco () {} + + // radians + void set_phase (float angle) { + d_phase = gr_fxpt::float_to_fixed (angle); + } + + void adjust_phase (float delta_phase) { + d_phase += gr_fxpt::float_to_fixed (delta_phase); + } + + float get_phase () const { return gr_fxpt::fixed_to_float (d_phase); } + + // compute sin and cos for current phase angle + void sincos (float *sinx, float *cosx) const + { + *sinx = gr_fxpt::sin (d_phase); + *cosx = gr_fxpt::cos (d_phase); + } + + // compute a block at a time + void cos (float *output, const float *input, int noutput_items, float k, float ampl = 1.0) + { + for (int i = 0; i < noutput_items; i++){ + output[i] = (float)(gr_fxpt::cos (d_phase) * ampl); + adjust_phase(input[i] * k); + } + } + + // compute cos or sin for current phase angle + float cos () const { return gr_fxpt::cos (d_phase); } + float sin () const { return gr_fxpt::sin (d_phase); } +}; + +#endif /* INCLUDED_GR_FXPT_VCO_H */ diff --git a/gnuradio-runtime/include/gr_hier_block2.h b/gnuradio-runtime/include/gr_hier_block2.h new file mode 100644 index 0000000000..c39a98f6d7 --- /dev/null +++ b/gnuradio-runtime/include/gr_hier_block2.h @@ -0,0 +1,208 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_HIER_BLOCK2_H +#define INCLUDED_GR_HIER_BLOCK2_H + +#include <gr_runtime_api.h> +#include <gr_basic_block.h> + +/*! + * \brief public constructor for gr_hier_block2 + + */ +GR_RUNTIME_API gr_hier_block2_sptr gr_make_hier_block2(const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + +class gr_hier_block2_detail; + +/*! + * \brief Hierarchical container class for gr_block's and gr_hier_block2's + * \ingroup container_blk + * \ingroup base_blk + * + */ +class GR_RUNTIME_API gr_hier_block2 : public gr_basic_block +{ +private: + friend class gr_hier_block2_detail; + friend GR_RUNTIME_API gr_hier_block2_sptr gr_make_hier_block2(const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + + /*! + * \brief Private implementation details of gr_hier_block2 + */ + gr_hier_block2_detail *d_detail; + +protected: + gr_hier_block2 (void){} //allows pure virtual interface sub-classes + gr_hier_block2(const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + +public: + virtual ~gr_hier_block2(); + + /*! + * \brief typedef for object returned from self(). + * + * This type is only guaranteed to be passable to connect and disconnect. + * No other assumptions should be made about it. + */ + typedef gr_basic_block_sptr opaque_self; + + /*! + * \brief Return an object, representing the current block, which can be passed to connect. + * + * The returned object may only be used as an argument to connect or disconnect. + * Any other use of self() results in unspecified (erroneous) behavior. + */ + opaque_self self(); + + /*! + * \brief Add a stand-alone (possibly hierarchical) block to internal graph + * + * This adds a gr-block or hierarchical block to the internal graph + * without wiring it to anything else. + */ + void connect(gr_basic_block_sptr block); + + /*! + * \brief Add gr-blocks or hierarchical blocks to internal graph and wire together + * + * This adds (if not done earlier by another connect) a pair of gr-blocks or + * hierarchical blocks to the internal flowgraph, and wires the specified output + * port to the specified input port. + */ + void connect(gr_basic_block_sptr src, int src_port, + gr_basic_block_sptr dst, int dst_port); + + /*! + * \brief Add gr-blocks or hierarchical blocks to internal graph and wire together + * + * This adds (if not done earlier by another connect) a pair of gr-blocks or + * hierarchical blocks to the internal message port subscription + */ + void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); + void msg_connect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport); + void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport, + gr_basic_block_sptr dst, pmt::pmt_t dstport); + void msg_disconnect(gr_basic_block_sptr src, std::string srcport, + gr_basic_block_sptr dst, std::string dstport); + + /*! + * \brief Remove a gr-block or hierarchical block from the internal flowgraph. + * + * This removes a gr-block or hierarchical block from the internal flowgraph, + * disconnecting it from other blocks as needed. + * + */ + void disconnect(gr_basic_block_sptr block); + + /*! + * \brief Disconnect a pair of gr-blocks or hierarchical blocks in internal + * flowgraph. + * + * This disconnects the specified input port from the specified output port + * of a pair of gr-blocks or hierarchical blocks. + */ + void disconnect(gr_basic_block_sptr src, int src_port, + gr_basic_block_sptr dst, int dst_port); + + /*! + * \brief Disconnect all connections in the internal flowgraph. + * + * This call removes all output port to input port connections in the internal + * flowgraph. + */ + void disconnect_all(); + + /*! + * Lock a flowgraph in preparation for reconfiguration. When an equal + * number of calls to lock() and unlock() have occurred, the flowgraph + * will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph thread + * (E.g., gr_block::work method) or deadlock will occur when + * reconfiguration happens. + */ + virtual void lock(); + + /*! + * Unlock a flowgraph in preparation for reconfiguration. When an equal + * number of calls to lock() and unlock() have occurred, the flowgraph + * will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph thread + * (E.g., gr_block::work method) or deadlock will occur when + * reconfiguration happens. + */ + virtual void unlock(); + + // This is a public method for ease of code organization, but should be + // ignored by the user. + gr_flat_flowgraph_sptr flatten() const; + + gr_hier_block2_sptr to_hier_block2(); // Needed for Python type coercion + + bool has_msg_port(pmt::pmt_t which_port){ + return message_port_is_hier(which_port) || gr_basic_block::has_msg_port(which_port); + } + + bool message_port_is_hier(pmt::pmt_t port_id){ + return message_port_is_hier_in(port_id) || message_port_is_hier_out(port_id); + } + bool message_port_is_hier_in(pmt::pmt_t port_id){ + return pmt::list_has(hier_message_ports_in, port_id); + } + bool message_port_is_hier_out(pmt::pmt_t port_id){ + return pmt::list_has(hier_message_ports_out, port_id); + } + + pmt::pmt_t hier_message_ports_in; + pmt::pmt_t hier_message_ports_out; + + void message_port_register_hier_in(pmt::pmt_t port_id){ + if(pmt::list_has(hier_message_ports_in, port_id)) + throw std::invalid_argument("hier msg in port by this name already registered"); + if(msg_queue.find(port_id) != msg_queue.end()) + throw std::invalid_argument("block already has a primitive input port by this name"); + hier_message_ports_in = pmt::list_add(hier_message_ports_in, port_id); + } + void message_port_register_hier_out(pmt::pmt_t port_id){ + if(pmt::list_has(hier_message_ports_out, port_id)) + throw std::invalid_argument("hier msg out port by this name already registered"); + if(pmt::dict_has_key(message_subscribers, port_id)) + throw std::invalid_argument("block already has a primitive output port by this name"); + hier_message_ports_out = pmt::list_add(hier_message_ports_out, port_id); + } + +}; + +inline gr_hier_block2_sptr cast_to_hier_block2_sptr(gr_basic_block_sptr block) { + return boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(block); +} + +#endif /* INCLUDED_GR_HIER_BLOCK2_H */ diff --git a/gnuradio-runtime/include/gr_io_signature.h b/gnuradio-runtime/include/gr_io_signature.h new file mode 100644 index 0000000000..345cd6b9d2 --- /dev/null +++ b/gnuradio-runtime/include/gr_io_signature.h @@ -0,0 +1,117 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IO_SIGNATURE_H +#define INCLUDED_IO_SIGNATURE_H + +#include <gr_runtime_api.h> +#include <gr_runtime_types.h> + +/*! + * \brief Create an i/o signature + * + * \ingroup internal + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item specify the size of the items in each stream + */ +GR_RUNTIME_API gr_io_signature_sptr +gr_make_io_signature(int min_streams, int max_streams, + int sizeof_stream_item); + +/*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item1 specify the size of the items in the first stream + * \param sizeof_stream_item2 specify the size of the items in the second and subsequent streams + */ +GR_RUNTIME_API gr_io_signature_sptr +gr_make_io_signature2(int min_streams, int max_streams, + int sizeof_stream_item1, + int sizeof_stream_item2 + ); + +/*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_item1 specify the size of the items in the first stream + * \param sizeof_stream_item2 specify the size of the items in the second stream + * \param sizeof_stream_item3 specify the size of the items in the third and subsequent streams + */ +GR_RUNTIME_API gr_io_signature_sptr +gr_make_io_signature3(int min_streams, int max_streams, + int sizeof_stream_item1, + int sizeof_stream_item2, + int sizeof_stream_item3 + ); + +/*! + * \brief Create an i/o signature + * + * \param min_streams specify minimum number of streams (>= 0) + * \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite) + * \param sizeof_stream_items specify the size of the items in the streams + * + * If there are more streams than there are entries in sizeof_stream_items, the + * value of the last entry in sizeof_stream_items is used for the missing values. + * sizeof_stream_items must contain at least 1 entry. + */ +GR_RUNTIME_API gr_io_signature_sptr +gr_make_io_signaturev(int min_streams, int max_streams, + const std::vector<int> &sizeof_stream_items); + + +/*! + * \brief i/o signature for input and output ports. + * \brief misc + */ +class GR_RUNTIME_API gr_io_signature { + int d_min_streams; + int d_max_streams; + std::vector<int> d_sizeof_stream_item; + + gr_io_signature(int min_streams, int max_streams, + const std::vector<int> &sizeof_stream_items); + + friend GR_RUNTIME_API gr_io_signature_sptr + gr_make_io_signaturev(int min_streams, + int max_streams, + const std::vector<int> &sizeof_stream_items); + + public: + + static const int IO_INFINITE = -1; + + ~gr_io_signature (); + + int min_streams () const { return d_min_streams; } + int max_streams () const { return d_max_streams; } + int sizeof_stream_item (int index) const; + std::vector<int> sizeof_stream_items() const; +}; + + +#endif /* INCLUDED_IO_SIGNATURE_H */ diff --git a/gnuradio-runtime/include/gr_logger.h b/gnuradio-runtime/include/gr_logger.h new file mode 100644 index 0000000000..2c1ee8d8ad --- /dev/null +++ b/gnuradio-runtime/include/gr_logger.h @@ -0,0 +1,644 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/******************************************************************************* +* Author: Mark Plett +* Description: +* The gr_logger module wraps the log4cpp library for logging in gnuradio +*******************************************************************************/ + +#ifndef INCLUDED_GR_LOGGER_H +#define INCLUDED_GR_LOGGER_H + +/*! +* \file gr_logger.h +* \ingroup logging +* \brief GNURADIO logging wrapper for log4cpp library (C++ port of log4j) +* +*/ + +#include <gr_runtime_api.h> +#include <assert.h> +#include <iostream> +#include <boost/filesystem.hpp> +#include <boost/thread.hpp> +#include <boost/format.hpp> + +#ifdef ENABLE_GR_LOG + +// We have three configurations... first logging to stdout/stderr +#ifndef HAVE_LOG4CPP +//#warning GR logging Enabled and using std::cout + +typedef std::string gr_logger_ptr; + +#define GR_LOG_DECLARE_LOGPTR(logger) +#define GR_LOG_ASSIGN_LOGPTR(logger,name) +#define GR_CONFIG_LOGGER(config) +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) +#define GR_LOG_GETLOGGER(logger, name) +#define GR_SET_LEVEL(name, level) +#define GR_LOG_SET_LEVEL(logger, level) +#define GR_GET_LEVEL(name, level) +#define GR_LOG_GET_LEVEL(logger, level) +#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_ADD_FILE_APPENDER(name,filename,append,pattern) +#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) +#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) +#define GR_GET_LOGGER_NAMES(names) +#define GR_RESET_CONFIGURATION() +#define GR_DEBUG(name, msg) std::cout<<"DEBUG: "<<msg<<std::endl +#define GR_INFO(name, msg) std::cout<<"INFO: "<<msg<<std::endl +#define GR_NOTICE(name, msg) std::cout<<"NOTICE: "<<msg<<std::endl +#define GR_WARN(name, msg) std::cerr<<"WARN: "<<msg<<std::endl +#define GR_ERROR(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_ALERT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_CRIT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_FATAL(name, msg) std::cerr<<"FATAL: "<<msg<<std::endl +#define GR_EMERG(name, msg) std::cerr<<"EMERG: "<<msg<<std::endl +#define GR_ERRORIF(name, cond, msg) {if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;} +#define GR_ASSERT(name, cond, msg) {if(!(cond)) std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);} +#define GR_LOG_DEBUG(logger, msg) std::cout<<"DEBUG: "<<msg<<std::endl +#define GR_LOG_INFO(logger, msg) std::cout<<"INFO: "<<msg<<std::endl +#define GR_LOG_NOTICE(logger, msg) std::cout<<"NOTICE: "<<msg<<std::endl +#define GR_LOG_WARN(logger, msg) std::cerr<<"WARN: "<<msg<<std::endl +#define GR_LOG_ERROR(logger, msg) std::cerr<<"ERROR: "<<msg<<std::endl +#define GR_LOG_ALERT(logger, msg) std::cerr<<"ALERT: "<<msg<<std::endl +#define GR_LOG_CRIT(logger, msg) std::cerr<<"CRIT: "<<msg<<std::endl +#define GR_LOG_FATAL(logger, msg) std::cerr<<"FATAL: "<<msg<<std::endl +#define GR_LOG_EMERG(logger, msg) std::cerr<<"EMERG: "<<msg<<std::endl +#define GR_LOG_ERRORIF(logger, cond, msg) {\ + if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;} +#define GR_LOG_ASSERT(logger, cond, msg) {\ + if(!(cond)) {std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);};} + +#else /* HAVE_LOG4CPP */ +// Second configuration...logging to log4cpp + +#include <log4cpp/Category.hh> +#include <log4cpp/PropertyConfigurator.hh> +#include <log4cpp/FileAppender.hh> +#include <log4cpp/RollingFileAppender.hh> +#include <log4cpp/OstreamAppender.hh> +#include <log4cpp/PatternLayout.hh> + +/*! + * \brief GR_LOG macros + * \ingroup logging + * + * These macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros + * are: + * GR_LOG_DEBUG + * GR_LOG_INFO + * GR_LOG_WARN + * GR_LOG_TRACE + * GR_LOG_ERROR + * GR_LOG_ALERT + * GR_LOG_CRIT + * GR_LOG_FATAL + * GR_LOG_EMERG + */ +typedef log4cpp::Category* gr_logger_ptr; + +/* Macros for Programmatic Configuration */ +#define GR_LOG_DECLARE_LOGPTR(logger) \ + gr_logger_ptr logger; + +#define GR_LOG_ASSIGN_LOGPTR(logger,name) \ + logger = logger_get_logger(name); + +#define GR_CONFIG_LOGGER(config) \ + logger_config::load_config(config) + +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) \ + logger_config::load_config(config,period) + +#define GR_LOG_GETLOGGER(logger, name) \ + gr_logger_ptr logger = logger_get_logger(name); + +#define GR_SET_LEVEL(name, level){ \ + gr_logger_ptr logger = logger_get_logger(name);\ + logger_set_level(logger,level);} + +#define GR_LOG_SET_LEVEL(logger, level) \ + logger_set_level(logger, level); + +#define GR_GET_LEVEL(name, level){ \ + gr_logger_ptr logger = logger_get_logger(name);\ + logger_get_level(logger,level);} + +#define GR_LOG_GET_LEVEL(logger, level) \ + logger_get_level(logger,level); + +#define GR_ADD_CONSOLE_APPENDER(name,target,pattern){\ + gr_logger_ptr logger = logger_get_logger(name);\ + logger_add_console_appender(logger,target,pattern);} + +#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern){\ + logger_add_console_appender(logger,target,pattern);} + +#define GR_ADD_FILE_APPENDER(name,filename,append,pattern){\ + gr_logger_ptr logger = logger_get_logger(name);\ + logger_add_file_appender(logger,filename,append,pattern);} + +#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern){\ + logger_add_file_appender(logger,filename,append,pattern);} + +#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern){\ + gr_logger_ptr logger = logger_get_logger(name);\ + logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} + +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern){\ + logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);} + +#define GR_GET_LOGGER_NAMES(names){ \ + names = logger_get_logger_names();} + +#define GR_RESET_CONFIGURATION(){ \ + logger_config::reset_config();} + +/* Logger name referenced macros */ +#define GR_DEBUG(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::DEBUG << msg << log4cpp::eol;} + +#define GR_INFO(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::INFO << msg << log4cpp::eol;} + +#define GR_NOTICE(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger << log4cpp::Priority::NOTICE << msg;} + +#define GR_WARN(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::WARN << msg << log4cpp::eol;} + +#define GR_ERROR(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} + +#define GR_CRIT(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::CRIT << msg << log4cpp::eol;} + +#define GR_ALERT(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::ALERT << msg << log4cpp::eol;} + +#define GR_FATAL(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::FATAL << msg << log4cpp::eol;} + +#define GR_EMERG(name, msg) { \ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} + +#define GR_ERRORIF(name, cond, msg) { \ +if((cond)){\ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;};\ +}; + +#define GR_ASSERT(name, cond, msg) { \ +if(!(cond)){\ + gr_logger_ptr logger = logger_get_logger(name);\ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;};\ + assert(0);\ +}; + +/* LoggerPtr Referenced Macros */ +#define GR_LOG_DEBUG(logger, msg) { \ + *logger << log4cpp::Priority::DEBUG << msg << log4cpp::eol;} + +#define GR_LOG_INFO(logger, msg) { \ + *logger << log4cpp::Priority::INFO << msg << log4cpp::eol;} + +#define GR_LOG_NOTICE(logger, msg) { \ + *logger << log4cpp::Priority::NOTICE << msg << log4cpp::eol;} + +#define GR_LOG_WARN(logger, msg) { \ + *logger << log4cpp::Priority::WARN << msg << log4cpp::eol;} + +#define GR_LOG_ERROR(logger, msg) { \ + *logger << log4cpp::Priority::ERROR << msg << log4cpp::eol;} + +#define GR_LOG_CRIT(logger, msg) { \ + *logger << log4cpp::Priority::CRIT << msg << log4cpp::eol;} + +#define GR_LOG_ALERT(logger, msg) { \ + *logger << log4cpp::Priority::ALERT << msg << log4cpp::eol;} + +#define GR_LOG_FATAL(logger, msg) { \ + *logger << log4cpp::Priority::FATAL << msg << log4cpp::eol;} + +#define GR_LOG_EMERG(logger, msg) { \ + *logger << log4cpp::Priority::EMERG << msg << log4cpp::eol;} + +#define GR_LOG_ERRORIF(logger,cond, msg) { \ +if((cond)){\ + *logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;};\ +}; + +#define GR_LOG_ASSERT(logger, cond, msg) { \ +if(!(cond)){\ + *logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;\ + assert(0);};\ +}; + +/*! + * \brief Class to control configuration of logger. + * This is a singleton that cna launch a thread to wathc a config file for changes + * \ingroup logging + */ +class logger_config { +private: + /*! \brief filename of logger config file */ + std::string filename; + /*! \brief Period (seconds) over which watcher thread checks config file for changes */ + unsigned int watch_period; + /*! \brief Pointer to watch thread for config file changes */ + boost::thread *watch_thread; + + /*! \brief Watcher thread method + * /param filename Name of configuration file + * /param watch_period Seconds between checks for changes in config file + */ + static void watch_file(std::string filename,unsigned int watch_period); + + logger_config(){}; //!< Constructor + logger_config(logger_config const&); //!<Copy constructor + void operator=(logger_config const&); //!<Assignment Operator + + /*! \brief destrcutor stops watch thread before exits */ + ~logger_config(){ + stop_watch(); + }; + + /*! \brief Instance getter for singleton. Only used by class. */ + static logger_config& get_instance(void); + +public: + /*! \brief Getter for config filename */ + static std::string get_filename(); + /*! \brief Getter for watch period */ + static unsigned int get_watch_period(); + /*! \brief Method to load configuration + * /param filename Name of configuration file + * /param watch_period Seconds between checks for changes in config file + */ + static void load_config(std::string filename,unsigned int watch_period=0); + /*! \brief Method to stop watcher thread */ + static void stop_watch(); + /*! \brief method to reset logger configuration */ + static void reset_config(void); +}; + +/*! + * \brief Retrieve a pointer to a logger by name + * + * Retrives a logger pointer + * \p name. + * + * \param name Name of the logger for which a pointer is requested + */ +GR_RUNTIME_API gr_logger_ptr logger_get_logger(std::string name); + +/*! + * \brief Load logger's configuration file. + * + * Initialize the GNU Radio logger by loading the configuration file + * \p config_filename. + * + * \param config_filename The configuration file. Set to "" for the + * basic logger that outputs to the console. + */ +GR_RUNTIME_API void logger_load_config(const std::string &config_filename=""); + +/*! + * \brief Reset logger's configuration file. + * + * Remove all appenders from loggers + */ +GR_RUNTIME_API void logger_reset_config(void); + +GR_RUNTIME_API void logger_load_config_and_watch(const std::string &config_filename, + unsigned int watch_period); + + +/*! + * \brief Set the logger's output level. + * + * Sets the level of the logger. This takes a string that is + * translated to the standard levels and can be (case insensitive): + * + * \li off , notset + * \li debug + * \li info + * \li notice + * \li warn + * \li error + * \li crit + * \li alert + * \li fatal + * \li emerg + * + * \param logger the logger to set the level of. + * \param level string to set the level to. + */ +GR_RUNTIME_API void logger_set_level(gr_logger_ptr logger, const std::string &level); + +/*! + * \brief Set the logger's output level. + * + * Sets the level of the logger. This takes the actual Log4cpp::Priority + * data type, which can be: + * + * \li log4cpp::Priority::NOTSET + * \li log4cpp::Priority::DEBUG + * \li log4cpp::Priority::INFO + * \li log4cpp::Priority::NOTICE + * \li log4cpp::Priority::WARN + * \li log4cpp::Priority::ERROR + * \li log4cpp::Priority::CRIT + * \li log4cpp::Priority::ALERT + * \li log4cpp::Priority::FATAL + * \li log4cpp::Priority::EMERG + * + * \param logger the logger to set the level of. + * \param level new logger level of type Log4cpp::Priority + */ +GR_RUNTIME_API void logger_set_level(gr_logger_ptr logger, log4cpp::Priority::Value level); + + +/*! + * \brief Get the logger's output level. + * + * Gets the level of the logger. This returns a string that + * corresponds to the standard levels and can be (case insensitive): + * + * \li notset + * \li debug + * \li info + * \li notice + * \li warn + * \li error + * \li crit + * \li alert + * \li fatal + * \li emerg + * + * \param logger the logger to get the level of. + * \param level string to get the level into. + */ +GR_RUNTIME_API void logger_get_level(gr_logger_ptr logger, std::string &level); + +/*! + * \brief Get the logger's output level. + * + * Gets the level of the logger. This returns the actual Log4cpp::Level + * data type, which can be: + * + * \li log4cpp::Priority::NOTSET + * \li log4cpp::Priority::DEBUG + * \li log4cpp::Priority::INFO + * \li log4cpp::Priority::NOTICE + * \li log4cpp::Priority::WARN + * \li log4cpp::Priority::ERROR + * \li log4cpp::Priority::CRIT + * \li log4cpp::Priority::ALERT + * \li log4cpp::Priority::FATAL + * \li log4cpp::Priority::EMERG + * + * \param logger the logger to get the level of. + * \param level of the logger. + */ +GR_RUNTIME_API void logger_get_level(gr_logger_ptr logger, log4cpp::Priority::Value &level); + +/*! + * \brief Add console appender to a given logger + * + * Add console appender to a given logger + * + * \param logger Logger to which appender will be added + * \param target Std target to write 'cout' or 'cerr' (default is cout) + * \param pattern Formating pattern for log messages + */ +GR_RUNTIME_API void logger_add_console_appender(gr_logger_ptr logger,std::string target,std::string pattern); + +/*! + * \brief Add file appender to a given logger + * + * Add file appender to a given logger + * + * \param logger Logger to which appender will be added + * \param filename File to which log will be written + * \param append Overwrite or append to log file + * \param pattern Formating pattern for log messages + */ +GR_RUNTIME_API void logger_add_file_appender(gr_logger_ptr logger,std::string filename,bool append,std::string pattern); + +/*! + * \brief Add rolling file appender to a given logger + * + * Add rolling file appender to a given logger + * + * \param logger Logger to which appender will be added + * \param filename File to which log will be written + * \param filesize Sizez of files to write + * \param bkup_index Number of files to write + * \param append Overwrite or append to log file + * \param mode Permissions to set on log file + * \param pattern Formating pattern for log messages + */ +GR_RUNTIME_API void logger_add_rollingfile_appender(gr_logger_ptr logger,std::string filename, + size_t filesize,int bkup_index,bool append,mode_t mode,std::string pattern); + + +/*! + * \brief Add rolling file appender to a given logger + * + * Add rolling file appender to a given logger + * + * \return vector of string names of loggers + */ +GR_RUNTIME_API std::vector<std::string> logger_get_logger_names(void); + +#endif /* HAVE_LOG4CPP */ + + +// If Logger disable do nothing +#else /* ENABLE_GR_LOG */ + +typedef void* gr_logger_ptr; + +#define GR_LOG_DECLARE_LOGPTR(logger) +#define GR_LOG_ASSIGN_LOGPTR(logger,name) +#define GR_CONFIG_LOGGER(config) +#define GR_CONFIG_AND_WATCH_LOGGER(config,period) +#define GR_LOG_GETLOGGER(logger, name) +#define GR_SET_LEVEL(name, level) +#define GR_LOG_SET_LEVEL(logger, level) +#define GR_GET_LEVEL(name, level) +#define GR_LOG_GET_LEVEL(logger, level) +#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern) +#define GR_ADD_FILE_APPENDER(name,filename,append,pattern) +#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern) +#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern) +#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern) +#define GR_GET_LOGGER_NAMES(names) +#define GR_RESET_CONFIGURATION() +#define GR_DEBUG(name, msg) +#define GR_INFO(name, msg) +#define GR_NOTICE(name, msg) +#define GR_WARN(name, msg) +#define GR_ERROR(name, msg) +#define GR_ALERT(name, msg) +#define GR_CRIT(name, msg) +#define GR_FATAL(name, msg) +#define GR_EMERG(name, msg) +#define GR_ERRORIF(name, cond, msg) +#define GR_ASSERT(name, cond, msg) +#define GR_LOG_DEBUG(logger, msg) +#define GR_LOG_INFO(logger, msg) +#define GR_LOG_NOTICE(logger, msg) +#define GR_LOG_WARN(logger, msg) +#define GR_LOG_ERROR(logger, msg) +#define GR_LOG_ALERT(logger, msg) +#define GR_LOG_CRIT(logger, msg) +#define GR_LOG_FATAL(logger, msg) +#define GR_LOG_EMERG(logger, msg) +#define GR_LOG_ERRORIF(logger, cond, msg) +#define GR_LOG_ASSERT(logger, cond, msg) + +#endif /* ENABLE_GR_LOG */ + +// Even if logger is disabled we'll need for methods below to exist in python. +// The macros these call will be disabled if ENABLE_GR_LOG is undefined + +/********************* Start Classes and Methods for Python ******************/ +/*! + * \brief Logger class for referencing loggers in python. Not needed in C++ (use macros) + * Wraps and manipulates loggers for python as python has no macros + * \ingroup logging + * + */ +class gr_logger +{ + private: + /*! \brief logger pointer to logger associated wiith this wrapper class */ + gr_logger_ptr d_logger; + public: + /*! + * \brief contructor Provide name of logger to associate with this class + * \param logger_name Name of logger associated with class + */ + gr_logger(std::string logger_name) { + GR_LOG_ASSIGN_LOGPTR(d_logger,logger_name); + }; + + /*! \brief Destructor */ + ~gr_logger(){;}; + + // Wrappers for logging macros + /*! \brief inline function, wrapper to set the logger level */ + void set_level(std::string level){GR_LOG_SET_LEVEL(d_logger,level);} + + /*! \brief inline function, wrapper to get the logger level */ + void get_level(std::string &level){GR_LOG_GET_LEVEL(d_logger,level);} + + /*! \brief inline function, wrapper for LOG4CPP_DEBUG for DEBUG message */ + void debug(std::string msg){GR_LOG_DEBUG(d_logger,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_INFO for INFO message */ + void info(std::string msg){GR_LOG_INFO(d_logger,msg);}; + + /*! \brief inline function, wrapper for NOTICE message */ + void notice(std::string msg){GR_LOG_NOTICE(d_logger,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_WARN for WARN message */ + void warn(std::string msg){GR_LOG_WARN(d_logger,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_ERROR for ERROR message */ + void error(std::string msg){GR_LOG_ERROR(d_logger,msg);}; + + /*! \brief inline function, wrapper for NOTICE message */ + void crit(std::string msg){GR_LOG_CRIT(d_logger,msg);}; + + /*! \brief inline function, wrapper for ALERT message */ + void alert(std::string msg){GR_LOG_ALERT(d_logger,msg);}; + + /*! \brief inline function, wrapper for FATAL message */ + void fatal(std::string msg){GR_LOG_FATAL(d_logger,msg);}; + + /*! \brief inline function, wrapper for EMERG message */ + void emerg(std::string msg){GR_LOG_EMERG(d_logger,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ + void errorIF(bool cond,std::string msg){GR_LOG_ERRORIF(d_logger,cond,msg);}; + + /*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */ + void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);}; + + /*! \brief inline function, Method to add console appender to logger */ + void add_console_appender(std::string target,std::string pattern){ + GR_LOG_ADD_CONSOLE_APPENDER(d_logger,target,pattern); + }; + + /*! \brief inline function, Method to add file appender to logger */ + void add_file_appender(std::string filename,bool append,std::string pattern){ + GR_LOG_ADD_FILE_APPENDER(d_logger,filename,append,pattern); + }; + + /*! \brief inline function, Method to add rolling file appender to logger */ + void add_rollingfile_appender(std::string filename,size_t filesize, + int bkup_index,bool append,mode_t mode,std::string pattern){ + GR_LOG_ADD_ROLLINGFILE_APPENDER(d_logger,filename,filesize, + bkup_index,append,mode,pattern); + }; +}; + +/**************** Start Configuration Class and Methods for Python ************/ +/*! + * \brief Function to call configuration macro from python. + * Note: Configuration is only updated if filename or watch_period has changed. + * \param config_filename Name of configuration file + * \param watch_period Seconds to wait between checking for changes in conf file. + * Watch_period defaults to 0 in which case the file is not watched for changes + */ +GR_RUNTIME_API void gr_logger_config(const std::string config_filename, unsigned int watch_period = 0); +/*! + * \brief Function to return logger names to python + * \return Vector of name strings + * + */ +GR_RUNTIME_API std::vector<std::string> gr_logger_get_logger_names(void); +/*! + * \brief Function to reset logger configuration from python + * + */ +GR_RUNTIME_API void gr_logger_reset_config(void); + +#endif /* INCLUDED_GR_LOGGER_H */ diff --git a/gnuradio-runtime/include/gr_math.h b/gnuradio-runtime/include/gr_math.h new file mode 100644 index 0000000000..c7efe8facb --- /dev/null +++ b/gnuradio-runtime/include/gr_math.h @@ -0,0 +1,209 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003,2005,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* + * mathematical odds and ends. + */ + +#ifndef _GR_MATH_H_ +#define _GR_MATH_H_ + +#include <gr_runtime_api.h> +#include <gr_complex.h> + +static inline bool +gr_is_power_of_2(long x) +{ + return x != 0 && (x & (x-1)) == 0; +} + +/*! + * \brief Fast arc tangent using table lookup and linear interpolation + * \ingroup misc + * + * \param y component of input vector + * \param x component of input vector + * \returns float angle angle of vector (x, y) in radians + * + * This function calculates the angle of the vector (x,y) based on a + * table lookup and linear interpolation. The table uses a 256 point + * table covering -45 to +45 degrees and uses symetry to determine the + * final angle value in the range of -180 to 180 degrees. Note that + * this function uses the small angle approximation for values close + * to zero. This routine calculates the arc tangent with an average + * error of +/- 0.045 degrees. + */ +GR_RUNTIME_API float gr_fast_atan2f(float y, float x); + +static inline float gr_fast_atan2f(gr_complex z) +{ + return gr_fast_atan2f(z.imag(), z.real()); +} + +/* This bounds x by +/- clip without a branch */ +static inline float gr_branchless_clip(float x, float clip) +{ + float x1 = fabsf(x+clip); + float x2 = fabsf(x-clip); + x1 -= x2; + return 0.5*x1; +} + +static inline float gr_clip(float x, float clip) +{ + float y = x; + if(x > clip) + y = clip; + else if(x < -clip) + y = -clip; + return y; +} + +// Slicer Functions +static inline unsigned int gr_binary_slicer(float x) +{ + if(x >= 0) + return 1; + else + return 0; +} + +static inline unsigned int gr_quad_45deg_slicer(float r, float i) +{ + unsigned int ret = 0; + if((r >= 0) && (i >= 0)) + ret = 0; + else if((r < 0) && (i >= 0)) + ret = 1; + else if((r < 0) && (i < 0)) + ret = 2; + else + ret = 3; + return ret; +} + +static inline unsigned int gr_quad_0deg_slicer(float r, float i) +{ + unsigned int ret = 0; + if(fabsf(r) > fabsf(i)) { + if(r > 0) + ret = 0; + else + ret = 2; + } + else { + if(i > 0) + ret = 1; + else + ret = 3; + } + + return ret; +} + +static inline unsigned int gr_quad_45deg_slicer(gr_complex x) +{ + return gr_quad_45deg_slicer(x.real(), x.imag()); +} + +static inline unsigned int gr_quad_0deg_slicer(gr_complex x) +{ + return gr_quad_0deg_slicer(x.real(), x.imag()); +} + +// Branchless Slicer Functions +static inline unsigned int gr_branchless_binary_slicer(float x) +{ + return (x >= 0); +} + +static inline unsigned int gr_branchless_quad_0deg_slicer(float r, float i) +{ + unsigned int ret = 0; + ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10) + ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11) + + return ret; +} + +static inline unsigned int gr_branchless_quad_0deg_slicer(gr_complex x) +{ + return gr_branchless_quad_0deg_slicer(x.real(), x.imag()); +} + +static inline unsigned int gr_branchless_quad_45deg_slicer(float r, float i) +{ + char ret = (r <= 0); + ret |= ((i <= 0) << 1); + return (ret ^ ((ret & 0x2) >> 0x1)); +} + +static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x) +{ + return gr_branchless_quad_45deg_slicer(x.real(), x.imag()); +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded down to a multiple of \p pow2. + */ +static inline size_t +gr_p2_round_down(size_t x, size_t pow2) +{ + return x & -pow2; +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded up to a multiple of \p pow2. + */ +static inline size_t +gr_p2_round_up(size_t x, size_t pow2) +{ + return gr_p2_round_down(x + pow2 - 1, pow2); +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x modulo \p pow2. + */ +static inline size_t +gr_p2_modulo(size_t x, size_t pow2) +{ + return x & (pow2 - 1); +} + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p pow2 - (\p x modulo \p pow2). + */ +static inline size_t +gr_p2_modulo_neg(size_t x, size_t pow2) +{ + return pow2 - gr_p2_modulo(x, pow2); +} + +#endif /* _GR_MATH_H_ */ diff --git a/gnuradio-runtime/include/gr_message.h b/gnuradio-runtime/include/gr_message.h new file mode 100644 index 0000000000..941821617b --- /dev/null +++ b/gnuradio-runtime/include/gr_message.h @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_MESSAGE_H +#define INCLUDED_GR_MESSAGE_H + +#include <gr_runtime_api.h> +#include <gr_types.h> +#include <string> + +class gr_message; +typedef boost::shared_ptr<gr_message> gr_message_sptr; + +/*! + * \brief public constructor for gr_message + */ +GR_RUNTIME_API gr_message_sptr +gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0); + +GR_RUNTIME_API gr_message_sptr +gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0); + +/*! + * \brief Message class. + * + * \ingroup misc + * The ideas and method names for adjustable message length were + * lifted from the click modular router "Packet" class. + */ +class GR_RUNTIME_API gr_message { + gr_message_sptr d_next; // link field for msg queue + long d_type; // type of the message + double d_arg1; // optional arg1 + double d_arg2; // optional arg2 + + unsigned char *d_buf_start; // start of allocated buffer + unsigned char *d_msg_start; // where the msg starts + unsigned char *d_msg_end; // one beyond end of msg + unsigned char *d_buf_end; // one beyond end of allocated buffer + + gr_message (long type, double arg1, double arg2, size_t length); + + friend GR_RUNTIME_API gr_message_sptr + gr_make_message (long type, double arg1, double arg2, size_t length); + + friend GR_RUNTIME_API gr_message_sptr + gr_make_message_from_string (const std::string s, long type, double arg1, double arg2); + + friend class gr_msg_queue; + + unsigned char *buf_data() const { return d_buf_start; } + size_t buf_len() const { return d_buf_end - d_buf_start; } + +public: + ~gr_message (); + + long type() const { return d_type; } + double arg1() const { return d_arg1; } + double arg2() const { return d_arg2; } + + void set_type(long type) { d_type = type; } + void set_arg1(double arg1) { d_arg1 = arg1; } + void set_arg2(double arg2) { d_arg2 = arg2; } + + unsigned char *msg() const { return d_msg_start; } + size_t length() const { return d_msg_end - d_msg_start; } + std::string to_string() const; + +}; + +GR_RUNTIME_API long gr_message_ncurrently_allocated (); + +#endif /* INCLUDED_GR_MESSAGE_H */ diff --git a/gnuradio-runtime/include/gr_misc.h b/gnuradio-runtime/include/gr_misc.h new file mode 100644 index 0000000000..182ae87de6 --- /dev/null +++ b/gnuradio-runtime/include/gr_misc.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_MISC_H +#define INCLUDED_GR_MISC_H + +#include <gr_runtime_api.h> +#include <gr_types.h> + +GR_RUNTIME_API unsigned int +gr_rounduppow2(unsigned int n); + +// FIXME should be template +GR_RUNTIME_API void gr_zero_vector(std::vector<float> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<double> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<int> &v); +GR_RUNTIME_API void gr_zero_vector(std::vector<gr_complex> &v); + + +#endif /* INCLUDED_GR_MISC_H */ diff --git a/gnuradio-runtime/include/gr_msg_accepter.h b/gnuradio-runtime/include/gr_msg_accepter.h new file mode 100644 index 0000000000..e7feac4686 --- /dev/null +++ b/gnuradio-runtime/include/gr_msg_accepter.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_MSG_ACCEPTER_H +#define INCLUDED_GR_MSG_ACCEPTER_H + +#include <gr_runtime_api.h> +#include <messages/msg_accepter.h> +#include <pmt/pmt.h> + +/*! + * \brief Accepts messages and inserts them into a message queue, then notifies + * subclass gr_basic_block there is a message pending. + */ +class GR_RUNTIME_API gr_msg_accepter : public gr::messages::msg_accepter +{ +public: + gr_msg_accepter(); + ~gr_msg_accepter(); + + void post(pmt::pmt_t which_port, pmt::pmt_t msg); + +}; + +#endif /* INCLUDED_GR_MSG_ACCEPTER_H */ diff --git a/gnuradio-runtime/include/gr_msg_handler.h b/gnuradio-runtime/include/gr_msg_handler.h new file mode 100644 index 0000000000..06d583a38b --- /dev/null +++ b/gnuradio-runtime/include/gr_msg_handler.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_MSG_HANDLER_H +#define INCLUDED_GR_MSG_HANDLER_H + +#include <gr_runtime_api.h> +#include <gr_message.h> + +class gr_msg_handler; +typedef boost::shared_ptr<gr_msg_handler> gr_msg_handler_sptr; + +/*! + * \brief abstract class of message handlers + * \ingroup base + */ +class GR_RUNTIME_API gr_msg_handler { +public: + virtual ~gr_msg_handler (); + + //! handle \p msg + virtual void handle (gr_message_sptr msg) = 0; +}; + +#endif /* INCLUDED_GR_MSG_HANDLER_H */ diff --git a/gnuradio-runtime/include/gr_msg_queue.h b/gnuradio-runtime/include/gr_msg_queue.h new file mode 100644 index 0000000000..ac85729c81 --- /dev/null +++ b/gnuradio-runtime/include/gr_msg_queue.h @@ -0,0 +1,92 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_MSG_QUEUE_H +#define INCLUDED_GR_MSG_QUEUE_H + +#include <gr_runtime_api.h> +#include <gr_msg_handler.h> +#include <thread/thread.h> + +class gr_msg_queue; +typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr; + +GR_RUNTIME_API gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0); + +/*! + * \brief thread-safe message queue + * \ingroup misc + */ +class GR_RUNTIME_API gr_msg_queue : public gr_msg_handler { + + gr::thread::mutex d_mutex; + gr::thread::condition_variable d_not_empty; + gr::thread::condition_variable d_not_full; + gr_message_sptr d_head; + gr_message_sptr d_tail; + unsigned int d_count; // # of messages in queue. + unsigned int d_limit; // max # of messages in queue. 0 -> unbounded + +public: + gr_msg_queue(unsigned int limit); + ~gr_msg_queue(); + + //! Generic msg_handler method: insert the message. + void handle(gr_message_sptr msg) { insert_tail (msg); } + + /*! + * \brief Insert message at tail of queue. + * \param msg message + * + * Block if queue if full. + */ + void insert_tail(gr_message_sptr msg); + + /*! + * \brief Delete message from head of queue and return it. + * Block if no message is available. + */ + gr_message_sptr delete_head(); + + /*! + * \brief If there's a message in the q, delete it and return it. + * If no message is available, return 0. + */ + gr_message_sptr delete_head_nowait(); + + //! Delete all messages from the queue + void flush(); + + //! is the queue empty? + bool empty_p() const { return d_count == 0; } + + //! is the queue full? + bool full_p() const { return d_limit != 0 && d_count >= d_limit; } + + //! return number of messages in queue + unsigned int count() const { return d_count; } + + //! return limit on number of message in queue. 0 -> unbounded + unsigned int limit() const { return d_limit; } + +}; + +#endif /* INCLUDED_GR_MSG_QUEUE_H */ diff --git a/gnuradio-runtime/include/gr_nco.h b/gnuradio-runtime/include/gr_nco.h new file mode 100644 index 0000000000..fb51106aab --- /dev/null +++ b/gnuradio-runtime/include/gr_nco.h @@ -0,0 +1,198 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef _GR_NCO_H_ +#define _GR_NCO_H_ + + +#include <vector> +#include <gr_sincos.h> +#include <cmath> +#include <gr_complex.h> + +/*! + * \brief base class template for Numerically Controlled Oscillator (NCO) + * \ingroup misc + */ + + +//FIXME Eventually generalize this to fixed point + +template<class o_type, class i_type> +class gr_nco { +public: + gr_nco () : phase (0), phase_inc(0) {} + + virtual ~gr_nco () {} + + // radians + void set_phase (double angle) { + phase = angle; + } + + void adjust_phase (double delta_phase) { + phase += delta_phase; + } + + + // angle_rate is in radians / step + void set_freq (double angle_rate){ + phase_inc = angle_rate; + } + + // angle_rate is a delta in radians / step + void adjust_freq (double delta_angle_rate) + { + phase_inc += delta_angle_rate; + } + + // increment current phase angle + + void step () + { + phase += phase_inc; + if (fabs (phase) > M_PI){ + + while (phase > M_PI) + phase -= 2*M_PI; + + while (phase < -M_PI) + phase += 2*M_PI; + } + } + + void step (int n) + { + phase += phase_inc * n; + if (fabs (phase) > M_PI){ + + while (phase > M_PI) + phase -= 2*M_PI; + + while (phase < -M_PI) + phase += 2*M_PI; + } + } + + // units are radians / step + double get_phase () const { return phase; } + double get_freq () const { return phase_inc; } + + // compute sin and cos for current phase angle + void sincos (float *sinx, float *cosx) const; + + // compute cos or sin for current phase angle + float cos () const { return std::cos (phase); } + float sin () const { return std::sin (phase); } + + // compute a block at a time + void sin (float *output, int noutput_items, double ampl = 1.0); + void cos (float *output, int noutput_items, double ampl = 1.0); + void sincos (gr_complex *output, int noutput_items, double ampl = 1.0); + void sin (short *output, int noutput_items, double ampl = 1.0); + void cos (short *output, int noutput_items, double ampl = 1.0); + void sin (int *output, int noutput_items, double ampl = 1.0); + void cos (int *output, int noutput_items, double ampl = 1.0); + +protected: + double phase; + double phase_inc; +}; + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::sincos (float *sinx, float *cosx) const +{ + gr_sincosf (phase, sinx, cosx); +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::sin (float *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (float)(sin () * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::cos (float *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (float)(cos () * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::sin (short *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (short)(sin() * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::cos (short *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (short)(cos () * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::sin (int *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (int)(sin () * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::cos (int *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + output[i] = (int)(cos () * ampl); + step (); + } +} + +template<class o_type, class i_type> +void +gr_nco<o_type,i_type>::sincos (gr_complex *output, int noutput_items, double ampl) +{ + for (int i = 0; i < noutput_items; i++){ + float cosx, sinx; + sincos (&sinx, &cosx); + output[i] = gr_complex(cosx * ampl, sinx * ampl); + step (); + } +} +#endif /* _NCO_H_ */ diff --git a/gnuradio-runtime/include/gr_preferences.h b/gnuradio-runtime/include/gr_preferences.h new file mode 100644 index 0000000000..df5aecacba --- /dev/null +++ b/gnuradio-runtime/include/gr_preferences.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GR_PREFERENCES_H_ +#define _GR_PREFERENCES_H_ + +#include <gr_runtime_api.h> + +class GR_RUNTIME_API gr_preferences { + public: + static const char *get (const char *key); + static void set (const char *key, const char *value); +}; + +#endif /* _GR_PREFERENCES_H_ */
\ No newline at end of file diff --git a/gnuradio-runtime/include/gr_prefs.h b/gnuradio-runtime/include/gr_prefs.h new file mode 100644 index 0000000000..0f82c46fae --- /dev/null +++ b/gnuradio-runtime/include/gr_prefs.h @@ -0,0 +1,143 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_PREFS_H +#define INCLUDED_GR_PREFS_H + +#include <gr_runtime_api.h> +#include <string> +#include <map> +#include <thread/thread.h> + +typedef std::map< std::string, std::map<std::string, std::string> > gr_config_map_t; +typedef std::map< std::string, std::map<std::string, std::string> >::iterator gr_config_map_itr; +typedef std::map<std::string, std::string> gr_config_map_elem_t; +typedef std::map<std::string, std::string>::iterator gr_config_map_elem_itr; + +/*! + * \brief Base class for representing user preferences a la windows INI files. + * \ingroup misc + * + * The real implementation is in Python, and is accessable from C++ + * via the magic of SWIG directors. + */ + +class GR_RUNTIME_API gr_prefs +{ +public: + static gr_prefs *singleton(); + static void set_singleton(gr_prefs *p); + + gr_prefs(); + virtual ~gr_prefs(); + + /*! + * \brief Returns the configuration options as a string. + */ + std::string to_string(); + + /*! + * \brief Saves the configuration settings to ${HOME}/.gnuradio/config.conf. + * + * WARNING: this will overwrite your current config.conf file. + */ + void save(); + + /*! + * \brief Does \p section exist? + */ + virtual bool has_section(const std::string §ion); + + /*! + * \brief Does \p option exist? + */ + virtual bool has_option(const std::string §ion, const std::string &option); + + /*! + * \brief If option exists return associated value; else default_val. + */ + virtual const std::string get_string(const std::string §ion, + const std::string &option, + const std::string &default_val); + + /*! + * \brief Set or add a string \p option to \p section with value \p val. + */ + virtual void set_string(const std::string §ion, + const std::string &option, + const std::string &val); + + /*! + * \brief If option exists and value can be converted to bool, return it; else default_val. + */ + virtual bool get_bool(const std::string §ion, + const std::string &option, + bool default_val); + + /*! + * \brief Set or add a bool \p option to \p section with value \p val. + */ + virtual void set_bool(const std::string §ion, + const std::string &option, + bool val); + + /*! + * \brief If option exists and value can be converted to long, return it; else default_val. + */ + virtual long get_long(const std::string §ion, + const std::string &option, + long default_val); + + /*! + * \brief Set or add a long \p option to \p section with value \p val. + */ + virtual void set_long(const std::string §ion, + const std::string &option, + long val); + + /*! + * \brief If option exists and value can be converted to double, return it; else default_val. + */ + virtual double get_double(const std::string §ion, + const std::string &option, + double default_val); + + /*! + * \brief Set or add a double \p option to \p section with value \p val. + */ + virtual void set_double(const std::string §ion, + const std::string &option, + double val); + + protected: + virtual std::vector<std::string> _sys_prefs_filenames(); + virtual void _read_files(); + virtual void _convert_to_map(const std::string &conf); + virtual char * option_to_env(std::string section, std::string option); + + private: + gr::thread::mutex d_mutex; + gr_config_map_t d_config_map; +}; + + +#endif /* INCLUDED_GR_PREFS_H */ diff --git a/gnuradio-runtime/include/gr_py_feval.h b/gnuradio-runtime/include/gr_py_feval.h new file mode 100644 index 0000000000..f2f6c801a8 --- /dev/null +++ b/gnuradio-runtime/include/gr_py_feval.h @@ -0,0 +1,51 @@ +#include <pmt/pmt.h> + +class gr_py_feval_dd : public gr_feval_dd +{ + public: + double calleval(double x) + { + ensure_py_gil_state _lock; + return eval(x); + } +}; + +class gr_py_feval_cc : public gr_feval_cc +{ + public: + gr_complex calleval(gr_complex x) + { + ensure_py_gil_state _lock; + return eval(x); + } +}; + +class gr_py_feval_ll : public gr_feval_ll +{ + public: + long calleval(long x) + { + ensure_py_gil_state _lock; + return eval(x); + } +}; + +class gr_py_feval : public gr_feval +{ + public: + void calleval() + { + ensure_py_gil_state _lock; + eval(); + } +}; + +class gr_py_feval_p : public gr_feval_p +{ + public: + void calleval(pmt::pmt_t x) + { + ensure_py_gil_state _lock; + eval(x); + } +}; diff --git a/gnuradio-runtime/include/gr_random.h b/gnuradio-runtime/include/gr_random.h new file mode 100644 index 0000000000..783c05f920 --- /dev/null +++ b/gnuradio-runtime/include/gr_random.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RANDOM_H +#define INCLUDED_GR_RANDOM_H + +#include <gr_runtime_api.h> +#include <gr_complex.h> + +/*! + * \brief pseudo random number generator + * \ingroup math_blk + */ +class GR_RUNTIME_API gr_random { +protected: + static const int NTAB = 32; + long d_seed; + long d_iy; + long d_iv[NTAB]; + int d_iset; + float d_gset; + + +public: + gr_random (long seed=3021); + + void reseed (long seed); + + /*! + * \brief uniform random deviate in the range [0.0, 1.0) + */ + float ran1 (); + + /*! + * \brief normally distributed deviate with zero mean and variance 1 + */ + float gasdev (); + + float laplacian (); + float impulse (float factor); + float rayleigh (); + gr_complex rayleigh_complex (); +}; + +#endif /* INCLUDED_GR_RANDOM_H */ + diff --git a/gnuradio-runtime/include/gr_realtime.h b/gnuradio-runtime/include/gr_realtime.h new file mode 100644 index 0000000000..a1e5af69c4 --- /dev/null +++ b/gnuradio-runtime/include/gr_realtime.h @@ -0,0 +1,37 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_REALTIME_H +#define INCLUDED_GR_REALTIME_H + +#include <gr_runtime_api.h> +#include <realtime.h> + +typedef gr::rt_status_t gr_rt_status_t; + +/*! + * \brief If possible, enable high-priority "real time" scheduling. + * \ingroup misc + */ +GR_RUNTIME_API gr_rt_status_t gr_enable_realtime_scheduling(); + +#endif /* INCLUDED_GR_REALTIME_H */ diff --git a/gnuradio-runtime/include/gr_runtime_api.h b/gnuradio-runtime/include/gr_runtime_api.h new file mode 100644 index 0000000000..f4e1a4ea5b --- /dev/null +++ b/gnuradio-runtime/include/gr_runtime_api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_API_H +#define INCLUDED_GR_RUNTIME_API_H + +#include <attributes.h> + +#ifdef gnuradio_core_EXPORTS +# define GR_RUNTIME_API __GR_ATTR_EXPORT +#else +# define GR_RUNTIME_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_GR_RUNTIME_API_H */ diff --git a/gnuradio-runtime/include/gr_runtime_types.h b/gnuradio-runtime/include/gr_runtime_types.h new file mode 100644 index 0000000000..9af745b3fa --- /dev/null +++ b/gnuradio-runtime/include/gr_runtime_types.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_RUNTIME_TYPES_H +#define INCLUDED_GR_RUNTIME_TYPES_H + +#include <gr_runtime_api.h> +#include <gr_types.h> + +/* + * typedefs for smart pointers we use throughout the runtime system + */ + +class gr_basic_block; +class gr_block; +class gr_block_detail; +class gr_hier_block2; +class gr_io_signature; +class gr_buffer; +class gr_buffer_reader; +class gr_flowgraph; +class gr_flat_flowgraph; +class gr_top_block; +class gr_top_block_detail; + +typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr; +typedef boost::shared_ptr<gr_block> gr_block_sptr; +typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr; +typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr; +typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr; +typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr; +typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr; +typedef boost::shared_ptr<gr_flowgraph> gr_flowgraph_sptr; +typedef boost::shared_ptr<gr_flat_flowgraph> gr_flat_flowgraph_sptr; +typedef boost::shared_ptr<gr_top_block> gr_top_block_sptr; + +#endif /* INCLUDED_GR_RUNTIME_TYPES_H */ diff --git a/gnuradio-runtime/include/gr_select_handler.h b/gnuradio-runtime/include/gr_select_handler.h new file mode 100644 index 0000000000..ae4b9dfdb1 --- /dev/null +++ b/gnuradio-runtime/include/gr_select_handler.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SELECT_HANDLER_H +#define INCLUDED_GR_SELECT_HANDLER_H + +#include <gr_runtime_api.h> +#include <boost/shared_ptr.hpp> + +class gr_select_handler; +typedef boost::shared_ptr<gr_select_handler> gr_select_handler_sptr; + + +/*! + * \brief Abstract handler for select based notification. + * \ingroup base + * + * \sa gr_dispatcher + */ +class GR_RUNTIME_API gr_select_handler +{ + int d_fd; + +protected: + gr_select_handler(int file_descriptor); + +public: + virtual ~gr_select_handler(); + + int fd() const { return d_fd; } + int file_descriptor() const { return d_fd; } + + /*! + * \brief Called when file_descriptor is readable. + * + * Called when the dispatcher detects that file_descriptor can + * be read without blocking. + */ + virtual void handle_read() = 0; + + /*! + * \brief Called when file_descriptor is writable. + * + * Called when dispatcher detects that file descriptor can be + * written without blocking. + */ + virtual void handle_write() = 0; + + /*! + * Called each time around the dispatcher loop to determine whether + * this handler's file descriptor should be added to the list on which + * read events can occur. The default method returns true, indicating + * that by default, all handlers are interested in read events. + */ + virtual bool readable() { return true; } + + /*! + * Called each time around the dispatcher loop to determine whether + * this handler's file descriptor should be added to the list on which + * write events can occur. The default method returns true, indicating + * that by default, all handlers are interested in write events. + */ + virtual bool writable() { return true; } +}; + +#endif /* INCLUDED_GR_SELECT_HANDLER_H */ diff --git a/gnuradio-runtime/include/gr_sincos.h b/gnuradio-runtime/include/gr_sincos.h new file mode 100644 index 0000000000..5a182081de --- /dev/null +++ b/gnuradio-runtime/include/gr_sincos.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SINCOS_H +#define INCLUDED_GR_SINCOS_H + +#include <gr_runtime_api.h> + +#ifdef __cplusplus +extern "C" { +#endif + +// compute sine and cosine at the same time + +GR_RUNTIME_API void gr_sincos (double x, double *sin, double *cos); +GR_RUNTIME_API void gr_sincosf (float x, float *sin, float *cos); + +#ifdef __cplusplus +}; +#endif + +#endif /* INCLUDED_GR_SINCOS_H */ diff --git a/gnuradio-runtime/include/gr_single_threaded_scheduler.h b/gnuradio-runtime/include/gr_single_threaded_scheduler.h new file mode 100644 index 0000000000..d538fa3921 --- /dev/null +++ b/gnuradio-runtime/include/gr_single_threaded_scheduler.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H +#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H + +#include <gr_runtime_api.h> +#include <gr_runtime_types.h> +#include <fstream> + +class gr_single_threaded_scheduler; +typedef boost::shared_ptr<gr_single_threaded_scheduler> gr_single_threaded_scheduler_sptr; + + +/*! + * \brief Simple scheduler for stream computations. + * \ingroup internal + */ + +class GR_RUNTIME_API gr_single_threaded_scheduler { + public: + ~gr_single_threaded_scheduler (); + + void run (); + void stop (); + + private: + const std::vector<gr_block_sptr> d_blocks; + volatile bool d_enabled; + std::ofstream *d_log; + + gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks); + + void main_loop (); + + friend GR_RUNTIME_API gr_single_threaded_scheduler_sptr + gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks); +}; + +GR_RUNTIME_API gr_single_threaded_scheduler_sptr +gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks); + +#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */ diff --git a/gnuradio-runtime/include/gr_sptr_magic.h b/gnuradio-runtime/include/gr_sptr_magic.h new file mode 100644 index 0000000000..2a94806d18 --- /dev/null +++ b/gnuradio-runtime/include/gr_sptr_magic.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_SPTR_MAGIC_H +#define INCLUDED_GR_SPTR_MAGIC_H + +#include <gr_runtime_api.h> +#include <boost/shared_ptr.hpp> + +class gr_basic_block; +class gr_hier_block2; + +namespace gnuradio { + + namespace detail { + + class GR_RUNTIME_API sptr_magic { + public: + static boost::shared_ptr<gr_basic_block> fetch_initial_sptr(gr_basic_block *p); + static void create_and_stash_initial_sptr(gr_hier_block2 *p); + }; + }; + + /* + * \brief New! Improved! Standard method to get/create the boost::shared_ptr for a block. + */ + template<class T> + boost::shared_ptr<T> + get_initial_sptr(T *p) + { + return boost::dynamic_pointer_cast<T, gr_basic_block>(detail::sptr_magic::fetch_initial_sptr(p)); + } +}; + +#endif /* INCLUDED_GR_SPTR_MAGIC_H */ diff --git a/gnuradio-runtime/include/gr_sync_block.h b/gnuradio-runtime/include/gr_sync_block.h new file mode 100644 index 0000000000..01eb646143 --- /dev/null +++ b/gnuradio-runtime/include/gr_sync_block.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SYNC_BLOCK_H +#define INCLUDED_GR_SYNC_BLOCK_H + +#include <gr_runtime_api.h> +#include <gr_block.h> + +/*! + * \brief synchronous 1:1 input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ +class GR_RUNTIME_API gr_sync_block : public gr_block +{ + protected: + gr_sync_block (void){} //allows pure virtual interface sub-classes + gr_sync_block (const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature); + + public: + + /*! + * \brief just like gr_block::general_work, only this arranges to call consume_each for you + * + * The user must override work to define the signal processing code + */ + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) = 0; + + + // gr_sync_block overrides these to assist work + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); +}; + +#endif /* INCLUDED_GR_SYNC_BLOCK_H */ diff --git a/gnuradio-runtime/include/gr_sync_decimator.h b/gnuradio-runtime/include/gr_sync_decimator.h new file mode 100644 index 0000000000..c799ee0f7c --- /dev/null +++ b/gnuradio-runtime/include/gr_sync_decimator.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SYNC_DECIMATOR_H +#define INCLUDED_GR_SYNC_DECIMATOR_H + +#include <gr_runtime_api.h> +#include <gr_sync_block.h> + +/*! + * \brief synchronous N:1 input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ +class GR_RUNTIME_API gr_sync_decimator : public gr_sync_block +{ + private: + unsigned d_decimation; + + protected: + gr_sync_decimator (void){} //allows pure virtual interface sub-classes + gr_sync_decimator (const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature, + unsigned decimation); + public: + + unsigned decimation () const { return d_decimation; } + void set_decimation (unsigned decimation) + { + d_decimation = decimation; + set_relative_rate (1.0 / decimation); + } + + // gr_sync_decimator overrides these to assist work + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + // derived classes should override work + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); +}; + + +#endif /* INCLUDED_GR_SYNC_DECIMATOR_H */ diff --git a/gnuradio-runtime/include/gr_sync_interpolator.h b/gnuradio-runtime/include/gr_sync_interpolator.h new file mode 100644 index 0000000000..f219916743 --- /dev/null +++ b/gnuradio-runtime/include/gr_sync_interpolator.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_SYNC_INTERPOLATOR_H +#define INCLUDED_GR_SYNC_INTERPOLATOR_H + +#include <gr_runtime_api.h> +#include <gr_sync_block.h> + +/*! + * \brief synchronous 1:N input to output with history + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ +class GR_RUNTIME_API gr_sync_interpolator : public gr_sync_block +{ + private: + unsigned d_interpolation; + + protected: + gr_sync_interpolator (void){} //allows pure virtual interface sub-classes + gr_sync_interpolator (const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature, + unsigned interpolation); + public: + + unsigned interpolation () const { return d_interpolation; } + void set_interpolation (unsigned interpolation) + { + d_interpolation = interpolation; + set_relative_rate (1.0 * interpolation); + set_output_multiple (interpolation); + } + + // gr_sync_interpolator overrides these to assist work + void forecast (int noutput_items, gr_vector_int &ninput_items_required); + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + // derived classes should override work + + int fixed_rate_ninput_to_noutput(int ninput); + int fixed_rate_noutput_to_ninput(int noutput); +}; + + +#endif /* INCLUDED_GR_SYNC_INTERPOLATOR_H */ diff --git a/gnuradio-runtime/include/gr_sys_paths.h b/gnuradio-runtime/include/gr_sys_paths.h new file mode 100644 index 0000000000..6235e0e78f --- /dev/null +++ b/gnuradio-runtime/include/gr_sys_paths.h @@ -0,0 +1,33 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _GR_SYS_PATHS_H_ +#define _GR_SYS_PATHS_H_ + +#include <gr_runtime_api.h> + +//! directory to create temporary files +GR_RUNTIME_API const char *gr_tmp_path(); + +//! directory to store application data +GR_RUNTIME_API const char *gr_appdata_path(); + +#endif /* _GR_SYS_PATHS_H_ */ diff --git a/gnuradio-runtime/include/gr_tagged_stream_block.h b/gnuradio-runtime/include/gr_tagged_stream_block.h new file mode 100644 index 0000000000..67b144fb66 --- /dev/null +++ b/gnuradio-runtime/include/gr_tagged_stream_block.h @@ -0,0 +1,142 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TAGGED_STREAM_BLOCK_H +#define INCLUDED_GR_TAGGED_STREAM_BLOCK_H + +#include <gr_runtime_api.h> +#include <gr_block.h> + +/*! + * \brief Block that operates on PDUs in form of tagged streams + * \ingroup base_blk + * + * Override work to provide the signal processing implementation. + */ +class GR_RUNTIME_API gr_tagged_stream_block : public gr_block +{ + private: + pmt::pmt_t d_length_tag_key; //!< This is the key for the tag that stores the PDU length + gr_vector_int d_n_input_items_reqd; //!< How many input items do I need to process the next PDU? + + protected: + std::string d_length_tag_key_str; + gr_tagged_stream_block (void){} //allows pure virtual interface sub-classes + gr_tagged_stream_block (const std::string &name, + gr_io_signature_sptr input_signature, + gr_io_signature_sptr output_signature, + const std::string &length_tag_key); + + /*! + * \brief Parse all tags on the first sample of a PDU, return the number of items per input + * and prune the length tags. + * + * In most cases, you don't need to override this, unless the number of items read + * is not directly coded in one single tag. + * + * Default behaviour: + * - Go through all input ports + * - On every input port, search for the tag with the key specified in \p length_tag_key + * - Copy that value as an int to the corresponding position in \p n_input_items_reqd + * - Remove the length tag. + * + * \param[in] tags All the tags found on the first item of every input port. + * \param[out] n_input_items_reqd Number of items which will be read from every input + */ + virtual void parse_length_tags( + const std::vector<std::vector<gr_tag_t> > &tags, + gr_vector_int &n_input_items_reqd + ); + + /*! + * \brief Calculate the number of output items. + * + * This is basically the inverse function to forecast(): Given a number of input + * items, it returns the maximum number of output items. + * + * You most likely need to override this function, unless your block is a sync + * block or integer interpolator/decimator. + * + */ + virtual int calculate_output_stream_length(const gr_vector_int &ninput_items); + + /*! + * \brief Set the new length tags on the output stream + * + * Default behaviour: Set a tag with key \p length_tag_key and + * the number of produced items on every output port. + * + * For anything else, override this. + * + * \param n_produced Length of the new PDU + * \param n_ports Number of output ports + */ + virtual void update_length_tags(int n_produced, int n_ports); + + public: + + /*! \brief Don't override this. + */ + void /* final */ forecast (int noutput_items, gr_vector_int &ninput_items_required); + + /*! + * - Reads the number of input items from the tags using parse_length_tags() + * - Checks there's enough data on the input and output buffers + * - If not, inform the scheduler and do nothing + * - Calls work() with the exact number of items per PDU + * - Updates the tags using update_length_tags() + */ + int general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + /*! + * \brief Just like gr_block::general_work, but makes sure the input is valid + * + * The user must override work to define the signal processing code. + * Check the documentation for general_work() to see what happens here. + * + * Like gr_sync_block, this calls consume() for you (it consumes ninput_items[i] + * items from the i-th port). + * + * A note on tag propagation: The PDU length tags are handled by other functions, + * but all other tags are handled just as in any other \p gr_block. So, most likely, + * you either set the tag propagation policy to TPP_DONT and handle the tag + * propagation manually, or you propagate tags through the scheduler and don't + * do anything here. + * + * \param noutput_items The size of the writable output buffer + * \param ninput_items The exact size of the items on every input for this particular PDU. + * These will be consumed if a length tag key is provided! + * \param input_items See gr_block + * \param output_items See gr_block + */ + virtual int work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) = 0; + +}; + +#endif /* INCLUDED_GR_TAGGED_STREAM_BLOCK_H */ + diff --git a/gnuradio-runtime/include/gr_tags.h b/gnuradio-runtime/include/gr_tags.h new file mode 100644 index 0000000000..668b2bf248 --- /dev/null +++ b/gnuradio-runtime/include/gr_tags.h @@ -0,0 +1,55 @@ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TAGS_H +#define INCLUDED_GR_TAGS_H + +#include <gr_runtime_api.h> +#include <pmt/pmt.h> + +struct GR_RUNTIME_API gr_tag_t{ + + //! the item \p tag occurred at (as a uint64_t) + uint64_t offset; + + //! the key of \p tag (as a PMT symbol) + pmt::pmt_t key; + + //! the value of \p tag (as a PMT) + pmt::pmt_t value; + + //! the source ID of \p tag (as a PMT) + pmt::pmt_t srcid; + + //! Comparison function to test which tag, \p x or \p y, came first in time + static inline bool offset_compare( + const gr_tag_t &x, const gr_tag_t &y + ){ + return x.offset < y.offset; + } + + inline bool operator == (const gr_tag_t &t) const + { + return (t.key == key) && (t.value == value) && (t.srcid == srcid) && (t.offset == offset); + } +}; + +#endif /*INCLUDED_GR_TAGS_H*/ diff --git a/gnuradio-runtime/include/gr_timer.h b/gnuradio-runtime/include/gr_timer.h new file mode 100644 index 0000000000..45b663b368 --- /dev/null +++ b/gnuradio-runtime/include/gr_timer.h @@ -0,0 +1,84 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_TIMER_H +#define INCLUDED_GR_TIMER_H + +#include <gr_runtime_api.h> +#include <gr_types.h> + +class gr_timer; + +typedef boost::shared_ptr<gr_timer> gr_timer_sptr; + +GR_RUNTIME_API typedef void (*gr_timer_hook)(gr_timer *, void *); + +/*! + * \brief create a timeout. + * + * \ingroup misc + * gr_timer_hook is called when timer fires. + */ +GR_RUNTIME_API gr_timer_sptr gr_make_timer (gr_timer_hook, void *); + +/*! + * \brief implement timeouts + */ +class GR_RUNTIME_API gr_timer { + double d_expiry; + double d_period; + gr_timer_hook d_hook; + void *d_hook_arg; + + friend GR_RUNTIME_API gr_timer_sptr gr_make_timer (gr_timer_hook, void *); + + gr_timer (...); + +public: + ~gr_timer (); + + //! return absolute current time (seconds since the epoc). + static double now (); + + /*! + * \brief schedule timer to fire at abs_when + * \param abs_when absolute time in seconds since the epoc. + */ + void schedule_at (double abs_when); + + /*! + * \brief schedule timer to fire rel_when seconds from now. + * \param rel_when relative time in seconds from now. + */ + void schedule_after (double rel_when); // relative time in seconds + + /*! + * \brief schedule a periodic timeout. + * \param abs_when absolute time to fire first time + * \param period time between firings + */ + void schedule_periodic (double abs_when, double period); + + //! cancel timer + void unschedule (); +}; + +#endif /* INCLUDED_GR_TIMER_H */ diff --git a/gnuradio-runtime/include/gr_top_block.h b/gnuradio-runtime/include/gr_top_block.h new file mode 100644 index 0000000000..f523442cd0 --- /dev/null +++ b/gnuradio-runtime/include/gr_top_block.h @@ -0,0 +1,141 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007-2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TOP_BLOCK_H +#define INCLUDED_GR_TOP_BLOCK_H + +#include <gr_runtime_api.h> +#include <gr_hier_block2.h> + +class gr_top_block_impl; + +GR_RUNTIME_API gr_top_block_sptr gr_make_top_block(const std::string &name); + +/*! + *\brief Top-level hierarchical block representing a flowgraph + * \ingroup container_blk + * + */ +class GR_RUNTIME_API gr_top_block : public gr_hier_block2 +{ +private: + friend GR_RUNTIME_API gr_top_block_sptr gr_make_top_block(const std::string &name); + + gr_top_block_impl *d_impl; + +protected: + gr_top_block(const std::string &name); + +public: + ~gr_top_block(); + + /*! + * \brief The simple interface to running a flowgraph. + * + * Calls start() then wait(). Used to run a flowgraph that will stop + * on its own, or when another thread will call stop(). + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph. This passes through to + * the start function; see that function for more details. + */ + void run(int max_noutput_items=100000000); + + /*! + * Start the contained flowgraph. Creates one or more threads to + * execute the flow graph. Returns to the caller once the threads + * are created. Calling start() on a top_block that is already + * started IS an error. + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph; the noutput_items can + * always be less than this, but this will cap it as a maximum. Use + * this to adjust the maximum latency a flowgraph can exhibit. + */ + void start(int max_noutput_items=100000000); + + /*! + * Stop the running flowgraph. Notifies each thread created by the + * scheduler to shutdown, then returns to caller. Calling stop() on + * a top_block that is already stopped IS NOT an error. + */ + void stop(); + + /*! + * Wait for a flowgraph to complete. Flowgraphs complete when + * either (1) all blocks indicate that they are done (typically only + * when using blocks.file_source, or blocks.head, or (2) after stop() has been + * called to request shutdown. Calling wait on a top_block that is + * not running IS NOT an error (wait returns w/o blocking). + */ + void wait(); + + /*! + * Lock a flowgraph in preparation for reconfiguration. When an equal + * number of calls to lock() and unlock() have occurred, the flowgraph + * will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph thread + * (E.g., gr_block::work method) or deadlock will occur when + * reconfiguration happens. + */ + virtual void lock(); + + /*! + * Unlock a flowgraph in preparation for reconfiguration. When an equal + * number of calls to lock() and unlock() have occurred, the flowgraph + * will be reconfigured. + * + * N.B. lock() and unlock() may not be called from a flowgraph thread + * (E.g., gr_block::work method) or deadlock will occur when + * reconfiguration happens. + */ + virtual void unlock(); + + /*! + * Returns a string that lists the edge connections in the flattened + * flowgraph. + */ + std::string edge_list(); + + /*! + * Displays flattened flowgraph edges and block connectivity + */ + void dump(); + + //! Get the number of max noutput_items in the flowgraph + int max_noutput_items(); + + //! Set the maximum number of noutput_items in the flowgraph + void set_max_noutput_items(int nmax); + + gr_top_block_sptr to_top_block(); // Needed for Python type coercion + + void setup_rpc(); +}; + +inline gr_top_block_sptr cast_to_top_block_sptr(gr_basic_block_sptr block) { + return boost::dynamic_pointer_cast<gr_top_block, gr_basic_block>(block); +} + + +#endif /* INCLUDED_GR_TOP_BLOCK_H */ diff --git a/gnuradio-runtime/include/gr_tpb_detail.h b/gnuradio-runtime/include/gr_tpb_detail.h new file mode 100644 index 0000000000..f6f20917c9 --- /dev/null +++ b/gnuradio-runtime/include/gr_tpb_detail.h @@ -0,0 +1,89 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_TPB_DETAIL_H +#define INCLUDED_GR_TPB_DETAIL_H + +#include <gr_runtime_api.h> +#include <thread/thread.h> +#include <deque> +#include <pmt/pmt.h> + +class gr_block_detail; + +/*! + * \brief used by thread-per-block scheduler + */ +struct GR_RUNTIME_API gr_tpb_detail { + + gr::thread::mutex mutex; //< protects all vars + bool input_changed; + gr::thread::condition_variable input_cond; + bool output_changed; + gr::thread::condition_variable output_cond; + +public: + gr_tpb_detail() + : input_changed(false), output_changed(false) { } + + //! Called by us to tell all our upstream blocks that their output may have changed. + void notify_upstream(gr_block_detail *d); + + //! Called by us to tell all our downstream blocks that their input may have changed. + void notify_downstream(gr_block_detail *d); + + //! Called by us to notify both upstream and downstream + void notify_neighbors(gr_block_detail *d); + + //! Called by pmt msg posters + void notify_msg(){ + input_cond.notify_one(); + output_cond.notify_one(); + } + + //! Called by us + void clear_changed() + { + gr::thread::scoped_lock guard(mutex); + input_changed = false; + output_changed = false; + } + +private: + + //! Used by notify_downstream + void set_input_changed() + { + gr::thread::scoped_lock guard(mutex); + input_changed = true; + input_cond.notify_one(); + } + + //! Used by notify_upstream + void set_output_changed() + { + gr::thread::scoped_lock guard(mutex); + output_changed = true; + output_cond.notify_one(); + } + +}; + +#endif /* INCLUDED_GR_TPB_DETAIL_H */ diff --git a/gnuradio-runtime/include/gr_types.h b/gnuradio-runtime/include/gr_types.h new file mode 100644 index 0000000000..47e22469b0 --- /dev/null +++ b/gnuradio-runtime/include/gr_types.h @@ -0,0 +1,65 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_TYPES_H +#define INCLUDED_GR_TYPES_H + +#include <gr_runtime_api.h> +#include <boost/shared_ptr.hpp> +#include <vector> +#include <stddef.h> // size_t + +#include <gr_complex.h> + +typedef std::vector<int> gr_vector_int; +typedef std::vector<unsigned int> gr_vector_uint; +typedef std::vector<float> gr_vector_float; +typedef std::vector<double> gr_vector_double; +typedef std::vector<void *> gr_vector_void_star; +typedef std::vector<const void *> gr_vector_const_void_star; + +/* + * #include <config.h> must be placed beforehand + * in the source file including gr_types.h for + * the following to work correctly + */ +#ifdef HAVE_STDINT_H +#include <stdint.h> +typedef int16_t gr_int16; +typedef int32_t gr_int32; +typedef int64_t gr_int64; +typedef uint16_t gr_uint16; +typedef uint32_t gr_uint32; +typedef uint64_t gr_uint64; +#else +/* + * Note: these defaults may be wrong on 64-bit systems + */ +typedef short gr_int16; +typedef int gr_int32; +typedef long long gr_int64; +typedef unsigned short gr_uint16; +typedef unsigned int gr_uint32; +typedef unsigned long long gr_uint64; +#endif /* HAVE_STDINT_H */ + +#endif /* INCLUDED_GR_TYPES_H */ diff --git a/gnuradio-runtime/include/gr_unittests.h b/gnuradio-runtime/include/gr_unittests.h new file mode 100644 index 0000000000..d160ba3354 --- /dev/null +++ b/gnuradio-runtime/include/gr_unittests.h @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gr_runtime_api.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string> + +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> + +static std::string get_unittest_path(const std::string &filename){ + boost::filesystem::path path = boost::filesystem::current_path() / ".unittests"; + if (!boost::filesystem::is_directory(path)) boost::filesystem::create_directory(path); + return (path / filename).string(); +} diff --git a/gnuradio-runtime/include/high_res_timer.h b/gnuradio-runtime/include/high_res_timer.h new file mode 100644 index 0000000000..fc7b007c61 --- /dev/null +++ b/gnuradio-runtime/include/high_res_timer.h @@ -0,0 +1,126 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GNURADIO_HIGH_RES_TIMER_H +#define INCLUDED_GNURADIO_HIGH_RES_TIMER_H + +namespace gr { + + //! Typedef for the timer tick count + typedef signed long long high_res_timer_type; + + //! Get the current time in ticks + high_res_timer_type high_res_timer_now(void); + + //! Get the number of ticks per second + high_res_timer_type high_res_timer_tps(void); + + //! Get the tick count at the epoch + high_res_timer_type high_res_timer_epoch(void); + +} /* namespace gr */ + +//////////////////////////////////////////////////////////////////////// +// Use architecture defines to determine the implementation +//////////////////////////////////////////////////////////////////////// +#if defined(linux) || defined(__linux) || defined(__linux__) + #define GNURADIO_HRT_USE_CLOCK_GETTIME +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + #define GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + #define GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + #define GNURADIO_HRT_USE_CLOCK_GETTIME +#else + #define GNURADIO_HRT_USE_MICROSEC_CLOCK +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME + #include <ctime> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec*high_res_timer_tps() + ts.tv_nsec; + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + return 1000000000UL; + } +#endif /* GNURADIO_HRT_USE_CLOCK_GETTIME */ + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME + #include <mach/mach_time.h> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + return mach_absolute_time(); + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + return gr::high_res_timer_type(info.numer*1000000000UL)/info.denom; + } +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER + #include <Windows.h> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + LARGE_INTEGER counts; + QueryPerformanceCounter(&counts); + return counts.QuadPart; + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + return freq.QuadPart; + } +#endif + +//////////////////////////////////////////////////////////////////////// +#ifdef GNURADIO_HRT_USE_MICROSEC_CLOCK + #include <boost/date_time/posix_time/posix_time.hpp> + + inline gr::high_res_timer_type gr::high_res_timer_now(void){ + static const boost::posix_time::ptime epoch(boost::posix_time::from_time_t(0)); + return (boost::posix_time::microsec_clock::universal_time() - epoch).ticks(); + } + + inline gr::high_res_timer_type gr::high_res_timer_tps(void){ + return boost::posix_time::time_duration::ticks_per_second(); + } +#endif + +//////////////////////////////////////////////////////////////////////// +#include <boost/date_time/posix_time/posix_time.hpp> + +inline gr::high_res_timer_type gr::high_res_timer_epoch(void){ + static const double hrt_ticks_per_utc_ticks = gr::high_res_timer_tps()/double(boost::posix_time::time_duration::ticks_per_second()); + boost::posix_time::time_duration utc = boost::posix_time::microsec_clock::universal_time() - boost::posix_time::from_time_t(0); + return gr::high_res_timer_now() - utc.ticks()*hrt_ticks_per_utc_ticks; +} + +#endif /* INCLUDED_GNURADIO_HIGH_RES_TIMER_H */ diff --git a/gnuradio-runtime/include/ice_application_base.h b/gnuradio-runtime/include/ice_application_base.h new file mode 100644 index 0000000000..f25c7272fc --- /dev/null +++ b/gnuradio-runtime/include/ice_application_base.h @@ -0,0 +1,222 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ICE_APPLICATION_BASE_H +#define ICE_APPLICATION_BASE_H + +#include <gr_runtime_api.h> +#include <gr_prefs.h> +#include <Ice/Ice.h> +#include <boost/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <stdio.h> +#include <iostream> +#include <set> +#include <string> +#include <stdio.h> + +namespace { + static const unsigned int ICEAPPLICATION_ACTIVATION_TIMEOUT_MS(600); +}; + + +class GR_RUNTIME_API ice_application_common : public Ice::Application +{ + public: + template<typename TserverBase, typename TserverClass> friend class ice_application_base; + static boost::shared_ptr<ice_application_common> Instance(); + ~ice_application_common() {;} + static int d_reacquire_attributes; + + protected: + static bool d_main_called, d_have_ice_config; + static std::string d_endpointStr; + static boost::shared_ptr<boost::thread> d_thread; + ice_application_common() {;} + int run(int, char*[]); +}; + +template<typename TserverBase, typename TserverClass> +class ice_application_base +{ +public: + boost::shared_ptr<ice_application_common> d_application; + ice_application_base(TserverClass* _this); + ~ice_application_base() {;} + + static TserverBase* i(); + static const std::vector<std::string> endpoints(); + +protected: + bool have_ice_config() { return d_application->d_have_ice_config; } + void set_endpoint(const std::string& endpoint) { d_application->d_endpointStr = endpoint;} + + //this one is the key... overwrite in templated/inherited variants + virtual TserverBase* i_impl() = 0; + + //tools for the i_impl... + //tell it when it has to resync with the communicator + virtual bool reacquire_sync(); + virtual void sync_reacquire(); + + static TserverClass* d_this; + + int d_reacquire; + //static int d_reacquire_attributes; + +private: + void starticeexample(); + + bool application_started(); + + int run(int, char*[]); + + static void kickoff(); +}; + +template<typename TserverBase, typename TserverClass> +TserverClass* ice_application_base<TserverBase, TserverClass>::d_this(0); + +//template<typename TserverBase, typename TserverClass> +//int ice_application_base<TserverBase, TserverClass>::d_reacquire_attributes(0); + +template<typename TserverBase, typename TserverClass> +ice_application_base<TserverBase, TserverClass>::ice_application_base(TserverClass* _this) + : d_reacquire(0) +{ + //d_reacquire_attributes = 0; + d_this = _this; + d_application = ice_application_common::Instance(); +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::starticeexample() +{ + char* argv[2]; + argv[0] = (char*)""; + + std::string conffile = gr_prefs::singleton()->get_string("ControlPort", "config", ""); + + if(conffile.size() > 0) { + std::stringstream iceconf; + ice_application_common::d_have_ice_config = true; + ice_application_common::d_main_called = true; + iceconf << conffile; + d_application->main(0, argv, iceconf.str().c_str()); + } + else { + ice_application_common::d_have_ice_config = false; + ice_application_common::d_main_called = true; + d_application->main(0, argv); + } +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::kickoff() +{ + static bool run_once = false; + + //if(!d_this->application_started()) { + if(!run_once) { + ++d_this->d_application->d_reacquire_attributes; + + ice_application_common::d_thread = boost::shared_ptr<boost::thread> + (new boost::thread(boost::bind(&ice_application_base::starticeexample, d_this))); + + ::timespec timer_ts, rem_ts; + timer_ts.tv_sec = 0; timer_ts.tv_nsec = ICEAPPLICATION_ACTIVATION_TIMEOUT_MS*1000; + + int iter = 0; + while(!d_this->application_started()) { + ::nanosleep(&timer_ts, &rem_ts); + if(!d_this->application_started()) + std::cout << "@"; + if(iter++ > 100) { + std::cout << "ice_application_base::kickoff(), timeout waiting to get communicator() d_application->main() might have failed?!" << std::endl;; + break; + } + } + + run_once = true; + } + + return; +} + + +template<typename TserverBase, typename TserverClass> +bool ice_application_base<TserverBase, TserverClass>::reacquire_sync() +{ + return (d_this->d_reacquire != d_application->d_reacquire_attributes); +} + +template<typename TserverBase, typename TserverClass> +void ice_application_base<TserverBase, TserverClass>::sync_reacquire() +{ + d_this->d_reacquire = d_application->d_reacquire_attributes; +} + + +template<typename TserverBase, typename TserverClass> +const std::vector<std::string> ice_application_base<TserverBase, TserverClass>::endpoints() +{ + std::vector<std::string> ep; ep.push_back(d_this->d_application->d_endpointStr); return ep; +} + +template<typename TserverBase, typename TserverClass> +TserverBase* ice_application_base<TserverBase, TserverClass>::i() +{ + //printf("indacall\n"); + + assert(d_this != 0); + if(!d_this->application_started()) { + //printf("anotherkickoff\n"); + kickoff(); + } + //printf("donekickedoff\n"); + + /*else if(!d_proxy) { + d_proxy = d_this->i_impl(); + assert(d_proxy != 0); + }*/ + + return d_this->i_impl(); +} + +/*template<typename TserverBase, typename TserverClass> + int ice_application_base<TserverBase, TserverClass>::run(int argc, char* argv[]) { + int implreturn(run_impl(argc, argv)); + ice_application_base<TserverBase, TserverClass>::communicator()->waitForShutdown(); + return implreturn; + }*/ + +template<typename TserverBase, typename TImplClass> +bool ice_application_base<TserverBase, TImplClass>::application_started() +{ + return ice_application_base<TserverBase, TImplClass>::d_this->d_application->communicator(); +} + +/*template<typename TserverBase, typename TImplClass> +int ice_application_base<TserverBase, TImplClass>::run_impl(int argc, char* argv[]) { return EXIT_SUCCESS; } +*/ + +#endif diff --git a/gnuradio-runtime/include/ice_server_template.h b/gnuradio-runtime/include/ice_server_template.h new file mode 100644 index 0000000000..8ddb03cc8e --- /dev/null +++ b/gnuradio-runtime/include/ice_server_template.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef ICE_SERVER_TEMPLATE_H +#define ICE_SERVER_TEMPLATE_H + +#include <ice_application_base.h> +#include <iostream> + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +class ice_server_template : public ice_application_base<TserverBase, TImplClass> +{ +public: + ice_server_template(TImplClass* _this, + const std::string& contolPortName, + const std::string& endpointName); + ~ice_server_template(); + +protected: + //virtual bool application_started(); + TserverBase* i_impl(); + friend class ice_application_base<TserverBase, TImplClass>; + +private: + //virtual int run_impl(int, char*[]); + Ice::ObjectAdapterPtr d_adapter; + TserverBase* d_iceserver; + const std::string d_contolPortName, d_endpointName; +}; + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::ice_server_template + (TImplClass* _this, const std::string& controlPortName, const std::string& endpointName) + : ice_application_base<TserverBase, TImplClass>(_this), + d_iceserver(0), + d_contolPortName(controlPortName), + d_endpointName(endpointName) +{;} + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +ice_server_template<TserverBase, TserverClass,TImplClass, TIceClass>::~ice_server_template() +{ + if(d_adapter) { + d_adapter->deactivate(); + delete(d_iceserver); + d_adapter = 0; + } +} + +template<typename TserverBase, typename TserverClass, typename TImplClass, typename TIceClass> +TserverBase* ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::i_impl() +{ + if(ice_application_base<TserverBase, TImplClass>::d_this->reacquire_sync()) { + d_adapter = (ice_application_base<TserverBase, TImplClass>::d_this->have_ice_config()) ? + ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->createObjectAdapter(d_contolPortName) : + ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->createObjectAdapterWithEndpoints(d_contolPortName,"tcp -h *"); + + TserverClass* server_ice(new TserverClass()); + TIceClass obj(server_ice); + + Ice::Identity id(ice_application_base<TserverBase, TImplClass>::d_this->d_this->d_application->communicator()->stringToIdentity(d_endpointName)); + d_adapter->add(obj, id); + d_adapter->activate(); + ice_application_base<TserverBase, TImplClass>::d_this->set_endpoint(ice_application_common::communicator()->proxyToString(d_adapter->createDirectProxy(id))); + + std::cout << std::endl << "Ice Radio Endpoint: " + << ice_server_template<TserverBase, TserverClass, TImplClass, TIceClass>::endpoints()[0] + << std::endl; + + d_iceserver = (TserverBase*) server_ice; + ice_application_base<TserverBase, TImplClass>::d_this->sync_reacquire(); + } + + return d_iceserver; +} + +#endif /* ICE_SERVER_TEMPLATE_H */ diff --git a/gnuradio-runtime/include/messages/CMakeLists.txt b/gnuradio-runtime/include/messages/CMakeLists.txt new file mode 100644 index 0000000000..f79f2bd24f --- /dev/null +++ b/gnuradio-runtime/include/messages/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install header files +######################################################################## +install(FILES + msg_accepter.h + msg_accepter_msgq.h + msg_passing.h + msg_producer.h + msg_queue.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/messages + COMPONENT "runtime_devel" +) diff --git a/gnuradio-runtime/include/messages/msg_accepter.h b/gnuradio-runtime/include/messages/msg_accepter.h new file mode 100644 index 0000000000..d3e89daf74 --- /dev/null +++ b/gnuradio-runtime/include/messages/msg_accepter.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_ACCEPTER_H +#define INCLUDED_MSG_ACCEPTER_H + +#include <gr_runtime_api.h> +#include <pmt/pmt.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + namespace messages { + + /*! + * \brief Virtual base class that accepts messages + */ + class GR_RUNTIME_API msg_accepter + { + public: + msg_accepter() {}; + virtual ~msg_accepter(); + + /*! + * \brief send \p msg to \p msg_accepter on port \p which_port + * + * Sending a message is an asynchronous operation. The \p post + * call will not wait for the message either to arrive at the + * destination or to be received. + */ + virtual void post(pmt::pmt_t which_port, pmt::pmt_t msg) = 0; + }; + + typedef boost::shared_ptr<msg_accepter> msg_accepter_sptr; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_ACCEPTER_H */ diff --git a/gnuradio-runtime/include/messages/msg_accepter_msgq.h b/gnuradio-runtime/include/messages/msg_accepter_msgq.h new file mode 100644 index 0000000000..5d1d4f7e27 --- /dev/null +++ b/gnuradio-runtime/include/messages/msg_accepter_msgq.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_ACCEPTER_MSGQ_H +#define INCLUDED_MSG_ACCEPTER_MSGQ_H + +#include <gr_runtime_api.h> +#include <messages/msg_accepter.h> +#include <messages/msg_queue.h> + +namespace gr { + namespace messages { + + /*! + * \brief Concrete class that accepts messages and inserts them + * into a message queue. + */ + class GR_RUNTIME_API msg_accepter_msgq : public msg_accepter + { + protected: + msg_queue_sptr d_msg_queue; + + public: + msg_accepter_msgq(msg_queue_sptr msgq); + ~msg_accepter_msgq(); + + virtual void post(pmt::pmt_t msg); + + msg_queue_sptr msg_queue() const { return d_msg_queue; } + }; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_ACCEPTER_MSGQ_H */ diff --git a/gnuradio-runtime/include/messages/msg_passing.h b/gnuradio-runtime/include/messages/msg_passing.h new file mode 100644 index 0000000000..3bfccda339 --- /dev/null +++ b/gnuradio-runtime/include/messages/msg_passing.h @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_PASSING_H +#define INCLUDED_MSG_PASSING_H + +/*! + * \brief Include this header to use the message passing features + */ + +#include <gr_runtime_api.h> +#include <pmt/pmt.h> +#include <messages/msg_accepter.h> + +namespace gr { + namespace messages { + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter_sptr accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter->post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter *accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter->post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(msg_accepter &accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + accepter.post(which_port, msg); + return msg; + } + + /*! + * \brief send message to msg_accepter + * + * \param accepter is the target of the send. + * aprecond: pmt::is_msg_accepter(accepter) + * \param which_port A pmt symbol describing the port by name. + * \param msg is the message to send. It's usually a pmt tuple. + * + * Sending a message is an asynchronous operation. The \p send + * call will not wait for the message either to arrive at the + * destination or to be received. + * + * \returns msg + */ + static inline pmt::pmt_t + send(pmt::pmt_t accepter, const pmt::pmt_t &which_port, + const pmt::pmt_t &msg) + { + return send(pmt::msg_accepter_ref(accepter), which_port, msg); + } + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_PASSING_H */ diff --git a/gnuradio-runtime/include/messages/msg_producer.h b/gnuradio-runtime/include/messages/msg_producer.h new file mode 100644 index 0000000000..3167fc442a --- /dev/null +++ b/gnuradio-runtime/include/messages/msg_producer.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MSG_PRODUCER_H +#define INCLUDED_MSG_PRODUCER_H + +#include <gr_runtime_api.h> +#include <pmt/pmt.h> +#include <boost/shared_ptr.hpp> + +namespace gr { + namespace messages { + + /*! + * \brief Virtual base class that produces messages + */ + class GR_RUNTIME_API msg_producer + { + public: + msg_producer() {} + virtual ~msg_producer(); + + /*! + * \brief send \p msg to \p msg_producer + */ + virtual pmt::pmt_t retrieve() = 0; + }; + + typedef boost::shared_ptr<msg_producer> msg_producer_sptr; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_PRODUCER_H */ diff --git a/gnuradio-runtime/include/messages/msg_queue.h b/gnuradio-runtime/include/messages/msg_queue.h new file mode 100644 index 0000000000..81531afcdf --- /dev/null +++ b/gnuradio-runtime/include/messages/msg_queue.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_MSG_QUEUE_H +#define INCLUDED_MSG_QUEUE_H + +#include <gr_runtime_api.h> +#include <thread/thread.h> +#include <pmt/pmt.h> +#include <deque> + +namespace gr { + namespace messages { + + class msg_queue; + typedef boost::shared_ptr<msg_queue> msg_queue_sptr; + + msg_queue_sptr make_msg_queue(unsigned int limit=0); + + /*! + * \brief thread-safe message queue + */ + class GR_RUNTIME_API msg_queue + { + private: + gr::thread::mutex d_mutex; + gr::thread::condition_variable d_not_empty; + gr::thread::condition_variable d_not_full; + unsigned int d_limit; // max # of messages in queue. 0 -> unbounded + + std::deque<pmt::pmt_t> d_msgs; + + public: + msg_queue(unsigned int limit); + ~msg_queue(); + + /*! + * \brief Insert message at tail of queue. + * \param msg message + * + * Block if queue if full. + */ + void insert_tail(pmt::pmt_t msg); + + /*! + * \brief Delete message from head of queue and return it. + * Block if no message is available. + */ + pmt::pmt_t delete_head(); + + /*! + * \brief If there's a message in the q, delete it and return it. + * If no message is available, return pmt_t(). + */ + pmt::pmt_t delete_head_nowait(); + + //! Delete all messages from the queue + void flush(); + + //! is the queue empty? + bool empty_p() const { return d_msgs.empty(); } + + //! is the queue full? + bool full_p() const { return d_limit != 0 && count() >= d_limit; } + + //! return number of messages in queue + unsigned int count() const { return d_msgs.size(); } + + //! return limit on number of message in queue. 0 -> unbounded + unsigned int limit() const { return d_limit; } + }; + + } /* namespace messages */ +} /* namespace gr */ + +#endif /* INCLUDED_MSG_QUEUE_H */ diff --git a/gnuradio-runtime/include/pmt/CMakeLists.txt b/gnuradio-runtime/include/pmt/CMakeLists.txt new file mode 100644 index 0000000000..4ae0e22431 --- /dev/null +++ b/gnuradio-runtime/include/pmt/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright 2010-2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install the headers +######################################################################## +install(FILES + api.h + pmt.h + pmt_pool.h + pmt_sugar.h + DESTINATION ${GR_INCLUDE_DIR}/pmt + COMPONENT "runtime_devel") diff --git a/gnuradio-runtime/include/pmt/api.h b/gnuradio-runtime/include/pmt/api.h new file mode 100644 index 0000000000..5dcc8a84a5 --- /dev/null +++ b/gnuradio-runtime/include/pmt/api.h @@ -0,0 +1,33 @@ +/* + * Copyright 2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_PMT_API_H +#define INCLUDED_PMT_API_H + +#include <attributes.h> + +#ifdef pmt_EXPORTS +# define PMT_API __GR_ATTR_EXPORT +#else +# define PMT_API __GR_ATTR_IMPORT +#endif + +#endif /* INCLUDED_PMT_API_H */ diff --git a/gnuradio-runtime/include/pmt/pmt.h b/gnuradio-runtime/include/pmt/pmt.h new file mode 100644 index 0000000000..c4efbfc173 --- /dev/null +++ b/gnuradio-runtime/include/pmt/pmt.h @@ -0,0 +1,886 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,2010,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_PMT_H +#define INCLUDED_PMT_H + +#include <pmt/api.h> +#include <boost/intrusive_ptr.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/any.hpp> +#include <complex> +#include <string> +#include <stdint.h> +#include <iosfwd> +#include <stdexcept> +#include <vector> + +namespace gr { + namespace messages { + class msg_accepter; + } +} + +/*! + * This file defines a polymorphic type and the operations on it. + * + * It draws heavily on the idea of scheme and lisp data types. + * The interface parallels that in Guile 1.8, with the notable + * exception that these objects are transparently reference counted. + */ + +namespace pmt { + +/*! + * \brief base class of all pmt types + */ +class pmt_base; + +/*! + * \brief typedef for shared pointer (transparent reference counting). + * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm + */ +typedef boost::intrusive_ptr<pmt_base> pmt_t; + +extern PMT_API void intrusive_ptr_add_ref(pmt_base*); +extern PMT_API void intrusive_ptr_release(pmt_base*); + +class PMT_API exception : public std::logic_error +{ +public: + exception(const std::string &msg, pmt_t obj); +}; + +class PMT_API wrong_type : public exception +{ +public: + wrong_type(const std::string &msg, pmt_t obj); +}; + +class PMT_API out_of_range : public exception +{ +public: + out_of_range(const std::string &msg, pmt_t obj); +}; + +class PMT_API notimplemented : public exception +{ +public: + notimplemented(const std::string &msg, pmt_t obj); +}; + +/* + * ------------------------------------------------------------------------ + * Booleans. Two constants, #t and #f. + * + * In predicates, anything that is not #f is considered true. + * I.e., there is a single false value, #f. + * ------------------------------------------------------------------------ + */ +extern PMT_API const pmt_t PMT_T; //< \#t : boolean true constant +extern PMT_API const pmt_t PMT_F; //< \#f : boolean false constant + +//! Return true if obj is \#t or \#f, else return false. +PMT_API bool is_bool(pmt_t obj); + +//! Return false if obj is \#f, else return true. +PMT_API bool is_true(pmt_t obj); + +//! Return true if obj is \#f, else return true. +PMT_API bool is_false(pmt_t obj); + +//! Return \#f is val is false, else return \#t. +PMT_API pmt_t from_bool(bool val); + +//! Return true if val is pmt::True, return false when val is pmt::PMT_F, +// else raise wrong_type exception. +PMT_API bool to_bool(pmt_t val); + +/* + * ------------------------------------------------------------------------ + * Symbols + * ------------------------------------------------------------------------ + */ + +//! Return true if obj is a symbol, else false. +PMT_API bool is_symbol(const pmt_t& obj); + +//! Return the symbol whose name is \p s. +PMT_API pmt_t string_to_symbol(const std::string &s); + +//! Alias for pmt_string_to_symbol +PMT_API pmt_t intern(const std::string &s); + + +/*! + * If \p is a symbol, return the name of the symbol as a string. + * Otherwise, raise the wrong_type exception. + */ +PMT_API const std::string symbol_to_string(const pmt_t& sym); + +/* + * ------------------------------------------------------------------------ + * Numbers: we support integer, real and complex + * ------------------------------------------------------------------------ + */ + +//! Return true if obj is any kind of number, else false. +PMT_API bool is_number(pmt_t obj); + +/* + * ------------------------------------------------------------------------ + * Integers + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is an integer number, else false +PMT_API bool is_integer(pmt_t x); + +//! Return the pmt value that represents the integer \p x. +PMT_API pmt_t from_long(long x); + +/*! + * \brief Convert pmt to long if possible. + * + * When \p x represents an exact integer that fits in a long, + * return that integer. Else raise an exception, either wrong_type + * when x is not an exact integer, or out_of_range when it doesn't fit. + */ +PMT_API long to_long(pmt_t x); + +/* + * ------------------------------------------------------------------------ + * uint64_t + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is an uint64 number, else false +PMT_API bool is_uint64(pmt_t x); + +//! Return the pmt value that represents the uint64 \p x. +PMT_API pmt_t from_uint64(uint64_t x); + +/*! + * \brief Convert pmt to uint64 if possible. + * + * When \p x represents an exact integer that fits in a uint64, + * return that uint64. Else raise an exception, either wrong_type + * when x is not an exact uint64, or out_of_range when it doesn't fit. + */ +PMT_API uint64_t to_uint64(pmt_t x); + +/* + * ------------------------------------------------------------------------ + * Reals + * ------------------------------------------------------------------------ + */ + +/* + * \brief Return true if \p obj is a real number, else false. + */ +PMT_API bool is_real(pmt_t obj); + +//! Return the pmt value that represents double \p x. +PMT_API pmt_t from_double(double x); + +/*! + * \brief Convert pmt to double if possible. + * + * Returns the number closest to \p val that is representable + * as a double. The argument \p val must be a real or integer, otherwise + * a wrong_type exception is raised. + */ +PMT_API double to_double(pmt_t x); + +/* + * ------------------------------------------------------------------------ + * Complex + * ------------------------------------------------------------------------ + */ + +/*! + * \brief return true if \p obj is a complex number, false otherwise. + */ +PMT_API bool is_complex(pmt_t obj); + +//! Return a complex number constructed of the given real and imaginary parts. +PMT_API pmt_t make_rectangular(double re, double im); + +//! Return a complex number constructed of the given real and imaginary parts. +PMT_API pmt_t from_complex(double re, double im); + +//! Return a complex number constructed of the given a complex number. +PMT_API pmt_t from_complex(const std::complex<double> &z); + +//! Return a complex number constructed of the given real and imaginary parts. +PMT_API pmt_t pmt_from_complex(double re, double im); + +//! Return a complex number constructed of the given a complex number. +PMT_API pmt_t pmt_from_complex(const std::complex<double> &z); + +/*! + * If \p z is complex, real or integer, return the closest complex<double>. + * Otherwise, raise the wrong_type exception. + */ +PMT_API std::complex<double> to_complex(pmt_t z); + +/* + * ------------------------------------------------------------------------ + * Pairs + * ------------------------------------------------------------------------ + */ + +extern PMT_API const pmt_t PMT_NIL; //< the empty list + +//! Return true if \p x is the empty list, otherwise return false. +PMT_API bool is_null(const pmt_t& x); + +//! Return true if \p obj is a pair, else false. +PMT_API bool is_pair(const pmt_t& obj); + +//! Return a newly allocated pair whose car is \p x and whose cdr is \p y. +PMT_API pmt_t cons(const pmt_t& x, const pmt_t& y); + +//! If \p pair is a pair, return the car of the \p pair, otherwise raise wrong_type. +PMT_API pmt_t car(const pmt_t& pair); + +//! If \p pair is a pair, return the cdr of the \p pair, otherwise raise wrong_type. +PMT_API pmt_t cdr(const pmt_t& pair); + +//! Stores \p value in the car field of \p pair. +PMT_API void set_car(pmt_t pair, pmt_t value); + +//! Stores \p value in the cdr field of \p pair. +PMT_API void set_cdr(pmt_t pair, pmt_t value); + +PMT_API pmt_t caar(pmt_t pair); +PMT_API pmt_t cadr(pmt_t pair); +PMT_API pmt_t cdar(pmt_t pair); +PMT_API pmt_t cddr(pmt_t pair); +PMT_API pmt_t caddr(pmt_t pair); +PMT_API pmt_t cadddr(pmt_t pair); + +/* + * ------------------------------------------------------------------------ + * Tuples + * + * Store a fixed number of objects. Tuples are not modifiable, and thus + * are excellent for use as messages. Indexing is zero based. + * Access time to an element is O(1). + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is a tuple, othewise false. +PMT_API bool is_tuple(pmt_t x); + +PMT_API pmt_t make_tuple(); +PMT_API pmt_t make_tuple(const pmt_t &e0); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8); +PMT_API pmt_t make_tuple(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9); + +/*! + * If \p x is a vector or proper list, return a tuple containing the elements of x + */ +PMT_API pmt_t to_tuple(const pmt_t &x); + +/*! + * Return the contents of position \p k of \p tuple. + * \p k must be a valid index of \p tuple. + */ +PMT_API pmt_t tuple_ref(const pmt_t &tuple, size_t k); + +/* + * ------------------------------------------------------------------------ + * Vectors + * + * These vectors can hold any kind of objects. Indexing is zero based. + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is a vector, othewise false. +PMT_API bool is_vector(pmt_t x); + +//! Make a vector of length \p k, with initial values set to \p fill +PMT_API pmt_t make_vector(size_t k, pmt_t fill); + +/*! + * Return the contents of position \p k of \p vector. + * \p k must be a valid index of \p vector. + */ +PMT_API pmt_t vector_ref(pmt_t vector, size_t k); + +//! Store \p obj in position \p k. +PMT_API void vector_set(pmt_t vector, size_t k, pmt_t obj); + +//! Store \p fill in every position of \p vector +PMT_API void vector_fill(pmt_t vector, pmt_t fill); + +/* + * ------------------------------------------------------------------------ + * Binary Large Objects (BLOBs) + * + * Handy for passing around uninterpreted chunks of memory. + * ------------------------------------------------------------------------ + */ + +//! Return true if \p x is a blob, othewise false. +PMT_API bool is_blob(pmt_t x); + +/*! + * \brief Make a blob given a pointer and length in bytes + * + * \param buf is the pointer to data to use to create blob + * \param len is the size of the data in bytes. + * + * The data is copied into the blob. + */ +PMT_API pmt_t make_blob(const void *buf, size_t len); + +//! Return a pointer to the blob's data +PMT_API const void *blob_data(pmt_t blob); + +//! Return the blob's length in bytes +PMT_API size_t blob_length(pmt_t blob); + +/*! + * <pre> + * ------------------------------------------------------------------------ + * Uniform Numeric Vectors + * + * A uniform numeric vector is a vector whose elements are all of single + * numeric type. pmt offers uniform numeric vectors for signed and + * unsigned 8-bit, 16-bit, 32-bit, and 64-bit integers, two sizes of + * floating point values, and complex floating-point numbers of these + * two sizes. Indexing is zero based. + * + * The names of the functions include these tags in their names: + * + * u8 unsigned 8-bit integers + * s8 signed 8-bit integers + * u16 unsigned 16-bit integers + * s16 signed 16-bit integers + * u32 unsigned 32-bit integers + * s32 signed 32-bit integers + * u64 unsigned 64-bit integers + * s64 signed 64-bit integers + * f32 the C++ type float + * f64 the C++ type double + * c32 the C++ type complex<float> + * c64 the C++ type complex<double> + * ------------------------------------------------------------------------ + * </pre> + */ + +//! true if \p x is any kind of uniform numeric vector +PMT_API bool is_uniform_vector(pmt_t x); + +PMT_API bool is_u8vector(pmt_t x); +PMT_API bool is_s8vector(pmt_t x); +PMT_API bool is_u16vector(pmt_t x); +PMT_API bool is_s16vector(pmt_t x); +PMT_API bool is_u32vector(pmt_t x); +PMT_API bool is_s32vector(pmt_t x); +PMT_API bool is_u64vector(pmt_t x); +PMT_API bool is_s64vector(pmt_t x); +PMT_API bool is_f32vector(pmt_t x); +PMT_API bool is_f64vector(pmt_t x); +PMT_API bool is_c32vector(pmt_t x); +PMT_API bool is_c64vector(pmt_t x); + +PMT_API pmt_t make_u8vector(size_t k, uint8_t fill); +PMT_API pmt_t make_s8vector(size_t k, int8_t fill); +PMT_API pmt_t make_u16vector(size_t k, uint16_t fill); +PMT_API pmt_t make_s16vector(size_t k, int16_t fill); +PMT_API pmt_t make_u32vector(size_t k, uint32_t fill); +PMT_API pmt_t make_s32vector(size_t k, int32_t fill); +PMT_API pmt_t make_u64vector(size_t k, uint64_t fill); +PMT_API pmt_t make_s64vector(size_t k, int64_t fill); +PMT_API pmt_t make_f32vector(size_t k, float fill); +PMT_API pmt_t make_f64vector(size_t k, double fill); +PMT_API pmt_t make_c32vector(size_t k, std::complex<float> fill); +PMT_API pmt_t make_c64vector(size_t k, std::complex<double> fill); + +PMT_API pmt_t init_u8vector(size_t k, const uint8_t *data); +PMT_API pmt_t init_u8vector(size_t k, const std::vector<uint8_t> &data); +PMT_API pmt_t init_s8vector(size_t k, const int8_t *data); +PMT_API pmt_t init_s8vector(size_t k, const std::vector<int8_t> &data); +PMT_API pmt_t init_u16vector(size_t k, const uint16_t *data); +PMT_API pmt_t init_u16vector(size_t k, const std::vector<uint16_t> &data); +PMT_API pmt_t init_s16vector(size_t k, const int16_t *data); +PMT_API pmt_t init_s16vector(size_t k, const std::vector<int16_t> &data); +PMT_API pmt_t init_u32vector(size_t k, const uint32_t *data); +PMT_API pmt_t init_u32vector(size_t k, const std::vector<uint32_t> &data); +PMT_API pmt_t init_s32vector(size_t k, const int32_t *data); +PMT_API pmt_t init_s32vector(size_t k, const std::vector<int32_t> &data); +PMT_API pmt_t init_u64vector(size_t k, const uint64_t *data); +PMT_API pmt_t init_u64vector(size_t k, const std::vector<uint64_t> &data); +PMT_API pmt_t init_s64vector(size_t k, const int64_t *data); +PMT_API pmt_t init_s64vector(size_t k, const std::vector<int64_t> &data); +PMT_API pmt_t init_f32vector(size_t k, const float *data); +PMT_API pmt_t init_f32vector(size_t k, const std::vector<float> &data); +PMT_API pmt_t init_f64vector(size_t k, const double *data); +PMT_API pmt_t init_f64vector(size_t k, const std::vector<double> &data); +PMT_API pmt_t init_c32vector(size_t k, const std::complex<float> *data); +PMT_API pmt_t init_c32vector(size_t k, const std::vector<std::complex<float> > &data); +PMT_API pmt_t init_c64vector(size_t k, const std::complex<double> *data); +PMT_API pmt_t init_c64vector(size_t k, const std::vector<std::complex<double> > &data); + +PMT_API uint8_t u8vector_ref(pmt_t v, size_t k); +PMT_API int8_t s8vector_ref(pmt_t v, size_t k); +PMT_API uint16_t u16vector_ref(pmt_t v, size_t k); +PMT_API int16_t s16vector_ref(pmt_t v, size_t k); +PMT_API uint32_t u32vector_ref(pmt_t v, size_t k); +PMT_API int32_t s32vector_ref(pmt_t v, size_t k); +PMT_API uint64_t u64vector_ref(pmt_t v, size_t k); +PMT_API int64_t s64vector_ref(pmt_t v, size_t k); +PMT_API float f32vector_ref(pmt_t v, size_t k); +PMT_API double f64vector_ref(pmt_t v, size_t k); +PMT_API std::complex<float> c32vector_ref(pmt_t v, size_t k); +PMT_API std::complex<double> c64vector_ref(pmt_t v, size_t k); + +PMT_API void u8vector_set(pmt_t v, size_t k, uint8_t x); //< v[k] = x +PMT_API void s8vector_set(pmt_t v, size_t k, int8_t x); +PMT_API void u16vector_set(pmt_t v, size_t k, uint16_t x); +PMT_API void s16vector_set(pmt_t v, size_t k, int16_t x); +PMT_API void u32vector_set(pmt_t v, size_t k, uint32_t x); +PMT_API void s32vector_set(pmt_t v, size_t k, int32_t x); +PMT_API void u64vector_set(pmt_t v, size_t k, uint64_t x); +PMT_API void s64vector_set(pmt_t v, size_t k, int64_t x); +PMT_API void f32vector_set(pmt_t v, size_t k, float x); +PMT_API void f64vector_set(pmt_t v, size_t k, double x); +PMT_API void c32vector_set(pmt_t v, size_t k, std::complex<float> x); +PMT_API void c64vector_set(pmt_t v, size_t k, std::complex<double> x); + +// Return const pointers to the elements + +PMT_API const void *uniform_vector_elements(pmt_t v, size_t &len); //< works with any; len is in bytes + +PMT_API const uint8_t *u8vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const int8_t *s8vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const uint16_t *u16vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const int16_t *s16vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const uint32_t *u32vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const int32_t *s32vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const uint64_t *u64vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const int64_t *s64vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const float *f32vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const double *f64vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const std::complex<float> *c32vector_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API const std::complex<double> *c64vector_elements(pmt_t v, size_t &len); //< len is in elements + +// len is in elements +PMT_API const std::vector<uint8_t> u8vector_elements(pmt_t v); +PMT_API const std::vector<int8_t> s8vector_elements(pmt_t v); +PMT_API const std::vector<uint16_t> u16vector_elements(pmt_t v); +PMT_API const std::vector<int16_t> s16vector_elements(pmt_t v); +PMT_API const std::vector<uint32_t> u32vector_elements(pmt_t v); +PMT_API const std::vector<int32_t> s32vector_elements(pmt_t v); +PMT_API const std::vector<uint64_t> u64vector_elements(pmt_t v); +PMT_API const std::vector<int64_t> s64vector_elements(pmt_t v); +PMT_API const std::vector<float> f32vector_elements(pmt_t v); +PMT_API const std::vector<double> f64vector_elements(pmt_t v); +PMT_API const std::vector<std::complex<float> > c32vector_elements(pmt_t v); +PMT_API const std::vector<std::complex<double> > c64vector_elements(pmt_t v); + +// len is in elements +PMT_API const std::vector<uint8_t> pmt_u8vector_elements(pmt_t v); +PMT_API const std::vector<int8_t> pmt_s8vector_elements(pmt_t v); +PMT_API const std::vector<uint16_t> pmt_u16vector_elements(pmt_t v); +PMT_API const std::vector<int16_t> pmt_s16vector_elements(pmt_t v); +PMT_API const std::vector<uint32_t> pmt_u32vector_elements(pmt_t v); +PMT_API const std::vector<int32_t> pmt_s32vector_elements(pmt_t v); +PMT_API const std::vector<uint64_t> pmt_u64vector_elements(pmt_t v); +PMT_API const std::vector<int64_t> pmt_s64vector_elements(pmt_t v); +PMT_API const std::vector<float> pmt_f32vector_elements(pmt_t v); +PMT_API const std::vector<double> pmt_f64vector_elements(pmt_t v); +PMT_API const std::vector<std::complex<float> > pmt_c32vector_elements(pmt_t v); +PMT_API const std::vector<std::complex<double> > pmt_c64vector_elements(pmt_t v); + +// Return non-const pointers to the elements + +PMT_API void *uniform_vector_writable_elements(pmt_t v, size_t &len); //< works with any; len is in bytes + +PMT_API uint8_t *u8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API int8_t *s8vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API uint16_t *u16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API int16_t *s16vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API uint32_t *u32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API int32_t *s32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API uint64_t *u64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API int64_t *s64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API float *f32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API double *f64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API std::complex<float> *c32vector_writable_elements(pmt_t v, size_t &len); //< len is in elements +PMT_API std::complex<double> *c64vector_writable_elements(pmt_t v, size_t &len); //< len is in elements + +/* + * ------------------------------------------------------------------------ + * Dictionary (a.k.a associative array, hash, map) + * + * This is a functional data structure that is persistent. Updating a + * functional data structure does not destroy the existing version, but + * rather creates a new version that coexists with the old. + * ------------------------------------------------------------------------ + */ + +//! Return true if \p obj is a dictionary +PMT_API bool is_dict(const pmt_t &obj); + +//! Make an empty dictionary +PMT_API pmt_t make_dict(); + +//! Return a new dictionary with \p key associated with \p value. +PMT_API pmt_t dict_add(const pmt_t &dict, const pmt_t &key, const pmt_t &value); + +//! Return a new dictionary with \p key removed. +PMT_API pmt_t dict_delete(const pmt_t &dict, const pmt_t &key); + +//! Return true if \p key exists in \p dict +PMT_API bool dict_has_key(const pmt_t &dict, const pmt_t &key); + +//! If \p key exists in \p dict, return associated value; otherwise return \p not_found. +PMT_API pmt_t dict_ref(const pmt_t &dict, const pmt_t &key, const pmt_t ¬_found); + +//! Return list of (key . value) pairs +PMT_API pmt_t dict_items(pmt_t dict); + +//! Return list of keys +PMT_API pmt_t dict_keys(pmt_t dict); + +//! Return list of values +PMT_API pmt_t dict_values(pmt_t dict); + +/* + * ------------------------------------------------------------------------ + * Any (wraps boost::any -- can be used to wrap pretty much anything) + * + * Cannot be serialized or used across process boundaries. + * See http://www.boost.org/doc/html/any.html + * ------------------------------------------------------------------------ + */ + +//! Return true if \p obj is an any +PMT_API bool is_any(pmt_t obj); + +//! make an any +PMT_API pmt_t make_any(const boost::any &any); + +//! Return underlying boost::any +PMT_API boost::any any_ref(pmt_t obj); + +//! Store \p any in \p obj +PMT_API void any_set(pmt_t obj, const boost::any &any); + + +/* + * ------------------------------------------------------------------------ + * msg_accepter -- pmt representation of pmt::msg_accepter + * ------------------------------------------------------------------------ + */ +//! Return true if \p obj is a msg_accepter +PMT_API bool is_msg_accepter(const pmt_t &obj); + +//! make a msg_accepter +PMT_API pmt_t make_msg_accepter(boost::shared_ptr<gr::messages::msg_accepter> ma); + +//! Return underlying msg_accepter +PMT_API boost::shared_ptr<gr::messages::msg_accepter> msg_accepter_ref(const pmt_t &obj); + +/* + * ------------------------------------------------------------------------ + * General functions + * ------------------------------------------------------------------------ + */ + +//! Return true if x and y are the same object; otherwise return false. +PMT_API bool eq(const pmt_t& x, const pmt_t& y); + +/*! + * \brief Return true if x and y should normally be regarded as the same object, else false. + * + * <pre> + * eqv returns true if: + * x and y are the same object. + * x and y are both \#t or both \#f. + * x and y are both symbols and their names are the same. + * x and y are both numbers, and are numerically equal. + * x and y are both the empty list (nil). + * x and y are pairs or vectors that denote same location in store. + * </pre> + */ +PMT_API bool eqv(const pmt_t& x, const pmt_t& y); + +/*! + * pmt::equal recursively compares the contents of pairs and vectors, + * applying pmt::eqv on other objects such as numbers and symbols. + * pmt::equal may fail to terminate if its arguments are circular data + * structures. + */ +PMT_API bool equal(const pmt_t& x, const pmt_t& y); + + +//! Return the number of elements in v +PMT_API size_t length(const pmt_t& v); + +/*! + * \brief Find the first pair in \p alist whose car field is \p obj + * and return that pair. + * + * \p alist (for "association list") must be a list of pairs. If no pair + * in \p alist has \p obj as its car then \#f is returned. + * Uses pmt::eq to compare \p obj with car fields of the pairs in \p alist. + */ +PMT_API pmt_t assq(pmt_t obj, pmt_t alist); + +/*! + * \brief Find the first pair in \p alist whose car field is \p obj + * and return that pair. + * + * \p alist (for "association list") must be a list of pairs. If no pair + * in \p alist has \p obj as its car then \#f is returned. + * Uses pmt::eqv to compare \p obj with car fields of the pairs in \p alist. + */ +PMT_API pmt_t assv(pmt_t obj, pmt_t alist); + +/*! + * \brief Find the first pair in \p alist whose car field is \p obj + * and return that pair. + * + * \p alist (for "association list") must be a list of pairs. If no pair + * in \p alist has \p obj as its car then \#f is returned. + * Uses pmt::equal to compare \p obj with car fields of the pairs in \p alist. + */ +PMT_API pmt_t assoc(pmt_t obj, pmt_t alist); + +/*! + * \brief Apply \p proc element-wise to the elements of list and returns + * a list of the results, in order. + * + * \p list must be a list. The dynamic order in which \p proc is + * applied to the elements of \p list is unspecified. + */ +PMT_API pmt_t map(pmt_t proc(const pmt_t&), pmt_t list); + +/*! + * \brief reverse \p list. + * + * \p list must be a proper list. + */ +PMT_API pmt_t reverse(pmt_t list); + +/*! + * \brief destructively reverse \p list. + * + * \p list must be a proper list. + */ +PMT_API pmt_t reverse_x(pmt_t list); + +/*! + * \brief (acons x y a) == (cons (cons x y) a) + */ +inline static pmt_t +acons(pmt_t x, pmt_t y, pmt_t a) +{ + return cons(cons(x, y), a); +} + +/*! + * \brief locates \p nth element of \n list where the car is the 'zeroth' element. + */ +PMT_API pmt_t nth(size_t n, pmt_t list); + +/*! + * \brief returns the tail of \p list that would be obtained by calling + * cdr \p n times in succession. + */ +PMT_API pmt_t nthcdr(size_t n, pmt_t list); + +/*! + * \brief Return the first sublist of \p list whose car is \p obj. + * If \p obj does not occur in \p list, then \#f is returned. + * pmt::memq use pmt::eq to compare \p obj with the elements of \p list. + */ +PMT_API pmt_t memq(pmt_t obj, pmt_t list); + +/*! + * \brief Return the first sublist of \p list whose car is \p obj. + * If \p obj does not occur in \p list, then \#f is returned. + * pmt::memv use pmt::eqv to compare \p obj with the elements of \p list. + */ +PMT_API pmt_t memv(pmt_t obj, pmt_t list); + +/*! + * \brief Return the first sublist of \p list whose car is \p obj. + * If \p obj does not occur in \p list, then \#f is returned. + * pmt::member use pmt::equal to compare \p obj with the elements of \p list. + */ +PMT_API pmt_t member(pmt_t obj, pmt_t list); + +/*! + * \brief Return true if every element of \p list1 appears in \p list2, and false otherwise. + * Comparisons are done with pmt::eqv. + */ +PMT_API bool subsetp(pmt_t list1, pmt_t list2); + +/*! + * \brief Return a list of length 1 containing \p x1 + */ +PMT_API pmt_t list1(const pmt_t& x1); + +/*! + * \brief Return a list of length 2 containing \p x1, \p x2 + */ +PMT_API pmt_t list2(const pmt_t& x1, const pmt_t& x2); + +/*! + * \brief Return a list of length 3 containing \p x1, \p x2, \p x3 + */ +PMT_API pmt_t list3(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3); + +/*! + * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4 + */ +PMT_API pmt_t list4(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4); + +/*! + * \brief Return a list of length 5 containing \p x1, \p x2, \p x3, \p x4, \p x5 + */ +PMT_API pmt_t list5(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5); + +/*! + * \brief Return a list of length 6 containing \p x1, \p x2, \p x3, \p x4, \p + * x5, \p x6 + */ +PMT_API pmt_t list6(const pmt_t& x1, const pmt_t& x2, const pmt_t& x3, const pmt_t& x4, const pmt_t& x5, const pmt_t& x6); + +/*! + * \brief Return \p list with \p item added to it. + */ +PMT_API pmt_t list_add(pmt_t list, const pmt_t& item); + +/*! + * \brief Return \p list with \p item removed from it. + */ +PMT_API pmt_t list_rm(pmt_t list, const pmt_t& item); + +/*! + * \brief Return bool of \p list contains \p item + */ +PMT_API bool list_has(pmt_t list, const pmt_t& item); + + +/* + * ------------------------------------------------------------------------ + * read / write + * ------------------------------------------------------------------------ + */ +extern PMT_API const pmt_t PMT_EOF; //< The end of file object + +//! return true if obj is the EOF object, otherwise return false. +PMT_API bool is_eof_object(pmt_t obj); + +/*! + * read converts external representations of pmt objects into the + * objects themselves. Read returns the next object parsable from + * the given input port, updating port to point to the first + * character past the end of the external representation of the + * object. + * + * If an end of file is encountered in the input before any + * characters are found that can begin an object, then an end of file + * object is returned. The port remains open, and further attempts + * to read will also return an end of file object. If an end of file + * is encountered after the beginning of an object's external + * representation, but the external representation is incomplete and + * therefore not parsable, an error is signaled. + */ +PMT_API pmt_t read(std::istream &port); + +/*! + * Write a written representation of \p obj to the given \p port. + */ +PMT_API void write(pmt_t obj, std::ostream &port); + +/*! + * Return a string representation of \p obj. + * This is the same output as would be generated by pmt::write. + */ +PMT_API std::string write_string(pmt_t obj); + + +PMT_API std::ostream& operator<<(std::ostream &os, pmt_t obj); + +/*! + * \brief Write pmt string representation to stdout. + */ +PMT_API void print(pmt_t v); + + +/* + * ------------------------------------------------------------------------ + * portable byte stream representation + * ------------------------------------------------------------------------ + */ +/*! + * \brief Write portable byte-serial representation of \p obj to \p sink + */ +PMT_API bool serialize(pmt_t obj, std::streambuf &sink); + +/*! + * \brief Create obj from portable byte-serial representation + */ +PMT_API pmt_t deserialize(std::streambuf &source); + + +PMT_API void dump_sizeof(); // debugging + +/*! + * \brief Provide a simple string generating interface to pmt's serialize function + */ +PMT_API std::string serialize_str(pmt_t obj); + +/*! + * \brief Provide a simple string generating interface to pmt's deserialize function + */ +PMT_API pmt_t deserialize_str(std::string str); + +/*! + * \brief Provide a comparator function object to allow pmt use in stl types + */ +class comperator { + public: + bool operator()(pmt::pmt_t const& p1, pmt::pmt_t const& p2) const + { return pmt::eqv(p1,p2)?false:p1.get()>p2.get(); } + }; + +} /* namespace pmt */ + +#include <pmt/pmt_sugar.h> + +#endif /* INCLUDED_PMT_H */ diff --git a/gnuradio-runtime/include/pmt/pmt_pool.h b/gnuradio-runtime/include/pmt/pmt_pool.h new file mode 100644 index 0000000000..a8cb8e6314 --- /dev/null +++ b/gnuradio-runtime/include/pmt/pmt_pool.h @@ -0,0 +1,73 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_PMT_POOL_H +#define INCLUDED_PMT_POOL_H + +#include <pmt/api.h> +#include <cstddef> +#include <vector> +#include <boost/thread.hpp> + +namespace pmt { + +/*! + * \brief very simple thread-safe fixed-size allocation pool + * + * FIXME may want to go to global allocation with per-thread free list. + * This would eliminate virtually all lock contention. + */ +class PMT_API pmt_pool { + + struct PMT_API item { + struct item *d_next; + }; + + typedef boost::unique_lock<boost::mutex> scoped_lock; + mutable boost::mutex d_mutex; + boost::condition_variable d_cond; + + size_t d_itemsize; + size_t d_alignment; + size_t d_allocation_size; + size_t d_max_items; + size_t d_n_items; + item *d_freelist; + std::vector<char *> d_allocations; + +public: + /*! + * \param itemsize size in bytes of the items to be allocated. + * \param alignment alignment in bytes of all objects to be allocated (must be power-of-2). + * \param allocation_size number of bytes to allocate at a time from the underlying allocator. + * \param max_items is the maximum number of items to allocate. If this number is exceeded, + * the allocate blocks. 0 implies no limit. + */ + pmt_pool(size_t itemsize, size_t alignment = 16, + size_t allocation_size = 4096, size_t max_items = 0); + ~pmt_pool(); + + void *malloc(); + void free(void *p); +}; + +} /* namespace pmt */ + +#endif /* INCLUDED_PMT_POOL_H */ diff --git a/gnuradio-runtime/include/pmt/pmt_sugar.h b/gnuradio-runtime/include/pmt/pmt_sugar.h new file mode 100644 index 0000000000..09c9a5e3e4 --- /dev/null +++ b/gnuradio-runtime/include/pmt/pmt_sugar.h @@ -0,0 +1,174 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_PMT_SUGAR_H +#define INCLUDED_PMT_SUGAR_H + +/*! + * This file is included by pmt.h and contains pseudo-constructor + * shorthand for making pmt objects + */ + +#include <messages/msg_accepter.h> + +namespace pmt { + + //! Make pmt symbol + static inline pmt_t + mp(const std::string &s) + { + return string_to_symbol(s); + } + + //! Make pmt symbol + static inline pmt_t + mp(const char *s) + { + return string_to_symbol(s); + } + + //! Make pmt long + static inline pmt_t + mp(long x){ + return from_long(x); + } + + //! Make pmt long + static inline pmt_t + mp(long long unsigned x){ + return from_long(x); + } + + //! Make pmt long + static inline pmt_t + mp(int x){ + return from_long(x); + } + + //! Make pmt double + static inline pmt_t + mp(double x){ + return from_double(x); + } + + //! Make pmt complex + static inline pmt_t + mp(std::complex<double> z) + { + return make_rectangular(z.real(), z.imag()); + } + + //! Make pmt complex + static inline pmt_t + mp(std::complex<float> z) + { + return make_rectangular(z.real(), z.imag()); + } + + //! Make pmt msg_accepter + static inline pmt_t + mp(boost::shared_ptr<gr::messages::msg_accepter> ma) + { + return make_msg_accepter(ma); + } + + //! Make pmt Binary Large Object (BLOB) + static inline pmt_t + mp(const void *data, size_t len_in_bytes) + { + return make_blob(data, len_in_bytes); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0) + { + return make_tuple(e0); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1) + { + return make_tuple(e0, e1); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2) + { + return make_tuple(e0, e1, e2); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3) + { + return make_tuple(e0, e1, e2, e3); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4) + { + return make_tuple(e0, e1, e2, e3, e4); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5) + { + return make_tuple(e0, e1, e2, e3, e4, e5); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6) + { + return make_tuple(e0, e1, e2, e3, e4, e5, e6); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7) + { + return make_tuple(e0, e1, e2, e3, e4, e5, e6, e7); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8) + { + return make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8); + } + + //! Make tuple + static inline pmt_t + mp(const pmt_t &e0, const pmt_t &e1, const pmt_t &e2, const pmt_t &e3, const pmt_t &e4, const pmt_t &e5, const pmt_t &e6, const pmt_t &e7, const pmt_t &e8, const pmt_t &e9) + { + return make_tuple(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9); + } + + +} /* namespace pmt */ + + +#endif /* INCLUDED_PMT_SUGAR_H */ diff --git a/gnuradio-runtime/include/pycallback_object.h b/gnuradio-runtime/include/pycallback_object.h new file mode 100644 index 0000000000..23782a42be --- /dev/null +++ b/gnuradio-runtime/include/pycallback_object.h @@ -0,0 +1,206 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <iostream> +#include <rpcregisterhelpers.h> +#include <ice_application_base.h> +#include <IcePy_Communicator.h> +#include <pythread.h> +#include <boost/format.hpp> + +enum pyport_t { + PYPORT_STRING, + PYPORT_FLOAT +}; + +class Instance +{ +public: + static boost::shared_ptr<ice_application_common> get_application() + { + return ice_application_common::Instance(); + } + static Ice::CommunicatorPtr get_swig_communicator() + { + return get_application()->communicator(); + } +}; + +int pycallback_object_count = 500; + +// a simple to-PMT converter template class-function +template <class myType> class pmt_assist +{ +public: + static pmt::pmt_t make(myType _val) + { + return pmt::mp(_val); + } +}; + +/* template specializations for vectors that cant use pmt::mp() */ +template<> +pmt::pmt_t pmt_assist<std::vector<float> >::make(std::vector<float> _val) +{ + return pmt::init_f32vector(_val.size(), &_val[0]); +} + +template<> +pmt::pmt_t pmt_assist<std::vector<gr_complex> >::make(std::vector<gr_complex> _val) +{ + return pmt::init_c32vector(_val.size(), &_val[0]); +} + +template <class myType> class pycallback_object +{ +public: + pycallback_object(std::string name, std::string functionbase, + std::string units, std::string desc, + myType min, myType max, myType deflt, + DisplayType dtype) : + d_callback(NULL), + d_functionbase(functionbase), d_units(units), d_desc(desc), + d_min(min), d_max(max), d_deflt(deflt), d_dtype(dtype), + d_name(name), d_id(pycallback_object_count++) + { + d_callback = NULL; + setup_rpc(); + } + + void add_rpc_variable(rpcbasic_sptr s) + { + d_rpc_vars.push_back(s); + } + + myType get() { + myType rVal; + if(d_callback == NULL) { + printf("WARNING: pycallback_object get() called without py callback set!\n"); + return rVal; + } + else { + // obtain PyGIL + PyGILState_STATE state = PyGILState_Ensure(); + + PyObject *func; + //PyObject *arglist; + PyObject *result; + + func = (PyObject *) d_callback; // Get Python function + //arglist = Py_BuildValue(""); // Build argument list + result = PyEval_CallObject(func,NULL); // Call Python + //result = PyEval_CallObject(func,arglist); // Call Python + //Py_DECREF(arglist); // Trash arglist + if(result) { // If no errors, return double + rVal = pyCast(result); + } + Py_XDECREF(result); + + // release PyGIL + PyGILState_Release(state); + return rVal; + } + } + + void set_callback(PyObject *cb) + { + d_callback = cb; + } + + void setup_rpc() + { +#ifdef GR_CTRLPORT + add_rpc_variable( + rpcbasic_sptr(new rpcbasic_register_get<pycallback_object, myType>( + (boost::format("%s%d") % d_name % d_id).str() , d_functionbase.c_str(), + this, &pycallback_object::get, pmt_assist<myType>::make(d_min), + pmt_assist<myType>::make(d_max), pmt_assist<myType>::make(d_deflt), + d_units.c_str(), d_desc.c_str(), RPC_PRIVLVL_MIN, d_dtype))); +#endif /* GR_CTRLPORT */ + } + +private: + PyObject* d_callback; + std::string d_functionbase, d_units, d_desc; + myType d_min, d_max, d_deflt; + DisplayType d_dtype; + + myType pyCast(PyObject* obj) { + printf("TYPE NOT IMPLEMENTED!\n"); + assert(0); + }; + std::vector<boost::any> d_rpc_vars; // container for all RPC variables + std::string d_name; + int d_id; + +}; + + +// template specialization conversion functions +// get data out of the PyObject and into the real world +template<> +std::string pycallback_object<std::string>::pyCast(PyObject* obj) +{ + return std::string(PyString_AsString(obj)); +} + +template<> +double pycallback_object<double>::pyCast(PyObject* obj) +{ + return PyFloat_AsDouble(obj); +} + +template<> +float pycallback_object<float>::pyCast(PyObject* obj) +{ + return (float)PyFloat_AsDouble(obj); +} + +template<> +int pycallback_object<int>::pyCast(PyObject* obj) +{ + return PyInt_AsLong(obj); +} + +template<> +std::vector<float> pycallback_object<std::vector<float> >::pyCast(PyObject* obj) +{ + int size = PyObject_Size(obj); + std::vector<float> rval(size); + for(int i=0; i<size; i++) { + rval[i] = (float)PyFloat_AsDouble(PyList_GetItem(obj, i)); + } + return rval; +} + +template<> +std::vector<gr_complex> pycallback_object<std::vector<gr_complex> >::pyCast(PyObject* obj) +{ + int size = PyObject_Size(obj); + std::vector<gr_complex> rval(size); + for(int i=0; i<size; i++){ rval[i] = \ + gr_complex((float)PyComplex_RealAsDouble(PyList_GetItem(obj, i)), + (float)PyComplex_ImagAsDouble(PyList_GetItem(obj, i))); + } + return rval; +} +// TODO: add more template specializations as needed! diff --git a/gnuradio-runtime/include/random.h b/gnuradio-runtime/include/random.h new file mode 100644 index 0000000000..c643c3e422 --- /dev/null +++ b/gnuradio-runtime/include/random.h @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003, 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _RANDOM_H_ +#define _RANDOM_H_ + +// While rand(3) specifies RAND_MAX, random(3) says that the output +// ranges from 0 to 2^31-1 but does not specify a macro to denote +// this. We define RANDOM_MAX for cleanliness. We must omit the +// definition for systems that have made the same choice. (Note that +// random(3) is from 4.2BSD, and not specified by POSIX.) + +#ifndef RANDOM_MAX +static const int RANDOM_MAX = 2147483647; // 2^31-1 +#endif /* RANDOM_MAX */ + +#include <stdlib.h> + +#endif // _RANDOM_H_ diff --git a/gnuradio-runtime/include/realtime.h b/gnuradio-runtime/include/realtime.h new file mode 100644 index 0000000000..9a51a6ba1d --- /dev/null +++ b/gnuradio-runtime/include/realtime.h @@ -0,0 +1,96 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GNURADIO_REALTIME_H +#define INCLUDED_GNURADIO_REALTIME_H + +#include <gr_runtime_api.h> +#include <stdexcept> + +/*! + * \brief System independent way to ask for realtime scheduling + * + * \sa sys_pri.h + */ + +namespace gr { + + typedef enum { + RT_OK = 0, + RT_NOT_IMPLEMENTED, + RT_NO_PRIVS, + RT_OTHER_ERROR + } rt_status_t; + + + enum rt_sched_policy { + RT_SCHED_RR = 0, // round robin + RT_SCHED_FIFO = 1, // first in first out + }; + + /* + * Define the range for our virtual priorities (don't change these) + * + * Processes (or threads) with numerically higher priority values + * are scheduled before processes with numerically lower priority + * values. Thus, the value returned by rt_priority_max() will be + * greater than the value returned by rt_priority_min(). + */ + static inline int rt_priority_min() { return 0; } + static inline int rt_priority_max() { return 15; } + static inline int rt_priority_default() { return 1; } + + struct GR_RUNTIME_API rt_sched_param { + int priority; + rt_sched_policy policy; + + rt_sched_param() + : priority(rt_priority_default()), policy(RT_SCHED_RR){} + + rt_sched_param(int priority_, rt_sched_policy policy_ = RT_SCHED_RR) + { + if (priority_ < rt_priority_min() || priority_ > rt_priority_max()) + throw std::invalid_argument("rt_sched_param: priority out of range"); + + priority = priority_; + policy = policy_; + } + }; + + /*! + * \brief If possible, enable "realtime" scheduling. + * \ingroup misc + * + * In general, this means that the code will be scheduled before any + * non-realtime (normal) processes. Note that if your code contains + * an non-blocking infinite loop and you enable realtime scheduling, + * it's possible to hang the system. + */ + + // NOTE: If you change this, you need to change the code in + // gnuradio-core/src/lib/runtime/gr_realtime.i, see note there. + rt_status_t + GR_RUNTIME_API enable_realtime_scheduling(rt_sched_param = rt_sched_param()); + +} // namespace gr + +#endif /* INCLUDED_GNURADIO_REALTIME_H */ diff --git a/gnuradio-runtime/include/rpccallbackregister_base.h b/gnuradio-runtime/include/rpccallbackregister_base.h new file mode 100644 index 0000000000..f2cd1d8051 --- /dev/null +++ b/gnuradio-runtime/include/rpccallbackregister_base.h @@ -0,0 +1,105 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCCALLBACKREGISTER_BASE_H +#define RPCCALLBACKREGISTER_BASE_H + +#include <messages/msg_accepter.h> +#include <messages/msg_producer.h> + +typedef uint32_t DisplayType; + +// DisplayType Plotting types +const uint32_t DISPNULL = 0x0000; +const uint32_t DISPTIME = 0x0001; +const uint32_t DISPXY = 0x0002; +const uint32_t DISPPSD = 0x0004; +const uint32_t DISPSPEC = 0x0008; +const uint32_t DISPRAST = 0x0010; + +// DisplayType Options +const uint32_t DISPOPTCPLX = 0x0100; +const uint32_t DISPOPTLOG = 0x0200; +const uint32_t DISPOPTSTEM = 0x0400; +const uint32_t DISPOPTSTRIP = 0x0800; +const uint32_t DISPOPTSCATTER = 0x1000; + +enum priv_lvl_t { + RPC_PRIVLVL_ALL = 0, + RPC_PRIVLVL_MIN = 9, + RPC_PRIVLVL_NONE = 10 +}; + +enum KnobType { + KNOBBOOL, KNOBCHAR, KNOBINT, KNOBFLOAT, + KNOBDOUBLE, KNOBSTRING, KNOBLONG, KNOBVECBOOL, + KNOBVECCHAR, KNOBVECINT, KNOBVECFLOAT, KNOBVECDOUBLE, + KNOBVECSTRING, KNOBVECLONG +}; + +struct callbackregister_base +{ + struct callback_base_t + { + public: + callback_base_t(const priv_lvl_t priv_, const std::string& units_, + const DisplayType display_, const std::string& desc_, + const pmt::pmt_t min_, const pmt::pmt_t max_, const pmt::pmt_t def) + : priv(priv_), units(units_), description(desc_), + min(min_), max(max_), defaultvalue(def), display(display_) + { + } + + priv_lvl_t priv; + std::string units, description; + pmt::pmt_t min, max, defaultvalue; + DisplayType display; + }; + + template<typename T, typename Tsptr> + class callback_t : public callback_base_t + { + public: + callback_t(T* callback_, priv_lvl_t priv_, + const std::string& units_, const DisplayType display_, const:: std::string& desc_, + const pmt::pmt_t& min_, const pmt::pmt_t& max_, const pmt::pmt_t& def_) : + callback_base_t(priv_, units_, display_, desc_, min_, max_, def_), + callback(callback_) + { + } + + Tsptr callback; + }; + + typedef callback_t<gr::messages::msg_accepter, gr::messages::msg_accepter_sptr> configureCallback_t; + typedef callback_t<gr::messages::msg_producer, gr::messages::msg_producer_sptr> queryCallback_t; + + callbackregister_base() {;} + virtual ~callbackregister_base() {;} + + virtual void registerConfigureCallback(const std::string &id, const configureCallback_t callback) = 0; + virtual void unregisterConfigureCallback(const std::string &id) = 0; + virtual void registerQueryCallback(const std::string &id, const queryCallback_t callback) = 0; + virtual void unregisterQueryCallback(const std::string &id) = 0; +}; + +#endif /* RPCCALLBACKREGISTER_BASE_H */ diff --git a/gnuradio-runtime/include/rpcmanager.h b/gnuradio-runtime/include/rpcmanager.h new file mode 100644 index 0000000000..6e1e181c3c --- /dev/null +++ b/gnuradio-runtime/include/rpcmanager.h @@ -0,0 +1,59 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCMANAGER_H +#define RPCMANAGER_H + +#include <gr_runtime_api.h> +#include <rpcmanager_base.h> +#include <rpcserver_booter_aggregator.h> +#include <memory> +#include <iostream> + +class GR_RUNTIME_API rpcmanager : public virtual rpcmanager_base +{ + public: + rpcmanager(); + ~rpcmanager(); + + static rpcserver_booter_base* get(); + + static void register_booter(rpcserver_booter_base* booter); + + template<typename T> class rpcserver_booter_register_helper + { + public: + rpcserver_booter_register_helper() { + rpcmanager::register_booter(new T()); + } + + //TODO: unregister + }; + + private: + static bool make_aggregator, booter_registered, aggregator_registered; + static void rpcserver_booter_base_sptr_dest( rpcserver_booter_base* b) {;} + static rpcserver_booter_base* boot; + static std::auto_ptr<rpcserver_booter_aggregator> aggregator; +}; + +#endif /* RPCMANAGER_H */ diff --git a/gnuradio-runtime/include/rpcmanager_base.h b/gnuradio-runtime/include/rpcmanager_base.h new file mode 100644 index 0000000000..60425c4a15 --- /dev/null +++ b/gnuradio-runtime/include/rpcmanager_base.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCMANAGER_BASE_H +#define RPCMANAGER_BASE_H + +#include <boost/shared_ptr.hpp> + +class rpcserver_booter_base; +//class rpcserver_booter_aggregator; + +class rpcmanager_base +{ + public: + typedef boost::shared_ptr<rpcserver_booter_base> rpcserver_booter_base_sptr; + + rpcmanager_base() {;} + ~rpcmanager_base() {;} + + //static rpcserver_booter_base* get(); + + //static void register_booter(rpcserver_booter_base_sptr booter); + +private: +}; + +#endif /* RPCMANAGER_BASE_H */ diff --git a/gnuradio-runtime/include/rpcpmtconverters_ice.h b/gnuradio-runtime/include/rpcpmtconverters_ice.h new file mode 100644 index 0000000000..e592f4cdfb --- /dev/null +++ b/gnuradio-runtime/include/rpcpmtconverters_ice.h @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCPMTCONVERTERS_ICE_H +#define RPCPMTCONVERTERS_ICE_H + +#include <pmt/pmt.h> +#include <gnuradio.h> + +namespace rpcpmtconverter +{ + pmt::pmt_t to_pmt(const GNURadio::KnobPtr& knob, const Ice::Current& c); + GNURadio::KnobPtr from_pmt(const pmt::pmt_t& knob, const Ice::Current& c); +} + +#endif /* RPCPMTCONVERTERS_ICE_H */ diff --git a/gnuradio-runtime/include/rpcregisterhelpers.h b/gnuradio-runtime/include/rpcregisterhelpers.h new file mode 100644 index 0000000000..b09aae9704 --- /dev/null +++ b/gnuradio-runtime/include/rpcregisterhelpers.h @@ -0,0 +1,659 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCREGISTERHELPERS_H +#define RPCREGISTERHELPERS_H + +#include <stdio.h> +#include <sstream> +#include <iostream> +#include <rpcserver_booter_base.h> +#include <rpcmanager.h> +#include <rpcserver_selector.h> +#include <rpcserver_base.h> +#include <gr_block_registry.h> + +// Base classes +template<typename T, typename Tto> class rpcextractor_base + : public virtual gr::messages::msg_accepter +{ +public: + rpcextractor_base(T* source, void (T::*func)(Tto)) : + _source(source), _func(func) {;} + ~rpcextractor_base() {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) { + throw std::runtime_error("rpcextractor_base: no post defined for this data type.\n"); + } + +protected: + T* _source; + void (T::*_func)(Tto); +}; + +template<typename T, typename Tto> +class rpcbasic_extractor : public virtual rpcextractor_base<T,Tto> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(Tto)) : + rpcextractor_base<T,Tto>(source, func) + {;} +}; + +template<typename T, typename Tfrom> +class rpcinserter_base : public virtual gr::messages::msg_producer +{ +public: + rpcinserter_base(T* source, Tfrom (T::*func)()) : _source(source), _func(func) {;} + rpcinserter_base() {;} + + pmt::pmt_t retrieve() { assert(0); return pmt::pmt_t(); } + +protected: + T* _source; + Tfrom (T::*_func)(); +}; + +template<typename T, typename Tfrom> +class rpcbasic_inserter : + public virtual rpcinserter_base<T,Tfrom> +{ +public: + rpcbasic_inserter(T* source, Tfrom (T::*func)()const) + : rpcinserter_base<T,Tfrom>(source, func) + {;} + + rpcbasic_inserter(T* source, Tfrom (T::*func)()) + : rpcinserter_base<T,Tfrom>(source, func) + {;} + + pmt::pmt_t retrieve() + { + return pmt::mp((rpcinserter_base<T,Tfrom>:: + _source->*rpcinserter_base<T,Tfrom>::_func)()); + } +}; + +// Specialized Extractor Templates +template<typename T> +class rpcbasic_extractor<T,double> : public virtual rpcextractor_base<T,double> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(double)) + : rpcextractor_base<T,double>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,double>::_source->*rpcextractor_base<T,double>::_func) + (pmt::to_double(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,float> : public virtual rpcextractor_base<T,float> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(float)) + : rpcextractor_base<T,float>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,float>::_source->*rpcextractor_base<T,float>::_func) + (pmt::to_double(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,long> : public virtual rpcextractor_base<T,long> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(long)) + : rpcextractor_base<T,long>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,long>::_source->*rpcextractor_base<T,long>::_func) + (pmt::to_long(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,int> : public virtual rpcextractor_base<T,int> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(int)) + : rpcextractor_base<T,int>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,int>::_source->*rpcextractor_base<T,int>::_func) + (pmt::to_long(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,bool> : public virtual rpcextractor_base<T,bool> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(bool)) + : rpcextractor_base<T,bool>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,bool>::_source->*rpcextractor_base<T,bool>::_func) + (pmt::to_bool(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,std::complex<double> > + : public virtual rpcextractor_base<T,std::complex<double> > +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(std::complex<double>)) + : rpcextractor_base<T,std::complex<double> >(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,std::complex<double> >:: + _source->*rpcextractor_base<T,std::complex<double> >::_func)(pmt::to_complex(msg)); + } +}; + +template<typename T> +class rpcbasic_extractor<T,std::string> + : public virtual rpcextractor_base<T,std::string> +{ +public: + rpcbasic_extractor(T* source, void (T::*func)(std::string)) + : rpcextractor_base<T,std::string>(source, func) + {;} + + void post(pmt::pmt_t which_port, pmt::pmt_t msg) + { + (rpcextractor_base<T,std::string>:: + _source->*rpcextractor_base<T,std::string>::_func)(pmt::symbol_to_string(msg)); + } +}; + +template<typename T> +class rpcbasic_inserter<T,uint64_t> : public virtual rpcinserter_base<T,uint64_t> +{ +public: + rpcbasic_inserter(T* source, uint64_t (T::*func)() const) + : rpcinserter_base<T,uint64_t>(source, func) + {;} + + rpcbasic_inserter(T* source, uint64_t (T::*func)()) + : rpcinserter_base<T,uint64_t>(source, func) + {;} + + pmt::pmt_t retrieve() + { + return pmt::from_uint64((rpcinserter_base<T,uint64_t>:: + _source->*rpcinserter_base<T,uint64_t>::_func)()); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< int > > + : public virtual rpcinserter_base<T,std::vector< int > > +{ +public: + rpcbasic_inserter(T* source, std::vector<int > (T::*func)() const) + : rpcinserter_base<T,std::vector<int > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<int > (T::*func)()) + : rpcinserter_base<T,std::vector<int > >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< int > + vec((rpcinserter_base<T,std::vector<int > >:: + _source->*rpcinserter_base<T,std::vector< int > >::_func)()); + return pmt::init_s32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< std::complex<float> > > + : public virtual rpcinserter_base<T,std::vector< std::complex<float> > > +{ +public: + rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)() const) + : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<std::complex<float> > (T::*func)()) + : rpcinserter_base<T,std::vector<std::complex<float> > >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< std::complex<float> > + vec((rpcinserter_base<T,std::vector<std::complex<float> > >:: + _source->*rpcinserter_base<T,std::vector< std::complex<float> > >::_func)()); + return pmt::init_c32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< float> > + : public virtual rpcinserter_base<T,std::vector< float > > +{ +public: + rpcbasic_inserter(T* source, std::vector<float> (T::*func)() const) + : rpcinserter_base<T,std::vector<float > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<float> (T::*func)()) + : rpcinserter_base<T,std::vector<float> >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< float > vec((rpcinserter_base<T,std::vector<float> >:: + _source->*rpcinserter_base<T,std::vector< float> >::_func)()); + return pmt::init_f32vector(vec.size(), &vec[0]); + } +}; + +template<typename T> +class rpcbasic_inserter<T,std::vector< uint8_t> > + : public virtual rpcinserter_base<T,std::vector< uint8_t > > { +public: + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)() const) + : rpcinserter_base<T,std::vector<uint8_t > >(source, func) + {;} + + rpcbasic_inserter(T* source, std::vector<uint8_t> (T::*func)()) + : rpcinserter_base<T,std::vector<uint8_t> >(source, func) + {;} + + pmt::pmt_t retrieve() + { + std::vector< uint8_t > vec((rpcinserter_base<T,std::vector<uint8_t> >:: + _source->*rpcinserter_base<T,std::vector< uint8_t> >::_func)()); + return pmt::init_u8vector(vec.size(), &vec[0]); + } +}; + +template <typename T> +struct rpc_register_base +{ + rpc_register_base() {count++;} +protected: static int count; +}; + +// Base class to inherit from and create universal shared pointers. +class rpcbasic_base +{ +public: + rpcbasic_base() {} + virtual ~rpcbasic_base() {}; +}; + +typedef boost::shared_ptr<rpcbasic_base> rpcbasic_sptr; + +template<typename T, typename Tto> +struct rpcbasic_register_set : public rpcbasic_base +{ + // Function used to add a 'set' RPC call using a gr_basic_block's alias. + rpcbasic_register_set(const std::string& block_alias, + const char* functionbase, + void (T::*function)(Tto), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + minpriv_, std::string(units_), + display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + // Function used to add a 'set' RPC call using a name and the object + rpcbasic_register_set(const std::string& name, + const char* functionbase, + T* obj, + void (T::*function)(Tto), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::configureCallback_t + extractor(new rpcbasic_extractor<T,Tto>(d_object, function), + minpriv_, std::string(units_), + display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING SET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerConfigureCallback(d_id, extractor); +#endif + } + + ~rpcbasic_register_set() + { +#ifdef RPCSERVER_ENABLED + rpcmanager::get()->i()->unregisterConfigureCallback(d_id); +#endif + } + + + pmt::pmt_t min() const { return d_min; } + pmt::pmt_t max() const { return d_max; } + pmt::pmt_t def() const { return d_def; } + std::string units() const { return d_units; } + std::string description() const { return d_desc; } + priv_lvl_t privilege_level() const { return d_minpriv; } + DisplayType default_display() const { return d_display; } + + void set_min(pmt::pmt_t p) { d_min = p; } + void set_max(pmt::pmt_t p) { d_max = p; } + void set_def(pmt::pmt_t p) { d_def = p; } + void units(std::string u) { d_units = u; } + void description(std::string d) { d_desc = d; } + void privilege_level(priv_lvl_t p) { d_minpriv = p; } + void default_display(DisplayType d) { d_display = d; } + +private: + std::string d_id; + pmt::pmt_t d_min, d_max, d_def; + std::string d_units, d_desc; + priv_lvl_t d_minpriv; + DisplayType d_display; + T *d_object; +}; + + +template<typename T, typename Tfrom> +class rpcbasic_register_get : public rpcbasic_base +{ +public: + // Function used to add a 'set' RPC call using a gr_basic_block's alias. + // primary constructor to allow for T get() functions + rpcbasic_register_get(const std::string& block_alias, + const char* functionbase, + Tfrom (T::*function)(), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + + // alternate constructor to allow for T get() const functions + rpcbasic_register_get(const std::string& block_alias, + const char* functionbase, + Tfrom (T::*function)() const, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = dynamic_cast<T*>(global_block_registry.block_lookup(pmt::intern(block_alias)).get()); +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << block_alias << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + // Function used to add a 'set' RPC call using a name and the object + // primary constructor to allow for T get() functions + rpcbasic_register_get(const std::string& name, + const char* functionbase, + T* obj, + Tfrom (T::*function)(), + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET: " << d_id << " " << desc_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + + // alternate constructor to allow for T get() const functions + rpcbasic_register_get(const std::string& name, + const char* functionbase, + T* obj, + Tfrom (T::*function)() const, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_ = DISPNULL) + { + d_min = min; + d_max = max; + d_def = def; + d_units = units_; + d_desc = desc_; + d_minpriv = minpriv_; + d_display = display_; + d_object = obj; +#ifdef RPCSERVER_ENABLED + callbackregister_base::queryCallback_t + inserter(new rpcbasic_inserter<T,Tfrom>(d_object, (Tfrom (T::*)())function), + minpriv_, std::string(units_), display_, std::string(desc_), min, max, def); + std::ostringstream oss(std::ostringstream::out); + oss << name << "::" << functionbase; + d_id = oss.str(); + //std::cerr << "REGISTERING GET CONST: " << d_id << " " << desc_ << " " << display_ << std::endl; + rpcmanager::get()->i()->registerQueryCallback(d_id, inserter); +#endif + } + + ~rpcbasic_register_get() + { +#ifdef RPCSERVER_ENABLED + rpcmanager::get()->i()->unregisterQueryCallback(d_id); +#endif + } + + pmt::pmt_t min() const { return d_min; } + pmt::pmt_t max() const { return d_max; } + pmt::pmt_t def() const { return d_def; } + std::string units() const { return d_units; } + std::string description() const { return d_desc; } + priv_lvl_t privilege_level() const { return d_minpriv; } + DisplayType default_display() const { return d_display; } + + void set_min(pmt::pmt_t p) { d_min = p; } + void set_max(pmt::pmt_t p) { d_max = p; } + void set_def(pmt::pmt_t p) { d_def = p; } + void units(std::string u) { d_units = u; } + void description(std::string d) { d_desc = d; } + void privilege_level(priv_lvl_t p) { d_minpriv = p; } + void default_display(DisplayType d) { d_display = d; } + +private: + std::string d_id; + pmt::pmt_t d_min, d_max, d_def; + std::string d_units, d_desc; + priv_lvl_t d_minpriv; + DisplayType d_display; + T *d_object; +}; + +/* + * This class can wrap a pre-existing variable type for you + * it will define the getter and rpcregister call for you. + * + * It should be used for read-only getters. + * + */ +template<typename Tfrom> +class rpcbasic_register_variable : public rpcbasic_base +{ +protected: + rpcbasic_register_get< rpcbasic_register_variable<Tfrom>, Tfrom > d_rpc_reg; + Tfrom *d_variable; + Tfrom get() { return *d_variable; } +public: + // empty constructor which should never be called but needs to exist for ues in varous STL data structures + void setptr(Tfrom* _variable){ rpcbasic_register_variable<Tfrom>::d_variable = _variable; } + rpcbasic_register_variable() : + d_rpc_reg("FAIL", "FAIL", this, &rpcbasic_register_variable::get, + pmt::PMT_NIL, pmt::PMT_NIL, pmt::PMT_NIL, DISPNULL, + "FAIL", "FAIL", RPC_PRIVLVL_MIN), + d_variable(NULL) + { + throw std::runtime_error("ERROR: rpcbasic_register_variable called with no args. If this happens, someone has tried to use rpcbasic_register_variable incorrectly."); + }; + + rpcbasic_register_variable(const std::string& namebase, + const char* functionbase, + Tfrom *variable, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv_ = RPC_PRIVLVL_MIN, + DisplayType display_=DISPNULL) : + d_rpc_reg(namebase, functionbase, this, &rpcbasic_register_variable::get, + min, max, def, units_, desc_, minpriv_, display_), + d_variable(variable) + { + //std::cerr << "REGISTERING VAR: " << " " << desc_ << std::endl; + } +}; + +template<typename Tfrom> class rpcbasic_register_variable_rw : public rpcbasic_register_variable<Tfrom> { + private: + rpcbasic_register_set< rpcbasic_register_variable_rw<Tfrom>, Tfrom > d_rpc_regset; + public: + // empty constructor which should never be called but needs to exist for ues in varous STL data structures + rpcbasic_register_variable_rw() : + d_rpc_regset("FAIL","FAIL",this,&rpcbasic_register_variable<Tfrom>::get,pmt::PMT_NIL,pmt::PMT_NIL,pmt::PMT_NIL,DISPNULL,"FAIL","FAIL",RPC_PRIVLVL_MIN) + { + throw std::runtime_error("ERROR: rpcbasic_register_variable_rw called with no args. if this happens someone used rpcbasic_register_variable_rw incorrectly.\n"); + }; + void set(Tfrom _variable){ *(rpcbasic_register_variable<Tfrom>::d_variable) = _variable; } + rpcbasic_register_variable_rw( + const std::string& namebase, + const char* functionbase, + Tfrom *variable, + const pmt::pmt_t &min, const pmt::pmt_t &max, const pmt::pmt_t &def, + const char* units_ = "", + const char* desc_ = "", + priv_lvl_t minpriv = RPC_PRIVLVL_MIN, + DisplayType display_=DISPNULL) : + rpcbasic_register_variable<Tfrom>(namebase,functionbase,variable,min,max,def,units_,desc_), + d_rpc_regset(namebase,functionbase,this,&rpcbasic_register_variable_rw::set,min,max,def,units_,desc_,minpriv,display_) + { + // no action + } +}; + + + + +#endif diff --git a/gnuradio-runtime/include/rpcserver_aggregator.h b/gnuradio-runtime/include/rpcserver_aggregator.h new file mode 100644 index 0000000000..050d9bb1e5 --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_aggregator.h @@ -0,0 +1,100 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_AGGREGATOR_H +#define RPCSERVER_AGGREGATOR_H + +#include <vector> +#include <string> +#include <rpcserver_base.h> +#include <rpcmanager_base.h> + +class rpcserver_aggregator : public virtual rpcserver_base +{ +public: + rpcserver_aggregator(); + virtual ~rpcserver_aggregator(); + + void registerConfigureCallback(const std::string &id, const configureCallback_t callback); + void unregisterConfigureCallback(const std::string &id); + + void registerQueryCallback(const std::string &id, const queryCallback_t callback); + void unregisterQueryCallback(const std::string &id); + + void registerServer(rpcmanager_base::rpcserver_booter_base_sptr server); + + const std::string& type(); + + const std::vector<std::string>& registeredServers(); + +private: + template<class T, typename Tcallback> + struct registerConfigureCallback_f: public std::unary_function<T,void> + { + registerConfigureCallback_f(const std::string &_id, const Tcallback _callback) + : id(_id), callback(_callback) + {;} + + void operator()(T& x) { x->i()->registerConfigureCallback(id, callback); } + const std::string& id; const Tcallback& callback; + }; + + template<class T, typename Tcallback> + struct unregisterConfigureCallback_f: public std::unary_function<T,void> + { + unregisterConfigureCallback_f(const std::string &_id) + : id(_id) + {;} + + void operator()(T& x) { x->i()->unregisterConfigureCallback(id); } + const std::string& id; + }; + + template<class T, typename Tcallback> + struct registerQueryCallback_f: public std::unary_function<T,void> + { + registerQueryCallback_f(const std::string &_id, const Tcallback _callback) + : id(_id), callback(_callback) + {;} + + void operator()(T& x) { x->i()->registerQueryCallback(id, callback); } + const std::string& id; const Tcallback& callback; + }; + + template<class T, typename Tcallback> + struct unregisterQueryCallback_f: public std::unary_function<T,void> + { + unregisterQueryCallback_f(const std::string &_id) + : id(_id) + {;} + + void operator()(T& x) { x->i()->unregisterQueryCallback(id); } + const std::string& id; + }; + + const std::string d_type; + typedef std::vector<rpcmanager_base::rpcserver_booter_base_sptr> rpcServerMap_t; + std::vector<std::string> d_registeredServers; + rpcServerMap_t d_serverlist; +}; + +#endif /* RPCSERVER_AGGREGATOR_H */ diff --git a/gnuradio-runtime/include/rpcserver_base.h b/gnuradio-runtime/include/rpcserver_base.h new file mode 100644 index 0000000000..bc985c8d53 --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_base.h @@ -0,0 +1,47 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BASE_H +#define RPCSERVER_BASE_H + +#include <rpccallbackregister_base.h> + +class rpcserver_base : public virtual callbackregister_base +{ +public: + rpcserver_base() : cur_priv(RPC_PRIVLVL_ALL) {;} + virtual ~rpcserver_base() {;} + + virtual void registerConfigureCallback(const std::string &id, const configureCallback_t callback) = 0; + virtual void unregisterConfigureCallback(const std::string &id) = 0; + virtual void registerQueryCallback(const std::string &id, const queryCallback_t callback) = 0; + virtual void unregisterQueryCallback(const std::string &id) = 0; + virtual void setCurPrivLevel(const priv_lvl_t priv) { cur_priv = priv; } + + typedef boost::shared_ptr<rpcserver_base> rpcserver_base_sptr; +protected: + priv_lvl_t cur_priv; + +private: +}; + +#endif /* RPCSERVER_BASE_H */ diff --git a/gnuradio-runtime/include/rpcserver_booter_aggregator.h b/gnuradio-runtime/include/rpcserver_booter_aggregator.h new file mode 100644 index 0000000000..38739a1b50 --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_booter_aggregator.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_AGGREGATOR +#define RPCSERVER_BOOTER_AGGREGATOR + +#include <gr_runtime_api.h> +#include <rpcserver_booter_base.h> +#include <rpcserver_aggregator.h> +#include <boost/shared_ptr.hpp> +#include <string> + +class rpcserver_server; + +class GR_RUNTIME_API rpcserver_booter_aggregator : + public virtual rpcserver_booter_base +{ + public: + rpcserver_booter_aggregator(); + ~rpcserver_booter_aggregator(); + + rpcserver_base* i(); + const std::string& type(); + const std::vector<std::string> endpoints(); + + const std::vector<std::string>& registeredServers(); + + protected: + friend class rpcmanager; + rpcserver_aggregator* agg(); + +private: + std::string d_type; + boost::shared_ptr<rpcserver_aggregator> server; +}; + +#endif /* RPCSERVER_BOOTER_AGGREGATOR */ diff --git a/gnuradio-runtime/include/rpcserver_booter_base.h b/gnuradio-runtime/include/rpcserver_booter_base.h new file mode 100644 index 0000000000..682944dada --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_booter_base.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_BASE +#define RPCSERVER_BOOTER_BASE + +#include <string> +#include <vector> + +class rpcserver_base; + +class rpcserver_booter_base +{ +public: + rpcserver_booter_base() {;} + virtual ~rpcserver_booter_base() {;} + + virtual rpcserver_base* i()=0; + virtual const std::vector<std::string> endpoints()=0; + virtual const std::string& type()=0; + +private: +}; + +#endif /* RPCSERVER_BOOTER_BASE */ diff --git a/gnuradio-runtime/include/rpcserver_booter_ice.h b/gnuradio-runtime/include/rpcserver_booter_ice.h new file mode 100644 index 0000000000..69dfcc7602 --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_booter_ice.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_BOOTER_ICE_H +#define RPCSERVER_BOOTER_ICE_H + +#include <rpcserver_booter_base.h> +#include <ice_server_template.h> +#include <gnuradio.h> + +class rpcserver_base; +class rpcserver_ice; + +class rpcserver_booter_ice : public virtual rpcserver_booter_base, + public virtual ice_server_template<rpcserver_base, rpcserver_ice, + rpcserver_booter_ice, GNURadio::ControlPortPtr> +{ +public: + rpcserver_booter_ice(); + ~rpcserver_booter_ice(); + + rpcserver_base* i(); + const std::string & type() {return d_type;} + const std::vector<std::string> endpoints(); + +private: + std::string d_type; +}; + +#endif /* RPCSERVER_BOOTER_ICE_H */ diff --git a/gnuradio-runtime/include/rpcserver_ice.h b/gnuradio-runtime/include/rpcserver_ice.h new file mode 100644 index 0000000000..2c08f57dc7 --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_ice.h @@ -0,0 +1,226 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_ICE_H +#define RPCSERVER_ICE_H + +#include <rpcserver_base.h> +#include <rpcpmtconverters_ice.h> +#include <string> +#include <sstream> +#include <map> +#include <gnuradio.h> +#include <Ice/Exception.h> +#include <boost/format.hpp> + +class rpcserver_ice : public virtual rpcserver_base, public GNURadio::ControlPort +{ +public: + rpcserver_ice(); + virtual ~rpcserver_ice(); + + void registerConfigureCallback(const std::string &id, const configureCallback_t callback); + void unregisterConfigureCallback(const std::string &id); + + void registerQueryCallback(const std::string &id, const queryCallback_t callback); + void unregisterQueryCallback(const std::string &id); + + virtual void set(const GNURadio::KnobMap&, const Ice::Current&); + + GNURadio::KnobMap get(const GNURadio::KnobIDList&, const Ice::Current&); + + GNURadio::KnobPropMap properties(const GNURadio::KnobIDList&, const Ice::Current&); + + virtual void shutdown(const Ice::Current&); + +private: + typedef std::map<std::string, configureCallback_t> ConfigureCallbackMap_t; + ConfigureCallbackMap_t d_setcallbackmap; + + typedef std::map<std::string, queryCallback_t> QueryCallbackMap_t; + QueryCallbackMap_t d_getcallbackmap; + + template<typename T, typename TMap> struct set_f + : public std::unary_function<T,void> + { + set_f(const Ice::Current& _c, TMap& _setcallbackmap, const priv_lvl_t& _cur_priv) : + c(_c), d_setcallbackmap(_setcallbackmap), cur_priv(_cur_priv) + {;} + + void operator()(const T& p) + { + ConfigureCallbackMap_t::const_iterator iter(d_setcallbackmap.find(p.first)); + if(iter != d_setcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + (*iter->second.callback).post(pmt::PMT_NIL, rpcpmtconverter::to_pmt(p.second,c)); + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << iter->second.priv << " to set, currently at: " + << cur_priv << std::endl; + } + } + else { + throw IceUtil::NullHandleException(__FILE__, __LINE__); + } + } + + const Ice::Current& c; + TMap& d_setcallbackmap; + const priv_lvl_t& cur_priv; + }; + + template<typename T, typename TMap> + struct get_f : public std::unary_function<T,void> + { + get_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, GNURadio::KnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {} + + void operator()(const T& p) + { + QueryCallbackMap_t::const_iterator iter(d_getcallbackmap.find(p)); + if(iter != d_getcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + outknobs[p] = rpcpmtconverter::from_pmt((*iter->second.callback).retrieve(), c); + } + else { + std::cout << "Key " << iter->first << " requires PRIVLVL: <= " + << iter->second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + else { + std::stringstream ss; + ss << "Ctrlport Key called with unregistered key (" << p << ")\n"; + std::cout << ss.str(); + throw IceUtil::IllegalArgumentException(__FILE__,__LINE__,ss.str().c_str()); + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + GNURadio::KnobMap& outknobs; + }; + + template<typename T, typename TMap, typename TKnobMap> + struct get_all_f : public std::unary_function<T,void> + { + get_all_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, TKnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + if(cur_priv <= p.second.priv) { + outknobs[p.first] = rpcpmtconverter::from_pmt(p.second.callback->retrieve(), c); + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << p.second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; + + template<typename T, typename TMap, typename TKnobMap> + struct properties_all_f : public std::unary_function<T,void> + { + properties_all_f(const Ice::Current& _c, QueryCallbackMap_t& _getcallbackmap, + const priv_lvl_t& _cur_priv, GNURadio::KnobPropMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + if(cur_priv <= p.second.priv) { + GNURadio::KnobProp prop;//(new GNURadio::KnobProp()); + prop.type = GNURadio::KNOBDOUBLE; + prop.units = p.second.units; + prop.description = p.second.description; + prop.min = rpcpmtconverter::from_pmt(p.second.min, c); + prop.max = rpcpmtconverter::from_pmt(p.second.max, c); + prop.display = static_cast<uint32_t>(p.second.display); + outknobs[p.first] = prop; + } + else { + std::cout << "Key " << p.first << " requires PRIVLVL <= " + << p.second.priv << " to get, currently at: " + << cur_priv << std::endl; + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; + + template<class T, typename TMap, typename TKnobMap> + struct properties_f : public std::unary_function<T,void> + { + properties_f(const Ice::Current& _c, TMap& _getcallbackmap, + const priv_lvl_t& _cur_priv, TKnobMap& _outknobs) : + c(_c), d_getcallbackmap(_getcallbackmap), cur_priv(_cur_priv), outknobs(_outknobs) + {;} + + void operator()(const T& p) + { + typename TMap::const_iterator iter(d_getcallbackmap.find(p)); + if(iter != d_getcallbackmap.end()) { + if(cur_priv <= iter->second.priv) { + GNURadio::KnobProp prop; + prop.type = GNURadio::KNOBDOUBLE; + prop.units = iter->second.units; + prop.description = iter->second.description; + prop.min = rpcpmtconverter::from_pmt(iter->second.min, c); + prop.max = rpcpmtconverter::from_pmt(iter->second.max, c); + prop.display = static_cast<uint32_t>(iter->second.display); + //outknobs[iter->first] = prop; + outknobs[p] = prop; + } + else { + std::cout << "Key " << iter->first << " requires PRIVLVL: <= " << + iter->second.priv << " to get, currently at: " << cur_priv << std::endl; + } + } + else { + throw IceUtil::NullHandleException(__FILE__, __LINE__); + } + } + + const Ice::Current& c; + TMap& d_getcallbackmap; + const priv_lvl_t& cur_priv; + TKnobMap& outknobs; + }; +}; + +#endif /* RPCSERVER_ICE_H */ diff --git a/gnuradio-runtime/include/rpcserver_selector.h b/gnuradio-runtime/include/rpcserver_selector.h new file mode 100644 index 0000000000..fa63c9a2dc --- /dev/null +++ b/gnuradio-runtime/include/rpcserver_selector.h @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef RPCSERVER_SELECTOR +#define RPCSERVER_SELECTOR + +#define RPCSERVER_ENABLED + +#define RPCSERVER_ICE +//#define RPCSERVER_ERLANG +//#define RPCSERVER_XMLRPC + +#endif diff --git a/gnuradio-runtime/include/runtime_block_gateway.h b/gnuradio-runtime/include/runtime_block_gateway.h new file mode 100644 index 0000000000..390864376f --- /dev/null +++ b/gnuradio-runtime/include/runtime_block_gateway.h @@ -0,0 +1,265 @@ +/* + * Copyright 2011-2012 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_RUNTIME_BLOCK_GATEWAY_H +#define INCLUDED_RUNTIME_BLOCK_GATEWAY_H + +#include <gr_runtime_api.h> +#include <gr_block.h> +#include <gr_feval.h> + +/*! + * The work type enum tells the gateway what kind of block to implement. + * The choices are familiar gnuradio block overloads (sync, decim, interp). + */ +enum gr_block_gw_work_type{ + GR_BLOCK_GW_WORK_GENERAL, + GR_BLOCK_GW_WORK_SYNC, + GR_BLOCK_GW_WORK_DECIM, + GR_BLOCK_GW_WORK_INTERP, +}; + +/*! + * Shared message structure between python and gateway. + * Each action type represents a scheduler-called function. + */ +struct gr_block_gw_message_type{ + enum action_type{ + ACTION_GENERAL_WORK, //dispatch work + ACTION_WORK, //dispatch work + ACTION_FORECAST, //dispatch forecast + ACTION_START, //dispatch start + ACTION_STOP, //dispatch stop + }; + + action_type action; + + int general_work_args_noutput_items; + std::vector<int> general_work_args_ninput_items; + std::vector<void *> general_work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> general_work_args_output_items; + int general_work_args_return_value; + + int work_args_ninput_items; + int work_args_noutput_items; + std::vector<void *> work_args_input_items; //TODO this should be const void*, but swig cant int cast it right + std::vector<void *> work_args_output_items; + int work_args_return_value; + + int forecast_args_noutput_items; + std::vector<int> forecast_args_ninput_items_required; + + bool start_args_return_value; + + bool stop_args_return_value; +}; + +/*! + * The gateway block which performs all the magic. + * + * The gateway provides access to all the gr_block routines. + * The methods prefixed with gr_block__ are renamed + * to class methods without the prefix in python. + */ +class GR_RUNTIME_API runtime_block_gateway : virtual public gr_block{ +public: + //! Provide access to the shared message object + virtual gr_block_gw_message_type &gr_block_message(void) = 0; + + long gr_block__unique_id(void) const{ + return gr_block::unique_id(); + } + + std::string gr_block__name(void) const{ + return gr_block::name(); + } + + unsigned gr_block__history(void) const{ + return gr_block::history(); + } + + void gr_block__set_history(unsigned history){ + return gr_block::set_history(history); + } + + void gr_block__set_fixed_rate(bool fixed_rate){ + return gr_block::set_fixed_rate(fixed_rate); + } + + bool gr_block__fixed_rate(void) const{ + return gr_block::fixed_rate(); + } + + void gr_block__set_output_multiple(int multiple){ + return gr_block::set_output_multiple(multiple); + } + + int gr_block__output_multiple(void) const{ + return gr_block::output_multiple(); + } + + void gr_block__consume(int which_input, int how_many_items){ + return gr_block::consume(which_input, how_many_items); + } + + void gr_block__consume_each(int how_many_items){ + return gr_block::consume_each(how_many_items); + } + + void gr_block__produce(int which_output, int how_many_items){ + return gr_block::produce(which_output, how_many_items); + } + + void gr_block__set_relative_rate(double relative_rate){ + return gr_block::set_relative_rate(relative_rate); + } + + double gr_block__relative_rate(void) const{ + return gr_block::relative_rate(); + } + + uint64_t gr_block__nitems_read(unsigned int which_input){ + return gr_block::nitems_read(which_input); + } + + uint64_t gr_block__nitems_written(unsigned int which_output){ + return gr_block::nitems_written(which_output); + } + + gr_block::tag_propagation_policy_t gr_block__tag_propagation_policy(void){ + return gr_block::tag_propagation_policy(); + } + + void gr_block__set_tag_propagation_policy(gr_block::tag_propagation_policy_t p){ + return gr_block::set_tag_propagation_policy(p); + } + + void gr_block__add_item_tag( + unsigned int which_output, const gr_tag_t &tag + ){ + return gr_block::add_item_tag(which_output, tag); + } + + void gr_block__add_item_tag( + unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F + ){ + return gr_block::add_item_tag(which_output, abs_offset, key, value, srcid); + } + + std::vector<gr_tag_t> gr_block__get_tags_in_range( + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end + ){ + std::vector<gr_tag_t> tags; + gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end); + return tags; + } + + std::vector<gr_tag_t> gr_block__get_tags_in_range( + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key + ){ + std::vector<gr_tag_t> tags; + gr_block::get_tags_in_range(tags, which_input, abs_start, abs_end, key); + return tags; + } + + /* Message passing interface */ + void gr_block__message_port_register_in(pmt::pmt_t port_id){ + gr_basic_block::message_port_register_in(port_id); + } + + void gr_block__message_port_register_out(pmt::pmt_t port_id){ + gr_basic_block::message_port_register_out(port_id); + } + + void gr_block__message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg){ + gr_basic_block::message_port_pub(port_id, msg); + } + + void gr_block__message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){ + gr_basic_block::message_port_sub(port_id, target); + } + + void gr_block__message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target){ + gr_basic_block::message_port_unsub(port_id, target); + } + + pmt::pmt_t gr_block__message_ports_in(){ + return gr_basic_block::message_ports_in(); + } + + pmt::pmt_t gr_block__message_ports_out(){ + return gr_basic_block::message_ports_out(); + } + + void set_msg_handler_feval(pmt::pmt_t which_port, gr_feval_p *msg_handler) + { + if(msg_queue.find(which_port) == msg_queue.end()){ + throw std::runtime_error("attempt to set_msg_handler_feval() on bad input message port!"); + } + d_msg_handlers_feval[which_port] = msg_handler; + } + +protected: + typedef std::map<pmt::pmt_t, gr_feval_p *, pmt::comperator> msg_handlers_feval_t; + msg_handlers_feval_t d_msg_handlers_feval; + + void dispatch_msg(pmt::pmt_t which_port, pmt::pmt_t msg){ + // Is there a handler? + if (d_msg_handlers_feval.find(which_port) != d_msg_handlers_feval.end()){ + d_msg_handlers_feval[which_port]->calleval(msg); // Yes, invoke it. + } + else { + // Pass to generic dispatcher if not found + gr_basic_block::dispatch_msg(which_port, msg); + } + } +}; + +/*! + * Make a new gateway block. + * \param handler the swig director object with callback + * \param name the name of the block (Ex: "Shirley") + * \param in_sig the input signature for this block + * \param out_sig the output signature for this block + * \param work_type the type of block overload to implement + * \param factor the decimation or interpolation factor + * \return a new gateway block + */ +GR_RUNTIME_API boost::shared_ptr<runtime_block_gateway> +runtime_make_block_gateway( + gr_feval_ll *handler, + const std::string &name, + gr_io_signature_sptr in_sig, + gr_io_signature_sptr out_sig, + const gr_block_gw_work_type work_type, + const unsigned factor +); + +#endif /* INCLUDED_RUNTIME_BLOCK_GATEWAY_H */ diff --git a/gnuradio-runtime/include/sys_pri.h b/gnuradio-runtime/include/sys_pri.h new file mode 100644 index 0000000000..745176e681 --- /dev/null +++ b/gnuradio-runtime/include/sys_pri.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GNURADIO_SYS_PRI_H +#define INCLUDED_GNURADIO_SYS_PRI_H + +#include <gr_runtime_api.h> +#include <realtime.h> + +/* + * A single place to define real-time priorities used by the system itself + */ +namespace gr { + + struct GR_RUNTIME_API sys_pri { + static rt_sched_param python(); // python code + static rt_sched_param normal(); // normal blocks + static rt_sched_param gcell_event_handler(); + static rt_sched_param usrp2_backend(); // thread that services the ethernet + }; + +} /* namespace gr */ + +#endif /* INCLUDED_GNURADIO_SYS_PRI_H */ diff --git a/gnuradio-runtime/include/thread/CMakeLists.txt b/gnuradio-runtime/include/thread/CMakeLists.txt new file mode 100644 index 0000000000..8ea4bfc66e --- /dev/null +++ b/gnuradio-runtime/include/thread/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright 2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. + +######################################################################## +# Install header files +######################################################################## +install(FILES + thread.h + thread_body_wrapper.h + thread_group.h + DESTINATION ${GR_INCLUDE_DIR}/gnuradio/thread + COMPONENT "runtime_devel" +) diff --git a/gnuradio-runtime/include/thread/thread.h b/gnuradio-runtime/include/thread/thread.h new file mode 100644 index 0000000000..548d76e9a5 --- /dev/null +++ b/gnuradio-runtime/include/thread/thread.h @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_THREAD_H +#define INCLUDED_THREAD_H + +#include <gr_runtime_api.h> +#include <boost/thread/thread.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/condition_variable.hpp> +#include <vector> + +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#include <windows.h> + +#endif + +namespace gr { + namespace thread { + + typedef boost::thread thread; + typedef boost::mutex mutex; + typedef boost::unique_lock<boost::mutex> scoped_lock; + typedef boost::condition_variable condition_variable; + + /*! \brief a system-dependent typedef for the underlying thread type. + */ +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + typedef HANDLE gr_thread_t; +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) + typedef pthread_t gr_thread_t; +#else + typedef pthread_t gr_thread_t; +#endif + + /*! \brief Get the current thread's ID as a gr_thread_t + * + * We use this when setting the thread affinity or any other + * low-level thread settings. Can be called withing a GNU Radio + * block to get a reference to its current thread ID. + */ + GR_RUNTIME_API gr_thread_t get_current_thread_id(); + + /*! \brief Bind the current thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number + * from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(const std::vector<int> &mask); + + /*! \brief Convineince function to bind the current thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * current thread to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(int n); + + /*! \brief Bind a thread to a set of cores. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to the processor mask. The mask is simply a + * 1-demensional vector containing the processor or core number + * from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread, + const std::vector<int> &mask); + + + /*! \brief Convineince function to bind the a thread to a single core. + * + * Wrapper for system-dependent calls to set the affinity of the + * given thread ID to a given core from 0 to N-1 for N cores. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread, + unsigned int n); + + /*! \brief Remove any thread-processor affinity for the current thread. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_unbind(); + + /*! \brief Remove any thread-processor affinity for a given thread ID. + * + * Note: this does not work on OSX; it is a nop call since OSX + * does not support the concept of thread affinity (and what they + * do support in this way since 10.5 is not what we want or can + * use in this fashion). + */ + GR_RUNTIME_API void thread_unbind(gr_thread_t thread); + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_H */ diff --git a/gnuradio-runtime/include/thread/thread_body_wrapper.h b/gnuradio-runtime/include/thread/thread_body_wrapper.h new file mode 100644 index 0000000000..dcf8cff48e --- /dev/null +++ b/gnuradio-runtime/include/thread/thread_body_wrapper.h @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_THREAD_BODY_WRAPPER_H +#define INCLUDED_THREAD_BODY_WRAPPER_H + +#include <gr_runtime_api.h> +#include <thread/thread.h> +#include <exception> +#include <iostream> + +namespace gr { + namespace thread { + + GR_RUNTIME_API void mask_signals(); + + template <class F> + class thread_body_wrapper + { + private: + F d_f; + std::string d_name; + + public: + explicit thread_body_wrapper(F f, const std::string &name="") + : d_f(f), d_name(name) {} + + void operator()() + { + mask_signals(); + + try { + d_f(); + } + catch(boost::thread_interrupted const &) + { + } + catch(std::exception const &e) + { + std::cerr << "thread[" << d_name << "]: " + << e.what() << std::endl; + } + catch(...) + { + std::cerr << "thread[" << d_name << "]: " + << "caught unrecognized exception\n"; + } + } + }; + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_BODY_WRAPPER_H */ diff --git a/gnuradio-runtime/include/thread/thread_group.h b/gnuradio-runtime/include/thread/thread_group.h new file mode 100644 index 0000000000..81b561bd64 --- /dev/null +++ b/gnuradio-runtime/include/thread/thread_group.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2001-2003 William E. Kempf + * Copyright (C) 2007 Anthony Williams + * Copyright 2008,2009 Free Software Foundation, Inc. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +/* + * This was extracted from Boost 1.35.0 and fixed. + */ + +#ifndef INCLUDED_THREAD_GROUP_H +#define INCLUDED_THREAD_GROUP_H + +#include <gr_runtime_api.h> +#include <thread/thread.h> +#include <boost/utility.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/function.hpp> + +namespace gr { + namespace thread { + + class GR_RUNTIME_API thread_group : public boost::noncopyable + { + public: + thread_group(); + ~thread_group(); + + boost::thread* create_thread(const boost::function0<void>& threadfunc); + void add_thread(boost::thread* thrd); + void remove_thread(boost::thread* thrd); + void join_all(); + void interrupt_all(); + size_t size() const; + + private: + std::list<boost::thread*> m_threads; + mutable boost::shared_mutex m_mutex; + }; + + } /* namespace thread */ +} /* namespace gr */ + +#endif /* INCLUDED_THREAD_GROUP_H */ |