summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib/runtime')
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am109
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc131
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h247
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc108
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h99
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.i66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.cc248
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.h196
-rw-r--r--gnuradio-core/src/lib/runtime/gr_buffer.i63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_complex.h46
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.cc192
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_dispatcher.i55
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.cc244
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.h114
-rw-r--r--gnuradio-core/src/lib/runtime/gr_error_handler.i69
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.cc54
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_io_signature.i49
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.cc186
-rw-r--r--gnuradio-core/src/lib/runtime/gr_local_sighandler.h60
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.cc77
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.h89
-rw-r--r--gnuradio-core/src/lib/runtime/gr_message.i65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.cc30
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.h41
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_handler.i32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.cc127
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.h89
-rw-r--r--gnuradio-core/src/lib/runtime/gr_msg_queue.i111
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.cc56
-rw-r--r--gnuradio-core/src/lib/runtime/gr_pagesize.h32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.cc101
-rw-r--r--gnuradio-core/src/lib/runtime/gr_preferences.h32
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.cc71
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.h39
-rw-r--r--gnuradio-core/src/lib/runtime/gr_realtime.i4
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.h44
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.cc36
-rw-r--r--gnuradio-core/src/lib/runtime/gr_select_handler.h83
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc360
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h61
-rw-r--r--gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_swig_block_magic.i45
-rw-r--r--gnuradio-core/src/lib/runtime/gr_timer.h82
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tmp_path.cc52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_tmp_path.h31
-rw-r--r--gnuradio-core/src/lib/runtime/gr_types.h63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc291
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf.h120
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc191
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc205
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc198
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h65
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc192
-rw-r--r--gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h65
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.cc89
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.h48
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_buffer.cc307
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_buffer.h53
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc55
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_io_signature.h47
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc40
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h39
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.cc49
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.h37
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i49
-rw-r--r--gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc53
71 files changed, 6771 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
new file mode 100644
index 0000000000..7ee94ba1b8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -0,0 +1,109 @@
+#
+# Copyright 2003,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 2, 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+
+include $(top_srcdir)/Makefile.common
+
+INCLUDES = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES)
+
+noinst_LTLIBRARIES = libruntime.la libruntime-qa.la
+
+libruntime_la_LIBADD = \
+ $(SHM_OPEN_LIBS)
+
+
+libruntime_la_SOURCES = \
+ gr_block.cc \
+ gr_block_detail.cc \
+ gr_buffer.cc \
+ gr_dispatcher.cc \
+ gr_error_handler.cc \
+ gr_io_signature.cc \
+ gr_local_sighandler.cc \
+ gr_message.cc \
+ gr_msg_handler.cc \
+ gr_msg_queue.cc \
+ gr_pagesize.cc \
+ gr_preferences.cc \
+ gr_realtime.cc \
+ gr_single_threaded_scheduler.cc \
+ gr_tmp_path.cc \
+ gr_vmcircbuf.cc \
+ gr_vmcircbuf_mmap_shm_open.cc \
+ gr_vmcircbuf_mmap_tmpfile.cc \
+ gr_vmcircbuf_createfilemapping.cc \
+ gr_vmcircbuf_sysv_shm.cc \
+ gr_select_handler.cc
+
+libruntime_qa_la_SOURCES = \
+ qa_gr_block.cc \
+ qa_gr_buffer.cc \
+ qa_gr_io_signature.cc \
+ qa_gr_vmcircbuf.cc \
+ qa_runtime.cc
+
+grinclude_HEADERS = \
+ gr_block.h \
+ gr_block_detail.h \
+ gr_buffer.h \
+ gr_complex.h \
+ gr_dispatcher.h \
+ gr_error_handler.h \
+ gr_io_signature.h \
+ gr_local_sighandler.h \
+ gr_message.h \
+ gr_msg_handler.h \
+ gr_msg_queue.h \
+ gr_pagesize.h \
+ gr_preferences.h \
+ gr_realtime.h \
+ gr_runtime.h \
+ gr_select_handler.h \
+ gr_single_threaded_scheduler.h \
+ gr_timer.h \
+ gr_tmp_path.h \
+ gr_types.h \
+ gr_vmcircbuf.h
+
+noinst_HEADERS = \
+ gr_vmcircbuf_mmap_shm_open.h \
+ gr_vmcircbuf_mmap_tmpfile.h \
+ gr_vmcircbuf_sysv_shm.h \
+ gr_vmcircbuf_createfilemapping.h \
+ qa_gr_block.h \
+ qa_gr_buffer.h \
+ qa_gr_io_signature.h \
+ qa_gr_vmcircbuf.h \
+ qa_runtime.h
+
+swiginclude_HEADERS = \
+ gr_block.i \
+ gr_block_detail.i \
+ gr_buffer.i \
+ gr_dispatcher.i \
+ gr_error_handler.i \
+ gr_io_signature.i \
+ gr_message.i \
+ gr_msg_handler.i \
+ gr_msg_queue.i \
+ gr_realtime.i \
+ gr_single_threaded_scheduler.i \
+ gr_swig_block_magic.i \
+ runtime.i
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
new file mode 100644
index 0000000000..8378c8f7de
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -0,0 +1,131 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <stdexcept>
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_block::gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : d_name (name),
+ d_input_signature (input_signature),
+ d_output_signature (output_signature),
+ d_output_multiple (1),
+ d_relative_rate (1.0),
+ d_unique_id (s_next_id++),
+ d_history(1),
+ d_fixed_rate(false)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_block::~gr_block ()
+{
+ s_ncurrently_allocated--;
+}
+
+// stub implementation: 1:1
+
+void
+gr_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
+{
+ unsigned ninputs = ninput_items_required.size ();
+ for (unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items;
+}
+
+// default implementation
+
+bool
+gr_block::check_topology (int ninputs, int noutputs)
+{
+ return true;
+}
+
+bool
+gr_block::start()
+{
+ return true;
+}
+
+bool
+gr_block::stop()
+{
+ return true;
+}
+
+void
+gr_block::set_output_multiple (int multiple)
+{
+ if (multiple < 1)
+ throw std::invalid_argument ("gr_block::set_output_multiple");
+
+ d_output_multiple = multiple;
+}
+
+void
+gr_block::set_relative_rate (double relative_rate)
+{
+ if (relative_rate < 0.0)
+ throw std::invalid_argument ("gr_block::set_relative_rate");
+
+ d_relative_rate = relative_rate;
+}
+
+
+void
+gr_block::consume (int which_input, int how_many_items)
+{
+ d_detail->consume (which_input, how_many_items);
+}
+
+void
+gr_block::consume_each (int how_many_items)
+{
+ d_detail->consume_each (how_many_items);
+}
+
+int
+gr_block::fixed_rate_ninput_to_noutput(int ninput)
+{
+ throw std::runtime_error("Unimplemented");
+}
+
+int
+gr_block::fixed_rate_noutput_to_ninput(int noutput)
+{
+ throw std::runtime_error("Unimplemented");
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
new file mode 100644
index 0000000000..df72e1a3fd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -0,0 +1,247 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_H
+#define INCLUDED_GR_BLOCK_H
+
+#include <gr_runtime.h>
+#include <string>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup block
+ *
+ * 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_block {
+
+ public:
+
+ virtual ~gr_block ();
+
+ std::string name () const { return d_name; }
+ gr_io_signature_sptr input_signature () const { return d_input_signature; }
+ gr_io_signature_sptr output_signature () const { return d_output_signature; }
+ long unique_id () const { return d_unique_id; }
+
+ /*!
+ * 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) = 0;
+
+ /*!
+ * \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);
+
+ /*!
+ * \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; }
+
+ /*!
+ * \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 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);
+
+ // ----------------------------------------------------------------------------
+
+ private:
+
+ std::string d_name;
+ gr_io_signature_sptr d_input_signature;
+ gr_io_signature_sptr d_output_signature;
+ int d_output_multiple;
+ double d_relative_rate; // approx output_rate / input_rate
+ gr_block_detail_sptr d_detail; // implementation details
+ long d_unique_id; // convenient for debugging
+ unsigned d_history;
+ bool d_fixed_rate;
+
+
+ protected:
+
+ gr_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;
+ }
+
+ void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
+
+ // These are really only for internal use, but leaving them public avoids
+ // having to work up an ever-varying list of friends
+
+ public:
+ gr_block_detail_sptr detail () const { return d_detail; }
+ void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+long gr_block_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
new file mode 100644
index 0000000000..f1f0332e85
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_block;
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+%template(gr_block_sptr) boost::shared_ptr<gr_block>;
+
+// support vectors of these...
+namespace std {
+ %template(x_vector_gr_block_sptr) vector<gr_block_sptr>;
+};
+
+class gr_block {
+ protected:
+ gr_block (const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ public:
+
+ virtual ~gr_block ();
+
+ std::string name () const;
+ gr_io_signature_sptr input_signature () const;
+ gr_io_signature_sptr output_signature () const;
+ long unique_id () const;
+ unsigned history () const;
+
+ int output_multiple () const;
+ double relative_rate () const;
+
+ bool check_topology (int ninputs, int noutputs);
+ bool start();
+ bool stop();
+
+ // internal use
+ gr_block_detail_sptr detail () const { return d_detail; }
+ void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
+};
+
+%rename(block_ncurrently_allocated) gr_block_ncurrently_allocated;
+long gr_block_ncurrently_allocated ();
+
+%pythoncode %{
+gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+gr_block_sptr.block = lambda self: self
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
new file mode 100644
index 0000000000..0ad5da49ce
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -0,0 +1,108 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+
+static long s_ncurrently_allocated = 0;
+
+long
+gr_block_detail_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
+ : d_ninputs (ninputs), d_noutputs (noutputs),
+ d_input (ninputs), d_output (noutputs),
+ d_done (false)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_block_detail::~gr_block_detail ()
+{
+ // should take care of itself
+ s_ncurrently_allocated--;
+}
+
+void
+gr_block_detail::set_input (unsigned int which, gr_buffer_reader_sptr reader)
+{
+ if (which >= d_ninputs)
+ throw std::invalid_argument ("gr_block_detail::set_input");
+
+ d_input[which] = reader;
+}
+
+void
+gr_block_detail::set_output (unsigned int which, gr_buffer_sptr buffer)
+{
+ if (which >= d_noutputs)
+ throw std::invalid_argument ("gr_block_detail::set_output");
+
+ d_output[which] = buffer;
+}
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs)
+{
+ return gr_block_detail_sptr (new gr_block_detail (ninputs, noutputs));
+}
+
+void
+gr_block_detail::set_done (bool done)
+{
+ d_done = done;
+ for (unsigned int i = 0; i < d_noutputs; i++)
+ d_output[i]->set_done (done);
+
+ for (unsigned int i = 0; i < d_ninputs; i++)
+ d_input[i]->set_done (done);
+}
+
+void
+gr_block_detail::consume (int which_input, int how_many_items)
+{
+ if (how_many_items > 0)
+ input (which_input)->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::consume_each (int how_many_items)
+{
+ if (how_many_items > 0)
+ for (int i = 0; i < ninputs (); i++)
+ d_input[i]->update_read_pointer (how_many_items);
+}
+
+void
+gr_block_detail::produce_each (int how_many_items)
+{
+ if (how_many_items > 0)
+ for (int i = 0; i < noutputs (); i++)
+ d_output[i]->update_write_pointer (how_many_items);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
new file mode 100644
index 0000000000..90c912c25a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -0,0 +1,99 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BLOCK_DETAIL_H
+#define INCLUDED_GR_BLOCK_DETAIL_H
+
+#include <gr_runtime.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_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);
+
+ void produce_each (int how_many_items);
+
+ // ----------------------------------------------------------------------------
+
+ 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;
+
+ gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+ friend gr_block_detail_sptr
+ gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+};
+
+gr_block_detail_sptr
+gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+long
+gr_block_detail_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_BLOCK_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.i b/gnuradio-core/src/lib/runtime/gr_block_detail.i
new file mode 100644
index 0000000000..9d3843ebe7
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.i
@@ -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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_block_detail;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+%template(gr_block_detail_sptr) boost::shared_ptr<gr_block_detail>;
+%rename(block_detail) gr_make_block_detail;
+%ignore gr_block_detail;
+
+gr_block_detail_sptr gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+class 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_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];
+ }
+
+ // ----------------------------------------------------------------------------
+
+ private:
+ gr_block_detail (unsigned int ninputs, unsigned int noutputs);
+
+};
+
+
+%rename(block_detail_ncurrently_allocated) gr_block_detail_ncurrently_allocated;
+long gr_block_detail_ncurrently_allocated ();
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc
new file mode 100644
index 0000000000..d3d1230967
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc
@@ -0,0 +1,248 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_buffer.h>
+#include <gr_vmcircbuf.h>
+#include <gr_math.h>
+#include <stdexcept>
+#include <iostream>
+#include <assert.h>
+#include <algorithm>
+
+static long s_buffer_count = 0; // counts for debugging storage mgmt
+static long s_buffer_reader_count = 0;
+
+// ----------------------------------------------------------------------------
+// Notes on storage management
+//
+// Pretty much all the fundamental classes are now using the
+// shared_ptr stuff for automatic reference counting. To ensure that
+// no mistakes are made, we make the constructors for classes private,
+// and then provide a free factory function that returns a smart
+// pointer to the desired class.
+//
+// gr_buffer and gr_buffer_reader are no exceptions. However, they
+// both want pointers to each other, and unless we do something, we'll
+// never delete any of them because of the circular structure.
+// They'll always have a reference count of at least one. We could
+// use boost::weak_ptr's from gr_buffer to gr_buffer_reader but that
+// introduces it's own problems. (gr_buffer_reader's destructor needs
+// to call gr_buffer::drop_reader, but has no easy way to get a
+// shared_ptr to itself.)
+//
+// Instead, we solve this problem by having gr_buffer hold a raw
+// pointer to gr_buffer_reader in its d_reader vector.
+// gr_buffer_reader's destructor calls gr_buffer::drop_reader, so
+// we're never left with an dangling pointer. gr_buffer_reader still
+// has a shared_ptr to the buffer ensuring that the buffer doesn't go
+// away under it. However, when the reference count of a
+// gr_buffer_reader goes to zero, we can successfully reclaim it.
+// ----------------------------------------------------------------------------
+
+
+/*
+ * Compute the minimum number of buffer items that work (i.e.,
+ * address space wrap-around works). To work is to satisfy this
+ * contraint for integer buffer_size and k:
+ *
+ * type_size * nitems == k * page_size
+ */
+static long
+minimum_buffer_items (long type_size, long page_size)
+{
+ return page_size / gr_gcd (type_size, page_size);
+}
+
+
+gr_buffer::gr_buffer (int nitems, size_t sizeof_item)
+ : d_base (0), d_bufsize (0), d_vmcircbuf (0),
+ d_sizeof_item (sizeof_item), d_write_index (0),
+ d_done (false)
+{
+ if (!allocate_buffer (nitems, sizeof_item))
+ throw std::bad_alloc ();
+
+ s_buffer_count++;
+}
+
+gr_buffer_sptr
+gr_make_buffer (int nitems, size_t sizeof_item)
+{
+ return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item));
+}
+
+gr_buffer::~gr_buffer ()
+{
+ delete d_vmcircbuf;
+ assert (d_readers.size() == 0);
+ s_buffer_count--;
+}
+
+/*!
+ * sets d_vmcircbuf, d_base, d_bufsize.
+ * returns true iff successful.
+ */
+bool
+gr_buffer::allocate_buffer (int nitems, size_t sizeof_item)
+{
+ int orig_nitems = nitems;
+
+ // Any buffersize we come up with must be a multiple of min_nitems.
+
+ int granularity = gr_vmcircbuf_sysconfig::granularity ();
+ int min_nitems = minimum_buffer_items (sizeof_item, granularity);
+
+ // Round-up nitems to a multiple of min_nitems.
+
+ if (nitems % min_nitems != 0)
+ nitems = ((nitems / min_nitems) + 1) * min_nitems;
+
+ // If we rounded-up a whole bunch, give the user a heads up.
+ // This only happens if sizeof_item is not a power of two.
+
+ if (nitems > 2 * orig_nitems && nitems * (int) sizeof_item > granularity){
+ std::cerr << "gr_buffer::allocate_buffer: warning: tried to allocate\n"
+ << " " << orig_nitems << " items of size "
+ << sizeof_item << ". Due to alignment requirements\n"
+ << " " << nitems << " were allocated. If this isn't OK, consider padding\n"
+ << " your structure to a power-of-two bytes.\n"
+ << " On this platform, our allocation granularity is " << granularity << " bytes.\n";
+ }
+
+ d_bufsize = nitems;
+ d_vmcircbuf = gr_vmcircbuf_sysconfig::make (d_bufsize * d_sizeof_item);
+ if (d_vmcircbuf == 0){
+ std::cerr << "gr_buffer::allocate_buffer: failed to allocate buffer of size "
+ << d_bufsize * d_sizeof_item / 1024 << " KB\n";
+ return false;
+ }
+
+ d_base = (char *) d_vmcircbuf->pointer_to_first_copy ();
+ return true;
+}
+
+
+int
+gr_buffer::space_available () const
+{
+ if (d_readers.empty ())
+ return d_bufsize - 1; // See comment below
+
+ else {
+
+ // Find out the maximum amount of data available to our readers
+
+ int most_data = d_readers[0]->items_available ();
+ for (unsigned int i = 1; i < d_readers.size (); i++)
+ most_data = std::max (most_data, d_readers[i]->items_available ());
+
+ // The -1 ensures that the case d_write_index == d_read_index is
+ // unambiguous. It indicates that there is no data for the reader
+
+ return d_bufsize - most_data - 1;
+ }
+}
+
+void *
+gr_buffer::write_pointer ()
+{
+ return &d_base[d_write_index * d_sizeof_item];
+}
+
+void
+gr_buffer::update_write_pointer (int nitems)
+{
+ d_write_index = index_add (d_write_index, nitems);
+}
+
+gr_buffer_reader_sptr
+gr_buffer_add_reader (gr_buffer_sptr buf, int history)
+{
+ gr_buffer_reader_sptr r (new gr_buffer_reader (buf,
+ buf->index_sub(buf->d_write_index,
+ history-1)));
+ buf->d_readers.push_back (r.get ());
+
+ return r;
+}
+
+void
+gr_buffer::drop_reader (gr_buffer_reader *reader)
+{
+ // isn't C++ beautiful... GAG!
+
+ std::vector<gr_buffer_reader *>::iterator result =
+ std::find (d_readers.begin (), d_readers.end (), reader);
+
+ if (result == d_readers.end ())
+ throw std::invalid_argument ("gr_buffer::drop_reader"); // we didn't find it...
+
+ d_readers.erase (result);
+}
+
+long
+gr_buffer_ncurrently_allocated ()
+{
+ return s_buffer_count;
+}
+
+// ----------------------------------------------------------------------------
+
+gr_buffer_reader::gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index)
+ : d_buffer (buffer), d_read_index (read_index)
+{
+ s_buffer_reader_count++;
+}
+
+gr_buffer_reader::~gr_buffer_reader ()
+{
+ d_buffer->drop_reader(this);
+ s_buffer_reader_count--;
+}
+
+int
+gr_buffer_reader::items_available () const
+{
+ return d_buffer->index_sub (d_buffer->d_write_index, d_read_index);
+}
+
+const void *
+gr_buffer_reader::read_pointer ()
+{
+ return &d_buffer->d_base[d_read_index * d_buffer->d_sizeof_item];
+}
+
+void
+gr_buffer_reader::update_read_pointer (int nitems)
+{
+ d_read_index = d_buffer->index_add (d_read_index, nitems);
+}
+
+long
+gr_buffer_reader_ncurrently_allocated ()
+{
+ return s_buffer_reader_count;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h
new file mode 100644
index 0000000000..6f85f275ee
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.h
@@ -0,0 +1,196 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_BUFFER_H
+#define INCLUDED_GR_BUFFER_H
+
+#include <gr_runtime.h>
+
+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.
+ */
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+
+/*!
+ * \brief Single writer, multiple reader fifo.
+ * \ingroup internal
+ */
+class gr_buffer {
+ public:
+ virtual ~gr_buffer ();
+
+ /*!
+ * \brief return number of items worth of space available for writing
+ */
+ int space_available () const;
+
+ /*!
+ * \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) { d_done = done; }
+ bool done () const { return d_done; }
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer_reader;
+ friend gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+ friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+ 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
+ unsigned int d_write_index; // in items [0,d_bufsize)
+ std::vector<gr_buffer_reader *> d_readers;
+ bool d_done;
+
+ 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.
+ *
+ * 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);
+
+ /*!
+ * \brief disassociate \p reader from this buffer
+ */
+ void drop_reader (gr_buffer_reader *reader);
+
+};
+
+//! create a new gr_buffer_reader and attach it to buffer \p buf
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+//! returns # of gr_buffers currently allocated
+long gr_buffer_ncurrently_allocated ();
+
+
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief How we keep track of the readers of a gr_buffer.
+ * \ingroup internal
+ */
+
+class gr_buffer_reader {
+
+ public:
+ ~gr_buffer_reader ();
+
+ /*!
+ * \brief Return number of items available for reading.
+ */
+ int items_available () const;
+
+ /*!
+ * \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 (); }
+
+ // -------------------------------------------------------------------------
+
+ private:
+
+ friend class gr_buffer;
+ friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+
+ gr_buffer_sptr d_buffer;
+ unsigned int d_read_index; // in items [0,d->buffer.d_bufsize)
+
+ //! constructor is private. Use gr_buffer::add_reader to create instances
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+//! returns # of gr_buffer_readers currently allocated
+long gr_buffer_reader_ncurrently_allocated ();
+
+
+#endif /* INCLUDED_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.i b/gnuradio-core/src/lib/runtime/gr_buffer.i
new file mode 100644
index 0000000000..80f92ece12
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_buffer.i
@@ -0,0 +1,63 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_buffer;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+%template(gr_buffer_sptr) boost::shared_ptr<gr_buffer>;
+%rename(buffer) gr_make_buffer;
+%ignore gr_buffer;
+
+gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item);
+
+class gr_buffer {
+ public:
+ ~gr_buffer ();
+
+ private:
+ gr_buffer (int nitems, size_t sizeof_item);
+};
+
+
+class gr_buffer_reader;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+%template(gr_buffer_reader_sptr) boost::shared_ptr<gr_buffer_reader>;
+%ignore gr_buffer_reader;
+
+%rename(buffer_add_reader) gr_buffer_add_reader;
+gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int history);
+
+class gr_buffer_reader {
+ public:
+ ~gr_buffer_reader ();
+
+ private:
+ friend class gr_buffer;
+ gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index);
+};
+
+
+%rename(buffer_ncurrently_allocated) gr_buffer_ncurrently_allocated;
+long gr_buffer_ncurrently_allocated ();
+
+%rename(buffer_reader_ncurrently_allocated) gr_buffer_reader_ncurrently_allocated;
+long gr_buffer_reader_ncurrently_allocated ();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_complex.h b/gnuradio-core/src/lib/runtime/gr_complex.h
new file mode 100644
index 0000000000..242b2f54d4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_complex.h
@@ -0,0 +1,46 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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) { return true;}
+inline bool is_complex (gr_complexd x) { return true;}
+inline bool is_complex (float x) { return false;}
+inline bool is_complex (double x) { return false;}
+inline bool is_complex (int x) { return false;}
+inline bool is_complex (char x) { return false;}
+inline bool is_complex (short x) { return false;}
+
+
+// this doesn't really belong here, but there are worse places for it...
+
+#define 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-core/src/lib/runtime/gr_dispatcher.cc b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
new file mode 100644
index 0000000000..c2a1eb50af
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.cc
@@ -0,0 +1,192 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_dispatcher.h>
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_SELECT
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# endif
+#endif
+
+
+static gr_dispatcher_sptr s_singleton;
+
+gr_dispatcher_sptr
+gr_make_dispatcher()
+{
+ return gr_dispatcher_sptr(new gr_dispatcher());
+}
+
+gr_dispatcher_sptr
+gr_dispatcher_singleton()
+{
+ if (s_singleton)
+ return s_singleton;
+
+ s_singleton = gr_make_dispatcher();
+ return s_singleton;
+}
+
+#if !defined(HAVE_SELECT) // Stub it out
+
+gr_dispatcher::gr_dispatcher()
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+ return true;
+}
+
+void
+gr_dispatcher::loop(double timeout)
+{
+}
+
+#else // defined(HAVE_SELECT)
+
+gr_dispatcher::gr_dispatcher()
+ : d_handler(FD_SETSIZE), d_max_index(-1)
+{
+}
+
+gr_dispatcher::~gr_dispatcher()
+{
+}
+
+bool
+gr_dispatcher::add_handler(gr_select_handler_sptr handler)
+{
+ int fd = handler->fd();
+ if (fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_max_index = std::max(d_max_index, fd);
+ d_handler[fd] = handler;
+ return true;
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler_sptr handler)
+{
+ return del_handler(handler.get());
+}
+
+bool
+gr_dispatcher::del_handler(gr_select_handler *handler)
+{
+ int fd = handler->fd();
+ if (fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_handler[fd].reset();
+
+ if (fd == d_max_index){
+ int i;
+ for (i = fd - 1; i >= 0 && !d_handler[i]; i--)
+ ;
+ d_max_index = i;
+ }
+ return true;
+}
+
+
+void
+gr_dispatcher::loop(double timeout)
+{
+ struct timeval master;
+ struct timeval tmp;
+ fd_set rd_set;
+ fd_set wr_set;
+
+ double secs = floor (timeout);
+ master.tv_sec = (long) secs;
+ master.tv_usec = (long) ((timeout - secs) * 1e6);
+
+ while (d_max_index >= 0){
+ FD_ZERO(&rd_set);
+ FD_ZERO(&wr_set);
+
+ for (int i = 0; i <= d_max_index; i++){
+ if (d_handler[i] && d_handler[i]->readable())
+ FD_SET(i, &rd_set);
+ if (d_handler[i] && d_handler[i]->writable())
+ FD_SET(i, &wr_set);
+ }
+
+ tmp = master;
+ int retval = select(d_max_index+1, &rd_set, &wr_set, 0, &tmp);
+ if (retval == 0) // timed out with nothing ready
+ continue;
+ if (retval < 0){
+ if (errno == EINTR)
+ continue;
+ perror ("gr_dispatcher/select");
+ return;
+ }
+
+ for (int i = 0; i <= d_max_index; i++){
+ if (FD_ISSET(i, &rd_set))
+ if (d_handler[i])
+ d_handler[i]->handle_read();
+ if (FD_ISSET(i, &wr_set))
+ if (d_handler[i])
+ d_handler[i]->handle_write();
+ }
+ }
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_dispatcher.h b/gnuradio-core/src/lib/runtime/gr_dispatcher.h
new file mode 100644
index 0000000000..a3d8579727
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.h
@@ -0,0 +1,67 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_DISPATCHER_H
+#define INCLUDED_GR_DISPATCHER_H
+
+#include <gr_select_handler.h>
+#include <vector>
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+
+gr_dispatcher_sptr gr_dispatcher_singleton();
+gr_dispatcher_sptr gr_make_dispatcher();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+ gr_dispatcher();
+ friend 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-core/src/lib/runtime/gr_dispatcher.i b/gnuradio-core/src/lib/runtime/gr_dispatcher.i
new file mode 100644
index 0000000000..5feca75713
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_dispatcher.i
@@ -0,0 +1,55 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_dispatcher;
+typedef boost::shared_ptr<gr_dispatcher> gr_dispatcher_sptr;
+%template(gr_dispatcher_sptr) boost::shared_ptr<gr_dispatcher>;
+
+%rename(dispatcher) gr_make_dispatcher;
+gr_dispatcher_sptr gr_make_dispatcher();
+
+%rename(dispatcher_singleton) gr_dispatcher_singleton;
+gr_dispatcher_sptr gr_dispatcher_singleton();
+
+/*!
+ * \brief invoke callbacks based on select.
+ *
+ * \sa gr_select_handler
+ */
+class gr_dispatcher
+{
+ gr_dispatcher();
+
+public:
+ ~gr_dispatcher();
+
+ /*!
+ * \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);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.cc b/gnuradio-core/src/lib/runtime/gr_error_handler.cc
new file mode 100644
index 0000000000..a3148cfde6
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.cc
@@ -0,0 +1,244 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/*
+ * This code is based on error.cc 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_error_handler.h>
+#include <assert.h>
+#include <stdexcept>
+#include <unistd.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+static gr_error_handler *s_default_handler = 0;
+static gr_error_handler *s_silent_handler = 0;
+
+bool
+gr_error_handler::has_default_handler()
+{
+ return s_default_handler != 0;
+}
+
+void
+gr_error_handler::set_default_handler(gr_error_handler *errh)
+{
+ s_default_handler = errh;
+}
+
+gr_error_handler *
+gr_error_handler::default_handler()
+{
+ assert (s_default_handler != 0);
+ return s_default_handler;
+}
+
+gr_error_handler *
+gr_error_handler::silent_handler()
+{
+ assert (s_silent_handler != 0);
+ return s_silent_handler;
+}
+
+// ----------------------------------------------------------------
+
+gr_error_handler::~gr_error_handler()
+{
+ // nop
+}
+
+void
+gr_error_handler::debug(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_DEBUG, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::message(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_MESSAGE, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::warning(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_WARNING, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::error(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_ERROR, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::fatal(const char *format, ...)
+{
+ va_list val;
+ va_start(val, format);
+ verror(ERR_FATAL, format, val);
+ va_end(val);
+}
+
+void
+gr_error_handler::verror(seriousness s, const char *format, va_list val)
+{
+ std::string text = make_text(s, format, val);
+ handle_text(s, text);
+ count_error(s);
+}
+
+void
+gr_error_handler::verror_text(seriousness s, const std::string &text)
+{
+ // text is already made
+ handle_text(s, text);
+ count_error(s);
+}
+
+std::string
+gr_error_handler::make_text(seriousness s, const char *format, va_list val)
+{
+ char text_buf[4096];
+ vsnprintf(text_buf, sizeof(text_buf), format, val);
+ text_buf[sizeof(text_buf)-1] = 0;
+ return text_buf;
+}
+
+// ----------------------------------------------------------------
+
+void
+gr_base_error_handler::count_error(seriousness s)
+{
+ if (s < ERR_WARNING)
+ /* do nothing */;
+ else if (s < ERR_ERROR)
+ d_nwarnings++;
+ else
+ d_nerrors++;
+}
+
+// ----------------------------------------------------------------
+
+gr_file_error_handler::gr_file_error_handler(FILE *file)
+ : d_file(file), d_fd(-1)
+{
+}
+
+gr_file_error_handler::gr_file_error_handler(int file_descriptor)
+{
+ d_fd = dup(file_descriptor); // so we can fclose it
+ if (d_fd == -1){
+ perror("gr_file_error_handler:dup");
+ throw std::invalid_argument("gr_file_error_handler:dup");
+ }
+ d_file = fdopen(d_fd, "w");
+ if (d_file == 0){
+ perror("gr_file_error_handler:fdopen");
+ throw std::invalid_argument("gr_file_error_handler:fdopen");
+ }
+}
+
+gr_file_error_handler::~gr_file_error_handler()
+{
+ if (d_fd != -1){
+ fclose(d_file);
+ }
+}
+
+void
+gr_file_error_handler::handle_text(seriousness s, const std::string &text)
+{
+ if (text.length() <= 0)
+ return;
+
+ fwrite(text.data(), 1, text.length(), d_file);
+ if (text[text.length()-1] != '\n')
+ fwrite("\n", 1, 1, d_file);
+
+ if (d_fd != -1)
+ fflush(d_file); // keep synced with any other users of fd
+}
+
+
+// ----------------------------------------------------------------
+// static error handlers
+//
+
+class gr_silent_error_handler : public gr_base_error_handler
+{
+public:
+ gr_silent_error_handler() {}
+ void handle_text(seriousness s, const std::string &str);
+};
+
+void
+gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
+{
+ // nop
+}
+
+class force_init {
+public:
+ force_init()
+ {
+ s_default_handler = new gr_file_error_handler(stdout);
+ s_silent_handler = new gr_silent_error_handler();
+ }
+};
+
+static force_init kludge;
diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.h b/gnuradio-core/src/lib/runtime/gr_error_handler.h
new file mode 100644
index 0000000000..275db64c33
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.h
@@ -0,0 +1,114 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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 <stdarg.h>
+#include <string>
+
+/*!
+ * \brief abstract error handler
+ */
+class 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_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_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-core/src/lib/runtime/gr_error_handler.i b/gnuradio-core/src/lib/runtime/gr_error_handler.i
new file mode 100644
index 0000000000..d0e61496f4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_error_handler.i
@@ -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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%rename(error_handler) gr_error_handler;
+%rename(file_error_handler) gr_file_error_handler;
+
+class 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);
+
+ virtual int nwarnings() const = 0;
+ virtual int nerrors() const = 0;
+ virtual void reset_counts() = 0;
+
+ void verror_text(seriousness s, const std::string &text);
+};
+
+%ignore gr_base_error_handler;
+class 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_file_error_handler : public gr_base_error_handler {
+public:
+ gr_file_error_handler(int file_descriptor);
+ ~gr_file_error_handler();
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.cc b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
new file mode 100644
index 0000000000..7277108cae
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.cc
@@ -0,0 +1,54 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_io_signature::gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+ if (min_streams < 0
+ || (max_streams != IO_INFINITE && max_streams < min_streams))
+ throw std::invalid_argument ("gr_io_signature");
+
+ d_min_streams = min_streams;
+ d_max_streams = max_streams;
+ d_sizeof_stream_item = sizeof_stream_item;
+}
+
+gr_io_signature::~gr_io_signature ()
+{
+ // NOP for now
+ // std::cout << "destroying gr_io_signature: " << this << '\n';
+}
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item)
+{
+ return gr_io_signature_sptr (new gr_io_signature (min_streams, max_streams,
+ sizeof_stream_item));
+}
+
+
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.h b/gnuradio-core/src/lib/runtime/gr_io_signature.h
new file mode 100644
index 0000000000..e0d979070c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.h
@@ -0,0 +1,65 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_IO_SIGNATURE_H
+#define INCLUDED_IO_SIGNATURE_H
+
+#include <gr_runtime.h>
+
+/*!
+ * \brief i/o signature for input and output ports.
+ *
+ * For now, we restrict all streams to be the same type.
+ * We can fix this later.
+ */
+
+class gr_io_signature {
+ 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; }
+ size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+ // ----------------------------------------------------------------------------
+
+ private:
+
+ int d_min_streams;
+ int d_max_streams;
+ size_t d_sizeof_stream_item;
+
+ gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+ friend gr_io_signature_sptr gr_make_io_signature (int min_streams,
+ int max_streams,
+ size_t sizeof_stream_item);
+};
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+
+
+#endif /* INCLUDED_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_io_signature.i b/gnuradio-core/src/lib/runtime/gr_io_signature.i
new file mode 100644
index 0000000000..601142e287
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_io_signature.i
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_io_signature;
+typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
+%template(gr_io_signature_sptr) boost::shared_ptr<gr_io_signature>;
+
+%rename(io_signature) gr_make_io_signature;
+
+gr_io_signature_sptr
+gr_make_io_signature (int min_streams,
+ int max_streams,
+ size_t sizeof_stream_item);
+
+class gr_io_signature {
+ public:
+
+ // disabled. Suspected bug in SWIG 1.3.24
+ // 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; }
+ size_t sizeof_stream_item (int index) const { return d_sizeof_stream_item; }
+
+ private:
+ gr_io_signature (int min_streams, int max_streams, size_t sizeof_stream_item);
+};
+
diff --git a/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
new file mode 100644
index 0000000000..c6da0978c3
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.cc
@@ -0,0 +1,186 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_local_sighandler.h>
+#include <stdexcept>
+#include <stdio.h>
+
+
+gr_local_sighandler::gr_local_sighandler (int signum,
+ void (*new_handler)(int))
+ : d_signum (signum)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction new_action;
+ memset (&new_action, 0, sizeof (new_action));
+
+ new_action.sa_handler = new_handler;
+ sigemptyset (&new_action.sa_mask);
+ new_action.sa_flags = 0;
+
+ if (sigaction (d_signum, &new_action, &d_old_action) < 0){
+ perror ("sigaction (install new)");
+ throw std::runtime_error ("sigaction");
+ }
+#endif
+}
+
+gr_local_sighandler::~gr_local_sighandler ()
+{
+#ifdef HAVE_SIGACTION
+ if (sigaction (d_signum, &d_old_action, 0) < 0){
+ perror ("sigaction (restore old)");
+ throw std::runtime_error ("sigaction");
+ }
+#endif
+}
+
+void
+gr_local_sighandler::throw_signal (int signum)
+{
+ throw gr_signal (signum);
+}
+
+/*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+
+#define SIGNAME(x) case x: return #x
+
+std::string
+gr_signal::name () const
+{
+ char tmp[128];
+
+ switch (signal ()){
+#ifdef SIGHUP
+ SIGNAME (SIGHUP);
+#endif
+#ifdef SIGINT
+ SIGNAME (SIGINT);
+#endif
+#ifdef SIGQUIT
+ SIGNAME (SIGQUIT);
+#endif
+#ifdef SIGILL
+ SIGNAME (SIGILL);
+#endif
+#ifdef SIGTRAP
+ SIGNAME (SIGTRAP);
+#endif
+#ifdef SIGABRT
+ SIGNAME (SIGABRT);
+#endif
+#ifdef SIGBUS
+ SIGNAME (SIGBUS);
+#endif
+#ifdef SIGFPE
+ SIGNAME (SIGFPE);
+#endif
+#ifdef SIGKILL
+ SIGNAME (SIGKILL);
+#endif
+#ifdef SIGUSR1
+ SIGNAME (SIGUSR1);
+#endif
+#ifdef SIGSEGV
+ SIGNAME (SIGSEGV);
+#endif
+#ifdef SIGUSR2
+ SIGNAME (SIGUSR2);
+#endif
+#ifdef SIGPIPE
+ SIGNAME (SIGPIPE);
+#endif
+#ifdef SIGALRM
+ SIGNAME (SIGALRM);
+#endif
+#ifdef SIGTERM
+ SIGNAME (SIGTERM);
+#endif
+#ifdef SIGSTKFLT
+ SIGNAME (SIGSTKFLT);
+#endif
+#ifdef SIGCHLD
+ SIGNAME (SIGCHLD);
+#endif
+#ifdef SIGCONT
+ SIGNAME (SIGCONT);
+#endif
+#ifdef SIGSTOP
+ SIGNAME (SIGSTOP);
+#endif
+#ifdef SIGTSTP
+ SIGNAME (SIGTSTP);
+#endif
+#ifdef SIGTTIN
+ SIGNAME (SIGTTIN);
+#endif
+#ifdef SIGTTOU
+ SIGNAME (SIGTTOU);
+#endif
+#ifdef SIGURG
+ SIGNAME (SIGURG);
+#endif
+#ifdef SIGXCPU
+ SIGNAME (SIGXCPU);
+#endif
+#ifdef SIGXFSZ
+ SIGNAME (SIGXFSZ);
+#endif
+#ifdef SIGVTALRM
+ SIGNAME (SIGVTALRM);
+#endif
+#ifdef SIGPROF
+ SIGNAME (SIGPROF);
+#endif
+#ifdef SIGWINCH
+ SIGNAME (SIGWINCH);
+#endif
+#ifdef SIGIO
+ SIGNAME (SIGIO);
+#endif
+#ifdef SIGPWR
+ SIGNAME (SIGPWR);
+#endif
+#ifdef SIGSYS
+ SIGNAME (SIGSYS);
+#endif
+ default:
+#if defined (HAVE_SNPRINTF)
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+ if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
+ snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
+ return tmp;
+ }
+#endif
+ snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
+ return tmp;
+#else
+ return "Unknown signal";
+#endif
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_local_sighandler.h b/gnuradio-core/src/lib/runtime/gr_local_sighandler.h
new file mode 100644
index 0000000000..69eb65d80d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_local_sighandler.h
@@ -0,0 +1,60 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_LOCAL_SIGHANDLER_H
+#define INCLUDED_GR_LOCAL_SIGHANDLER_H
+
+#include <signal.h>
+#include <string>
+
+/*!
+ * \brief Get and set signal handler.
+ *
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+class gr_local_sighandler {
+ int d_signum;
+#ifdef HAVE_SIGACTION
+ struct sigaction d_old_action;
+#endif
+public:
+ gr_local_sighandler (int signum, void (*new_handler)(int));
+ ~gr_local_sighandler ();
+
+ /* throw gr_signal (signum) */
+ static void throw_signal (int signum);
+};
+
+/*!
+ * \brief Representation of signal.
+ */
+class gr_signal
+{
+ int d_signum;
+public:
+ gr_signal (int signum) : d_signum (signum) {}
+ int signal () const { return d_signum; }
+ std::string name () const;
+};
+
+#endif /* INCLUDED_GR_LOCAL_SIGHANDLER_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.cc b/gnuradio-core/src/lib/runtime/gr_message.cc
new file mode 100644
index 0000000000..e9427e64df
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.cc
@@ -0,0 +1,77 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_message.h>
+#include <assert.h>
+
+static long s_ncurrently_allocated = 0;
+
+gr_message_sptr
+gr_make_message (long type, double arg1, double arg2, size_t length)
+{
+ return gr_message_sptr (new gr_message (type, arg1, arg2, length));
+}
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type, double arg1, double arg2)
+{
+ gr_message_sptr m = gr_make_message(type, arg1, arg2, s.size());
+ memcpy(m->msg(), s.data(), s.size());
+ return m;
+}
+
+
+gr_message::gr_message (long type, double arg1, double arg2, size_t length)
+ : d_type(type), d_arg1(arg1), d_arg2(arg2)
+{
+ if (length == 0)
+ d_buf_start = d_msg_start = d_msg_end = d_buf_end = 0;
+ else {
+ d_buf_start = new unsigned char [length];
+ d_msg_start = d_buf_start;
+ d_msg_end = d_buf_end = d_buf_start + length;
+ }
+ s_ncurrently_allocated++;
+}
+
+gr_message::~gr_message ()
+{
+ assert (d_next == 0);
+ delete [] d_buf_start;
+ d_msg_start = d_msg_end = d_buf_end = 0;
+ s_ncurrently_allocated--;
+}
+
+std::string
+gr_message::to_string() const
+{
+ return std::string((char *)d_msg_start, length());
+}
+
+long
+gr_message_ncurrently_allocated ()
+{
+ return s_ncurrently_allocated;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_message.h b/gnuradio-core/src/lib/runtime/gr_message.h
new file mode 100644
index 0000000000..272a82ee47
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.h
@@ -0,0 +1,89 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MESSAGE_H
+#define INCLUDED_GR_MESSAGE_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_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class 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_message_sptr
+ gr_make_message (long type, double arg1, double arg2, size_t length);
+
+ friend 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;
+
+};
+
+long gr_message_ncurrently_allocated ();
+
+#endif /* INCLUDED_GR_MESSAGE_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_message.i b/gnuradio-core/src/lib/runtime/gr_message.i
new file mode 100644
index 0000000000..19d5d1cd17
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_message.i
@@ -0,0 +1,65 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_message;
+typedef boost::shared_ptr<gr_message> gr_message_sptr;
+%template(gr_message_sptr) boost::shared_ptr<gr_message>;
+
+%rename(message_from_string) gr_make_message_from_string;
+gr_message_sptr
+gr_make_message_from_string(const std::string s, long type = 0, double arg1 = 0, double arg2 = 0);
+
+%rename(message) gr_make_message;
+gr_message_sptr
+gr_make_message(long type = 0, double arg1 = 0, double arg2 = 0, size_t length = 0);
+
+/*!
+ * \brief Message.
+ *
+ * The ideas and method names for adjustable message length were
+ * lifted from the click modular router "Packet" class.
+ */
+class gr_message {
+ gr_message (long type, double arg1, double arg2, size_t length);
+
+ 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; }
+
+ size_t length() const;
+ std::string to_string() const;
+
+};
+
+%rename(message_ncurrently_allocated) gr_message_ncurrently_allocated;
+long gr_message_ncurrently_allocated();
+
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.cc b/gnuradio-core/src/lib/runtime/gr_msg_handler.cc
new file mode 100644
index 0000000000..98007e239a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.cc
@@ -0,0 +1,30 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_msg_handler.h>
+
+gr_msg_handler::~gr_msg_handler ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_handler.h b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
new file mode 100644
index 0000000000..15aab338a5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.h
@@ -0,0 +1,41 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MSG_HANDLER_H
+#define INCLUDED_GR_MSG_HANDLER_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
+ */
+class 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-core/src/lib/runtime/gr_msg_handler.i b/gnuradio-core/src/lib/runtime/gr_msg_handler.i
new file mode 100644
index 0000000000..5571665ac7
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_handler.i
@@ -0,0 +1,32 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*!
+ * \brief abstract class of message handlers
+ */
+class gr_msg_handler {
+public:
+ virtual ~gr_msg_handler () = 0;
+
+ //! handle \p msg
+ virtual void handle (gr_message_sptr msg) = 0;
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.cc b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
new file mode 100644
index 0000000000..6b53fc7ea1
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.cc
@@ -0,0 +1,127 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_msg_queue.h>
+#include <stdexcept>
+
+
+gr_msg_queue_sptr
+gr_make_msg_queue(unsigned int limit)
+{
+ return gr_msg_queue_sptr (new gr_msg_queue(limit));
+}
+
+
+gr_msg_queue::gr_msg_queue(unsigned int limit)
+ : d_not_empty(&d_mutex), d_not_full(&d_mutex),
+ /*d_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
+{
+}
+
+gr_msg_queue::~gr_msg_queue()
+{
+ flush ();
+}
+
+void
+gr_msg_queue::insert_tail(gr_message_sptr msg)
+{
+ if (msg->d_next)
+ throw std::invalid_argument("gr_msg_queue::insert_tail: msg already in queue");
+
+ omni_mutex_lock l(d_mutex);
+
+ while (full_p())
+ d_not_full.wait();
+
+ if (d_tail == 0){
+ d_tail = d_head = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ else {
+ d_tail->d_next = msg;
+ d_tail = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ d_count++;
+ d_not_empty.signal();
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head()
+{
+ omni_mutex_lock l(d_mutex);
+ gr_message_sptr m;
+
+ while ((m = d_head) == 0)
+ d_not_empty.wait();
+
+ d_head = m->d_next;
+ if (d_head == 0){
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ // m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.signal();
+ return m;
+}
+
+gr_message_sptr
+gr_msg_queue::delete_head_nowait()
+{
+ omni_mutex_lock l(d_mutex);
+ gr_message_sptr m;
+
+ if ((m = d_head) == 0){
+ //return 0;
+ return gr_message_sptr();
+ }
+
+ d_head = m->d_next;
+ if (d_head == 0){
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ //m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.signal();
+ return m;
+}
+
+void
+gr_msg_queue::flush()
+{
+ gr_message_sptr m;
+
+ while ((m = delete_head_nowait ()) != 0)
+ ;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.h b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
new file mode 100644
index 0000000000..6a9147ee38
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.h
@@ -0,0 +1,89 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_MSG_QUEUE_H
+#define INCLUDED_GR_MSG_QUEUE_H
+
+#include <gr_msg_handler.h>
+#include <omnithread.h>
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+
+gr_msg_queue_sptr gr_make_msg_queue(unsigned int limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+class gr_msg_queue : public gr_msg_handler {
+ omni_mutex d_mutex;
+ omni_condition d_not_empty;
+ omni_condition 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-core/src/lib/runtime/gr_msg_queue.i b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
new file mode 100644
index 0000000000..28292d66fb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.i
@@ -0,0 +1,111 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+class gr_msg_queue;
+typedef boost::shared_ptr<gr_msg_queue> gr_msg_queue_sptr;
+%template(gr_msg_queue_sptr) boost::shared_ptr<gr_msg_queue>;
+
+%rename(msg_queue) gr_make_msg_queue;
+gr_msg_queue_sptr gr_make_msg_queue(unsigned limit=0);
+
+/*!
+ * \brief thread-safe message queue
+ */
+%ignore gr_msg_queue;
+class gr_msg_queue : public gr_msg_handler {
+ omni_mutex d_mutex;
+ omni_condition d_cond;
+ gr_message_sptr d_head;
+ gr_message_sptr d_tail;
+ int d_count;
+
+public:
+ gr_msg_queue();
+ ~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();
+
+ //! is the queue empty?
+ bool empty_p() const;
+
+ //! is the queue full?
+ bool full_p() const;
+
+ //! return number of messages in queue
+ unsigned int count() const;
+
+ //! Delete all messages from the queue
+ void flush();
+};
+
+/*
+ * The following kludge-o-rama releases the Python global interpreter
+ * lock around these potentially blocking calls. We don't want
+ * libgnuradio-core to be dependent on Python, thus we create these
+ * functions that serve as replacements for the normal C++ delete_head
+ * and insert_tail methods. The %pythoncode smashes these new C++
+ * functions into the gr.msg_queue wrapper class, so that everything
+ * appears normal. (An evil laugh is heard in the distance...)
+ */
+%inline {
+ gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) {
+ gr_message_sptr msg;
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ msg = q->delete_head(); // possibly blocking call
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ return msg;
+ }
+
+ void gr_py_msg_queue__insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg) {
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ q->insert_tail(msg); // possibly blocking call
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ }
+}
+
+// smash in new python delete_head and insert_tail methods...
+%pythoncode %{
+gr_msg_queue_sptr.delete_head = gr_py_msg_queue__delete_head
+gr_msg_queue_sptr.insert_tail = gr_py_msg_queue__insert_tail
+gr_msg_queue_sptr.handle = gr_py_msg_queue__insert_tail
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.cc b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
new file mode 100644
index 0000000000..dec40678b3
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_pagesize.cc
@@ -0,0 +1,56 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_pagesize.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#if defined(_WIN32) && defined(HAVE_GETPAGESIZE)
+extern "C" size_t getpagesize(void);
+#endif
+
+int
+gr_pagesize ()
+{
+ static int s_pagesize = -1;
+
+ if (s_pagesize == -1){
+#if defined(HAVE_GETPAGESIZE)
+ s_pagesize = getpagesize ();
+#elif defined (HAVE_SYSCONF)
+ s_pagesize = sysconf (_SC_PAGESIZE);
+ if (s_pagesize == -1){
+ perror ("_SC_PAGESIZE");
+ s_pagesize = 4096;
+ }
+#else
+ fprintf (stderr, "gr_pagesize: no info; setting pagesize = 4096\n");
+ s_pagesize = 4096;
+#endif
+ }
+ return s_pagesize;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_pagesize.h b/gnuradio-core/src/lib/runtime/gr_pagesize.h
new file mode 100644
index 0000000000..a5cadb7074
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_pagesize.h
@@ -0,0 +1,32 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _GR_PAGESIZE_H_
+#define _GR_PAGESIZE_H_
+
+/*!
+ * \brief return the page size in bytes
+ */
+
+int gr_pagesize ();
+
+
+#endif /* _GR_PAGESIZE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.cc b/gnuradio-core/src/lib/runtime/gr_preferences.cc
new file mode 100644
index 0000000000..854314447a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.cc
@@ -0,0 +1,101 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+#ifdef MKDIR_TAKES_ONE_ARG
+#define gr_mkdir(pathname, mode) mkdir(pathname)
+#else
+#define gr_mkdir(pathname, mode) mkdir((pathname), (mode))
+#endif
+
+/*
+ * The simplest thing that could possibly work:
+ * the key is the filename; the value is the file contents.
+ */
+
+static const char *
+pathname (const char *key)
+{
+ static char buf[200];
+ snprintf (buf, sizeof (buf), "%s/.gnuradio/prefs/%s", getenv ("HOME"), key);
+ return buf;
+}
+
+static void
+ensure_dir_path ()
+{
+ char path[200];
+ struct stat statbuf;
+
+ snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+ if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
+ return;
+
+ // blindly try to make it // FIXME make this robust. C++ SUCKS!
+
+ snprintf (path, sizeof (path), "%s/.gnuradio", getenv ("HOME"));
+ gr_mkdir (path, 0750);
+ snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME"));
+ gr_mkdir (path, 0750);
+}
+
+const char *
+gr_preferences::get (const char *key)
+{
+ static char buf[1024];
+
+ FILE *fp = fopen (pathname (key), "r");
+ if (fp == 0)
+ return 0;
+
+ memset (buf, 0, sizeof (buf));
+ fread (buf, 1, sizeof (buf) - 1, fp);
+ fclose (fp);
+ return buf;
+}
+
+void
+gr_preferences::set (const char *key, const char *value)
+{
+ ensure_dir_path ();
+
+ FILE *fp = fopen (pathname (key), "w");
+ if (fp == 0){
+ perror (pathname (key));
+ return;
+ }
+
+ fwrite (value, 1, strlen (value), fp);
+ fclose (fp);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.h b/gnuradio-core/src/lib/runtime/gr_preferences.h
new file mode 100644
index 0000000000..5a7cad454d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_preferences.h
@@ -0,0 +1,32 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_PREFERENCES_H_
+#define _GR_PREFERENCES_H_
+
+class gr_preferences {
+ public:
+ static const char *get (const char *key);
+ static void set (const char *key, const char *value);
+};
+
+#endif /* _GR_PREFERENCES_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.cc b/gnuradio-core/src/lib/runtime/gr_realtime.cc
new file mode 100644
index 0000000000..4f23ea0c63
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.cc
@@ -0,0 +1,71 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <gr_realtime.h>
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined(HAVE_SCHED_SETSCHEDULER)
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+ int policy = SCHED_FIFO;
+ int pri = (sched_get_priority_max (policy) - sched_get_priority_min (policy)) / 2;
+ int pid = 0; // this process
+
+ struct sched_param param;
+ memset(&param, 0, sizeof(param));
+ param.sched_priority = pri;
+ int result = sched_setscheduler(pid, policy, &param);
+ if (result != 0){
+ if (errno == EPERM)
+ return RT_NO_PRIVS;
+ else {
+ perror ("sched_setscheduler: failed to set real time priority");
+ return RT_OTHER_ERROR;
+ }
+ }
+ //printf("SCHED_FIFO enabled with priority = %d\n", pri);
+ return RT_OK;
+}
+
+// #elif // could try negative niceness
+
+#else
+
+gr_rt_status_t
+gr_enable_realtime_scheduling()
+{
+ return RT_NOT_IMPLEMENTED;
+}
+
+#endif
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.h b/gnuradio-core/src/lib/runtime/gr_realtime.h
new file mode 100644
index 0000000000..3aeafa5338
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.h
@@ -0,0 +1,39 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_REALTIME_H
+#define INCLUDED_GR_REALTIME_H
+
+typedef enum {
+ RT_OK = 0,
+ RT_NOT_IMPLEMENTED,
+ RT_NO_PRIVS,
+ RT_OTHER_ERROR
+} gr_rt_status_t;
+
+/*!
+ * \brief If possible, enable high-priority "real time" scheduling.
+ */
+gr_rt_status_t
+gr_enable_realtime_scheduling();
+
+#endif /* INCLUDED_GR_REALTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_realtime.i b/gnuradio-core/src/lib/runtime/gr_realtime.i
new file mode 100644
index 0000000000..cb43e0514c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_realtime.i
@@ -0,0 +1,4 @@
+%rename(enable_realtime_scheduling) gr_enable_realtime_scheduling;
+
+%include <gr_realtime.h>
+
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
new file mode 100644
index 0000000000..f138e6ac41
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_H
+#define INCLUDED_GR_RUNTIME_H
+
+#include <gr_types.h>
+
+/*
+ * typedefs for smart pointers we use throughout the runtime system
+ */
+
+class gr_block;
+class gr_block_detail;
+class gr_io_signature;
+class gr_buffer;
+class gr_buffer_reader;
+
+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_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;
+
+#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.cc b/gnuradio-core/src/lib/runtime/gr_select_handler.cc
new file mode 100644
index 0000000000..d85883a655
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_select_handler.cc
@@ -0,0 +1,36 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_select_handler.h>
+
+gr_select_handler::gr_select_handler(int fd)
+ : d_fd(fd)
+{
+}
+
+gr_select_handler::~gr_select_handler()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_select_handler.h b/gnuradio-core/src/lib/runtime/gr_select_handler.h
new file mode 100644
index 0000000000..d07ff007f8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_select_handler.h
@@ -0,0 +1,83 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SELECT_HANDLER_H
+#define INCLUDED_GR_SELECT_HANDLER_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.
+ *
+ * \sa gr_dispatcher
+ */
+class 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-core/src/lib/runtime/gr_single_threaded_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
new file mode 100644
index 0000000000..3d401557be
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
@@ -0,0 +1,360 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_single_threaded_scheduler.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <limits>
+#include <assert.h>
+#include <stdio.h>
+
+// must be defined to either 0 or 1
+#define ENABLE_LOGGING 0
+
+#if (ENABLE_LOGGING)
+#define LOG(x) do { x; } while(0)
+#else
+#define LOG(x) do {;} while(0)
+#endif
+
+static int which_scheduler = 0;
+
+
+std::ostream&
+operator << (std::ostream& os, const gr_block *m)
+{
+ os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>";
+ return os;
+}
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks)
+{
+ return
+ gr_single_threaded_scheduler_sptr (new gr_single_threaded_scheduler (blocks));
+}
+
+gr_single_threaded_scheduler::gr_single_threaded_scheduler (
+ const std::vector<gr_block_sptr> &blocks)
+ : d_blocks (blocks), d_enabled (true), d_log(0)
+{
+ if (ENABLE_LOGGING){
+ char name[100];
+ snprintf(name, sizeof(name), "sst-%d.log", which_scheduler++);
+ d_log = new std::ofstream(name);
+ *d_log << "gr_single_threaded_scheduler: "
+ << d_blocks.size ()
+ << " blocks\n";
+ }
+}
+
+gr_single_threaded_scheduler::~gr_single_threaded_scheduler ()
+{
+ if (ENABLE_LOGGING)
+ delete d_log;
+}
+
+void
+gr_single_threaded_scheduler::run ()
+{
+ d_enabled = true;
+ main_loop ();
+}
+
+
+inline static unsigned int
+round_up (unsigned int n, unsigned int multiple)
+{
+ return ((n + multiple - 1) / multiple) * multiple;
+}
+
+inline static unsigned int
+round_down (unsigned int n, unsigned int multiple)
+{
+ return (n / multiple) * multiple;
+}
+
+//
+// Return minimum available write space in all our downstream buffers
+// or -1 if we're output blocked and the output we're blocked
+// on is done.
+//
+static int
+min_available_space (gr_block_detail *d, int output_multiple)
+{
+ int min_space = std::numeric_limits<int>::max();
+
+ for (int i = 0; i < d->noutputs (); i++){
+ int n = round_down (d->output(i)->space_available (), output_multiple);
+ if (n == 0){ // We're blocked on output.
+ if (d->output(i)->done()){ // Downstream is done, therefore we're done.
+ return -1;
+ }
+ return 0;
+ }
+ min_space = std::min (min_space, n);
+ }
+ return min_space;
+}
+
+void
+gr_single_threaded_scheduler::main_loop ()
+{
+ static const int DEFAULT_CAPACITY = 16;
+
+ int noutput_items;
+ gr_vector_int ninput_items_required (DEFAULT_CAPACITY);
+ gr_vector_int ninput_items (DEFAULT_CAPACITY);
+ gr_vector_const_void_star input_items (DEFAULT_CAPACITY);
+ gr_vector_void_star output_items (DEFAULT_CAPACITY);
+ unsigned int bi;
+ unsigned int nalive;
+ int max_items_avail;
+ bool made_progress_last_pass;
+ bool making_progress;
+
+ for (unsigned i = 0; i < d_blocks.size (); i++)
+ d_blocks[i]->detail()->set_done (false); // reset any done flags
+
+ for (unsigned i = 0; i < d_blocks.size (); i++) // enable any drivers, etc.
+ d_blocks[i]->start();
+
+
+ bi = 0;
+ made_progress_last_pass = true;
+ making_progress = false;
+
+ // Loop while there are still blocks alive
+
+ nalive = d_blocks.size ();
+ while (d_enabled && nalive > 0){
+
+ gr_block *m = d_blocks[bi].get ();
+ gr_block_detail *d = m->detail().get ();
+
+ LOG(*d_log << std::endl << m);
+
+ if (d->done ())
+ goto next_block;
+
+ if (d->source_p ()){
+ // Invoke sources as a last resort. As long as the previous pass
+ // made progress, don't call a source.
+ if (made_progress_last_pass){
+ LOG(*d_log << " Skipping source\n");
+ goto next_block;
+ }
+
+ ninput_items_required.resize (0);
+ ninput_items.resize (0);
+ input_items.resize (0);
+ output_items.resize (d->noutputs ());
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple ());
+ LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl);
+ if (noutput_items == -1) // we're done
+ goto were_done;
+
+ if (noutput_items == 0){ // we're output blocked
+ LOG(*d_log << " BLKD_OUT\n");
+ goto next_block;
+ }
+
+ goto setup_call_to_work; // jump to common code
+ }
+
+ else if (d->sink_p ()){
+ ninput_items_required.resize (d->ninputs ());
+ ninput_items.resize (d->ninputs ());
+ input_items.resize (d->ninputs ());
+ output_items.resize (0);
+ LOG(*d_log << " sink\n");
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ ninput_items[i] = d->input(i)->items_available();
+ //if (ninput_items[i] == 0 && d->input(i)->done())
+ if (ninput_items[i] < m->output_multiple() && d->input(i)->done())
+ goto were_done;
+
+ max_items_avail = std::max (max_items_avail, ninput_items[i]);
+ }
+
+ // take a swag at how much output we can sink
+ noutput_items = (int) (max_items_avail * m->relative_rate ());
+ noutput_items = round_down (noutput_items, m->output_multiple ());
+ LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl);
+ LOG(*d_log << " noutput_items = " << noutput_items << std::endl);
+
+ if (noutput_items == 0){ // we're blocked on input
+ LOG(*d_log << " BLKD_IN\n");
+ goto next_block;
+ }
+
+ goto try_again; // Jump to code shared with regular case.
+ }
+
+ else {
+ // do the regular thing
+ ninput_items_required.resize (d->ninputs ());
+ ninput_items.resize (d->ninputs ());
+ input_items.resize (d->ninputs ());
+ output_items.resize (d->noutputs ());
+
+ max_items_avail = 0;
+ for (int i = 0; i < d->ninputs (); i++){
+ ninput_items[i] = d->input(i)->items_available ();
+ max_items_avail = std::max (max_items_avail, ninput_items[i]);
+ }
+
+ // determine the minimum available output space
+ noutput_items = min_available_space (d, m->output_multiple ());
+ if (ENABLE_LOGGING){
+ *d_log << " regular ";
+ if (m->relative_rate() >= 1.0)
+ *d_log << "1:" << m->relative_rate() << std::endl;
+ else
+ *d_log << 1.0/m->relative_rate() << ":1\n";
+ *d_log << " max_items_avail = " << max_items_avail << std::endl;
+ *d_log << " noutput_items = " << noutput_items << std::endl;
+ }
+ if (noutput_items == -1) // we're done
+ goto were_done;
+
+ if (noutput_items == 0){ // we're output blocked
+ LOG(*d_log << " BLKD_OUT\n");
+ goto next_block;
+ }
+
+#if 0
+ // Compute best estimate of noutput_items that we can really use.
+ noutput_items =
+ std::min ((unsigned) noutput_items,
+ std::max ((unsigned) m->output_multiple(),
+ round_up ((unsigned) (max_items_avail * m->relative_rate()),
+ m->output_multiple ())));
+
+ LOG(*d_log << " revised noutput_items = " << noutput_items << std::endl);
+#endif
+
+ try_again:
+ if (m->fixed_rate()){
+ // try to work it forward starting with max_items_avail.
+ // We want to try to consume all the input we've got.
+ int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail);
+ reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple());
+ if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
+ noutput_items = reqd_noutput_items;
+ }
+
+ // ask the block how much input they need to produce noutput_items
+ m->forecast (noutput_items, ninput_items_required);
+
+ // See if we've got sufficient input available
+
+ int i;
+ for (i = 0; i < d->ninputs (); i++)
+ if (ninput_items_required[i] > ninput_items[i]) // not enough
+ break;
+
+ if (i < d->ninputs ()){ // not enough input on input[i]
+ // if we can, try reducing the size of our output request
+ if (noutput_items > m->output_multiple ()){
+ noutput_items /= 2;
+ noutput_items = round_up (noutput_items, m->output_multiple ());
+ goto try_again;
+ }
+
+ // We're blocked on input
+ LOG(*d_log << " BLKD_IN\n");
+ if (d->input(i)->done()) // If the upstream block is done, we're done
+ goto were_done;
+
+ // Is it possible to ever fulfill this request?
+ if (ninput_items_required[i] > d->input(i)->max_possible_items_available ()){
+ // Nope, never going to happen...
+ std::cerr << "\nsched: <gr_block " << m->name()
+ << " (" << m->unique_id() << ")>"
+ << " is requesting more input data\n"
+ << " than we can provide.\n"
+ << " ninput_items_required = "
+ << ninput_items_required[i] << "\n"
+ << " max_possible_items_available = "
+ << d->input(i)->max_possible_items_available() << "\n"
+ << " If this is a filter, consider reducing the number of taps.\n";
+ goto were_done;
+ }
+
+ goto next_block;
+ }
+
+ // We've got enough data on each input to produce noutput_items.
+ // Finish setting up the call to work.
+
+ for (int i = 0; i < d->ninputs (); i++)
+ input_items[i] = d->input(i)->read_pointer();
+
+ setup_call_to_work:
+
+ for (int i = 0; i < d->noutputs (); i++)
+ output_items[i] = d->output(i)->write_pointer();
+
+ // Do the actual work of the block
+ int n = m->general_work (noutput_items, ninput_items,
+ input_items, output_items);
+ LOG(*d_log << " general_work: noutput_items = " << noutput_items
+ << " result = " << n << std::endl);
+
+ if (n == -1) // block is done
+ goto were_done;
+
+ d->produce_each (n); // advance write pointers
+ if (n > 0)
+ making_progress = true;
+
+ goto next_block;
+ }
+ assert (0);
+
+ were_done:
+ LOG(*d_log << " were_done\n");
+ d->set_done (true);
+ nalive--;
+
+ next_block:
+ if (++bi >= d_blocks.size ()){
+ bi = 0;
+ made_progress_last_pass = making_progress;
+ making_progress = false;
+ }
+ }
+
+ for (unsigned i = 0; i < d_blocks.size (); i++) // disable any drivers, etc.
+ d_blocks[i]->stop();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h
new file mode 100644
index 0000000000..1272831e59
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.h
@@ -0,0 +1,61 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
+
+#include <gr_runtime.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_single_threaded_scheduler {
+ public:
+ ~gr_single_threaded_scheduler ();
+
+ void run ();
+ void stop () { d_enabled = false; }
+
+ 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_single_threaded_scheduler_sptr
+ gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks);
+};
+
+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-core/src/lib/runtime/gr_single_threaded_scheduler.i b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
new file mode 100644
index 0000000000..40058228b2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i
@@ -0,0 +1,52 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_runtime.h>
+
+class gr_single_threaded_scheduler;
+typedef boost::shared_ptr<gr_single_threaded_scheduler> gr_single_threaded_scheduler_sptr;
+%template(gr_single_threaded_scheduler_sptr) boost::shared_ptr<gr_single_threaded_scheduler>;
+%rename(single_threaded_scheduler) gr_make_single_threaded_scheduler;
+%ignore gr_single_threaded_scheduler;
+
+gr_single_threaded_scheduler_sptr
+gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+
+class gr_single_threaded_scheduler {
+ public:
+ ~gr_single_threaded_scheduler ();
+
+ // void run ();
+ void stop ();
+
+ private:
+ gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules);
+};
+
+%inline {
+ void sts_pyrun (gr_single_threaded_scheduler_sptr s) {
+ Py_BEGIN_ALLOW_THREADS; // release global interpreter lock
+ s->run ();
+ Py_END_ALLOW_THREADS; // acquire global interpreter lock
+ }
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i b/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i
new file mode 100644
index 0000000000..ca4f6e600d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_swig_block_magic.i
@@ -0,0 +1,45 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%define GR_SWIG_BLOCK_MAGIC(PKG, BASE_NAME)
+_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, PKG ## _ ## BASE_NAME, BASE_NAME)
+%enddef
+
+%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, NAME, BASE_NAME)
+class NAME;
+typedef boost::shared_ptr<NAME> NAME ## _sptr;
+%template(NAME ## _sptr) boost::shared_ptr<NAME>;
+%rename(BASE_NAME) PKG ## _make_ ## BASE_NAME;
+%inline {
+ gr_block_sptr NAME ## _block (NAME ## _sptr r)
+ {
+ return gr_block_sptr (r);
+ }
+}
+
+%pythoncode %{
+NAME ## _sptr.block = lambda self: NAME ## _block (self)
+NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
+
+%ignore NAME;
+%enddef
diff --git a/gnuradio-core/src/lib/runtime/gr_timer.h b/gnuradio-core/src/lib/runtime/gr_timer.h
new file mode 100644
index 0000000000..709b98470e
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_timer.h
@@ -0,0 +1,82 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef INCLUDED_GR_TIMER_H
+#define INCLUDED_GR_TIMER_H
+
+#include <gr_types.h>
+
+class gr_timer;
+
+typedef boost::shared_ptr<gr_timer> gr_timer_sptr;
+
+typedef void (*gr_timer_hook)(gr_timer *, void *);
+
+/*!
+ * \brief create a timeout.
+ *
+ * gr_timer_hook is called when timer fires.
+ */
+gr_timer_sptr gr_make_timer (gr_timer_hook, void *);
+
+/*!
+ * \brief implement timeouts
+ */
+class gr_timer {
+ double d_expiry;
+ double d_period;
+ gr_timer_hook d_hook;
+ void *d_hook_arg;
+
+ friend 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-core/src/lib/runtime/gr_tmp_path.cc b/gnuradio-core/src/lib/runtime/gr_tmp_path.cc
new file mode 100644
index 0000000000..7eb03b5d55
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tmp_path.cc
@@ -0,0 +1,52 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_tmp_path.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *
+gr_tmp_path ()
+{
+ static char *pp = 0;
+
+ if (pp)
+ return pp;
+
+ char *s = getenv ("TMP");
+ if (s){
+ pp = strdup (s);
+ return pp;
+ }
+
+#ifdef P_tmpdir
+ if (P_tmpdir){
+ pp = strdup (P_tmpdir);
+ return pp;
+ }
+#endif
+
+ pp = strdup ("/tmp");
+ return pp;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.h b/gnuradio-core/src/lib/runtime/gr_tmp_path.h
new file mode 100644
index 0000000000..742ce05633
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_tmp_path.h
@@ -0,0 +1,31 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_TMP_PATH_H_
+#define _GR_TMP_PATH_H_
+
+/*!
+ * \brief return directory portion of pathname used for temporary files.
+ */
+const char *gr_tmp_path ();
+
+#endif /* _GR_TMP_PATH_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_types.h b/gnuradio-core/src/lib/runtime/gr_types.h
new file mode 100644
index 0000000000..370ca56424
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_types.h
@@ -0,0 +1,63 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_GR_TYPES_H
+#define INCLUDED_GR_TYPES_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<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-core/src/lib/runtime/gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
new file mode 100644
index 0000000000..3586c4c73d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc
@@ -0,0 +1,291 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf.h>
+#include <assert.h>
+#include <stdexcept>
+#include <gr_preferences.h>
+#include <stdio.h>
+#include <gr_local_sighandler.h>
+
+// all the factories we know about
+#include <gr_vmcircbuf_createfilemapping.h>
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+
+static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";
+
+gr_vmcircbuf::~gr_vmcircbuf ()
+{
+}
+
+gr_vmcircbuf_factory::~gr_vmcircbuf_factory ()
+{
+}
+
+// ----------------------------------------------------------------
+
+static gr_vmcircbuf_factory *s_default_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysconfig::get_default_factory ()
+{
+ if (s_default_factory)
+ return s_default_factory;
+
+ bool verbose = false;
+
+ std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+ const char *name = gr_preferences::get (FACTORY_PREF_KEY);
+
+ if (name){
+ for (unsigned int i = 0; i < all.size (); i++){
+ if (strcmp (name, all[i]->name ()) == 0){
+ s_default_factory = all[i];
+ if (verbose)
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n",
+ s_default_factory->name ());
+ return s_default_factory;
+ }
+ }
+ }
+
+ // either we don't have a default, or the default named is not in our
+ // list of factories. Find the first factory that works.
+
+ if (verbose)
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n");
+
+ for (unsigned int i = 0; i < all.size (); i++){
+ if (test_factory (all[i], verbose)){
+ set_default_factory (all[i]);
+ return s_default_factory;
+ }
+ }
+
+ // We're screwed!
+
+ fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n");
+ throw std::runtime_error ("gr_vmcircbuf_sysconfig");
+}
+
+std::vector<gr_vmcircbuf_factory *>
+gr_vmcircbuf_sysconfig::all_factories ()
+{
+ std::vector<gr_vmcircbuf_factory *> result;
+
+ result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ());
+ result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
+ result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
+ result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ());
+
+ return result;
+}
+
+void
+gr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f)
+{
+ gr_preferences::set (FACTORY_PREF_KEY, f->name ());
+ s_default_factory = f;
+}
+
+
+// ------------------------------------------------------------------------
+// test code for vmcircbuf factories
+// ------------------------------------------------------------------------
+
+static void
+init_buffer (gr_vmcircbuf *c, int counter, int size)
+{
+ unsigned int *p = (unsigned int *) c->pointer_to_first_copy ();
+ for (unsigned int i = 0; i < size / sizeof (int); i++)
+ p[i] = counter + i;
+}
+
+static bool
+check_mapping (gr_vmcircbuf *c, int counter, int size, char *msg, bool verbose)
+{
+ bool ok = true;
+
+ if (verbose)
+ fprintf (stderr, "... %s", msg);
+
+ unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy ();
+ unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy ();
+
+ // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2);
+
+ for (unsigned int i = 0; i < size / sizeof (int); i++){
+ if (p1[i] != counter + i){
+ ok = false;
+ if (verbose)
+ fprintf (stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
+ break;
+ }
+ if (p2[i] != counter + i){
+ if (verbose)
+ fprintf (stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
+ ok = false;
+ break;
+ }
+ }
+
+ if (ok && verbose){
+ fprintf (stderr, " OK\n");
+ }
+ return ok;
+}
+
+static char *
+memsize (int size)
+{
+ static char buf[100];
+ if (size >= (1 << 20)){
+ snprintf (buf, sizeof (buf), "%dMB", size / (1 << 20));
+ }
+ else if (size >= (1 << 10)){
+ snprintf (buf, sizeof (buf), "%dKB", size / (1 << 10));
+ }
+ else {
+ snprintf (buf, sizeof (buf), "%d", size);
+ }
+ return buf;
+}
+
+static bool
+test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
+{
+ bool ok = true;
+ int counter[n];
+ gr_vmcircbuf *c[n];
+ int cum_size = 0;
+
+ for (int i = 0; i < n; i++){
+ counter[i] = *start_ptr;
+ *start_ptr += size;
+ if ((c[i] = factory->make (size)) == 0){
+ if (verbose)
+ fprintf (stderr,
+ "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n",
+ i + 1, size, memsize (cum_size));
+ return false;
+ }
+ init_buffer (c[i], counter[i], size);
+ cum_size += size;
+ }
+
+ for (int i = 0; i < n; i++){
+ char msg[100];
+ snprintf (msg, sizeof (msg), "test_a_bunch_%dx%s[%d]", n, memsize (size), i);
+ ok &= check_mapping (c[i], counter[i], size, msg, verbose);
+ }
+
+ for (int i = 0; i < n; i++){
+ delete c[i];
+ c[i] = 0;
+ }
+
+ return ok;
+}
+
+static bool
+standard_tests (gr_vmcircbuf_factory *f, int verbose)
+{
+ if (verbose >= 1)
+ fprintf (stderr, "Testing %s...\n", f->name ());
+
+ bool v = verbose >= 2;
+ int granularity = f->granularity ();
+ int start = 0;
+ bool ok = true;
+
+ ok &= test_a_bunch (f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB
+
+ if (ok){
+ ok &= test_a_bunch (f, 64, 4 * granularity, &start, v); // 256 x 16KB = 4MB
+ ok &= test_a_bunch (f, 32, 4 * (1L << 20), &start, v); // 32 x 4MB = 64MB
+ ok &= test_a_bunch (f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB
+ }
+
+ if (verbose >= 1)
+ fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n");
+
+ return ok;
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose)
+{
+ // Install local signal handlers for SIGSEGV and SIGBUS.
+ // If something goes wrong, these signals may be invoked.
+
+#ifdef SIGSEGV
+ gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGBUS
+ gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal);
+#endif
+#ifdef SIGSYS
+ gr_local_sighandler sigsys (SIGSYS, gr_local_sighandler::throw_signal);
+#endif
+
+ try {
+ return standard_tests (f, verbose);
+ }
+ catch (gr_signal &sig){
+ if (verbose){
+ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+ fprintf (stderr,
+ "gr_vmcircbuf_factory::test_factory (%s): caught %s\n",
+ f->name (), sig.name().c_str());
+ return false;
+ }
+ }
+ catch (...){
+ if (verbose){
+ fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
+ fprintf (stderr,
+ "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
+ f->name ());
+ }
+ return false;
+ }
+ return false; // never gets here. shut compiler up.
+}
+
+bool
+gr_vmcircbuf_sysconfig::test_all_factories (int verbose)
+{
+ bool ok = false;
+
+ std::vector<gr_vmcircbuf_factory *> all = all_factories ();
+
+ for (unsigned int i = 0; i < all.size (); i++)
+ ok |= test_factory (all[i], verbose);
+
+ return ok;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
new file mode 100644
index 0000000000..e2af935877
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.h
@@ -0,0 +1,120 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_H_
+#define _GR_VMCIRCBUF_H_
+
+#include <vector>
+
+/*!
+ * \brief abstract class to implement doubly mapped virtual memory circular buffers
+ */
+class gr_vmcircbuf {
+ protected:
+ int d_size;
+ char *d_base;
+
+ // CREATORS
+ gr_vmcircbuf (int size) : d_size (size), d_base (0) {};
+
+ public:
+ virtual ~gr_vmcircbuf ();
+
+ // ACCESSORS
+ void *pointer_to_first_copy () const { return d_base; }
+ void *pointer_to_second_copy () const { return d_base + d_size; }
+};
+
+/*!
+ * \brief abstract factory for creating circular buffers
+ */
+class gr_vmcircbuf_factory {
+ protected:
+ gr_vmcircbuf_factory () {};
+ virtual ~gr_vmcircbuf_factory ();
+
+ public:
+
+ /*!
+ * \brief return name of this factory
+ */
+ virtual const char *name () const = 0;
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity () = 0;
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size) = 0;
+};
+
+/*
+ * \brief pulls together all implementations of gr_vmcircbuf
+ */
+class gr_vmcircbuf_sysconfig {
+ public:
+
+ /*
+ * \brief return the single instance of the default factory.
+ *
+ * returns the default factory to use if it's already defined,
+ * else find the first working factory and use it.
+ */
+ static gr_vmcircbuf_factory *get_default_factory ();
+
+
+ static int granularity () { return get_default_factory()->granularity(); }
+ static gr_vmcircbuf *make (int size) { return get_default_factory()->make(size); }
+
+
+ // N.B. not all factories are guaranteed to work.
+ // It's too hard to check everything at config time, so we check at runtime
+ static std::vector<gr_vmcircbuf_factory *> all_factories ();
+
+ // make this factory the default
+ static void set_default_factory (gr_vmcircbuf_factory *f);
+
+ /*!
+ * \brief Does this factory really work?
+ *
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_factory (gr_vmcircbuf_factory *f, int verbose);
+
+ /*!
+ * \brief Test all factories, return true if at least one of them works
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_all_factories (int verbose);
+};
+
+
+#endif /* _GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
new file mode 100644
index 0000000000..8f3540b4b4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc
@@ -0,0 +1,191 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+#include <gr_vmcircbuf_createfilemapping.h>
+
+
+gr_vmcircbuf_createfilemapping::gr_vmcircbuf_createfilemapping (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_CREATEFILEMAPPING)
+ fprintf (stderr, "%s: createfilemapping is not available\n",__FUNCTION__);
+ throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+#else
+ static int s_seg_counter = 0;
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_createfilemapping: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
+ }
+
+ char seg_name[1024];
+ snprintf (seg_name, sizeof (seg_name), "/gnuradio-%d-%d", getpid (), s_seg_counter);
+
+ d_handle = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ size, // buffer size
+ seg_name); // name of mapping object
+
+ s_seg_counter++;
+ if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
+ char msg[1024];
+ snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s] :%d", seg_name,(int)GetLastError());
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ int i = 0;
+ d_first_copy = d_second_copy = NULL;
+
+ while (i++ < 8 && d_second_copy == NULL){
+ // keep the first map allocation to force allocation in a new address
+ // space
+ LPVOID first_tmp = d_first_copy;
+
+ d_first_copy = MapViewOfFile((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size);
+
+ if (d_first_copy == NULL){
+ if (first_tmp)
+ UnmapViewOfFile(first_tmp);
+
+ CloseHandle(d_handle); // cleanup
+ char msg[1024];
+ snprintf (msg, sizeof (msg),
+ "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFile (1) :%d", (int)GetLastError());
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ // NOTE: d_second_copy will be NULL if MapViewFileEx() fails to allocate the
+ // requested address space
+ d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ (char *)d_first_copy + size);//(LPVOID) ((char *)d_first_copy + size));
+
+ if (first_tmp)
+ UnmapViewOfFile(first_tmp);
+
+#ifdef DEBUG
+ fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p, %d\n",
+ (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size,i);
+#endif
+ }
+
+ if (d_second_copy == NULL){ // cleanup
+ fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: non contiguous mmap - %p %p %p %p\n",
+ d_first_copy, d_second_copy, size, (char *)d_first_copy + size);
+ UnmapViewOfFile(d_first_copy);
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
+ }
+
+ // Now remember the important stuff
+ d_base = (char *) d_first_copy;
+ d_size = size;
+#endif /*HAVE_CREATEFILEMAPPING*/
+}
+
+gr_vmcircbuf_createfilemapping::~gr_vmcircbuf_createfilemapping ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+ if (UnmapViewOfFile(d_first_copy) == 0)
+ {
+ perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)");
+ }
+ d_base=NULL;
+ if (UnmapViewOfFile(d_second_copy) == 0)
+ {
+ perror ("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)");
+ }
+ //d_second=NULL;
+ CloseHandle(d_handle);
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_createfilemapping_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_createfilemapping_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+ s_the_factory = new gr_vmcircbuf_createfilemapping_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_createfilemapping_factory::granularity ()
+{
+#ifdef HAVE_CREATEFILEMAPPING
+ // return 65536;//TODO, check, is this needed or can we just use gr_pagesize()
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
+ return (int)system_info.dwAllocationGranularity;
+#else
+ return gr_pagesize ();
+#endif
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_createfilemapping_factory::make (int size)
+{
+ try
+ {
+ return new gr_vmcircbuf_createfilemapping (size);
+ }
+ catch (...)
+ {
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
new file mode 100644
index 0000000000..f7113cf4fd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+#define _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
+
+#include <gr_vmcircbuf.h>
+
+#ifdef HAVE_CREATEFILEMAPPING
+#include <windows.h>
+#endif
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping : public gr_vmcircbuf
+{
+ public:
+ // CREATORS
+ gr_vmcircbuf_createfilemapping (int size);
+ virtual ~gr_vmcircbuf_createfilemapping ();
+#ifdef HAVE_CREATEFILEMAPPING
+ private:
+ HANDLE d_handle;
+ LPVOID d_first_copy;
+ LPVOID d_second_copy;
+#endif
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_createfilemapping_factory : public gr_vmcircbuf_factory
+{
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_createfilemapping_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_CREATEFILEMAPPING_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
new file mode 100644
index 0000000000..65fa1183b4
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc
@@ -0,0 +1,205 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_shm_open.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_shm_open::gr_vmcircbuf_mmap_shm_open (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN)
+ fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+#else
+ static int s_seg_counter = 0;
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ int shm_fd = -1;
+ char seg_name[1024];
+ static bool portable_format = true;
+
+ // open a new named shared memory segment
+
+ while (1){
+ if (portable_format){
+
+ // This is the POSIX recommended "portable format".
+ // Of course the "portable format" doesn't work on some systems...
+
+ snprintf (seg_name, sizeof (seg_name),
+ "/gnuradio-%d-%d", getpid (), s_seg_counter);
+ }
+ else {
+
+ // Where the "portable format" doesn't work, we try building
+ // a full filesystem pathname pointing into a suitable temporary directory.
+
+ snprintf (seg_name, sizeof (seg_name),
+ "%s/gnuradio-%d-%d", gr_tmp_path (), getpid (), s_seg_counter);
+ }
+
+ shm_fd = shm_open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (shm_fd == -1 && errno == EACCES && portable_format){
+ portable_format = false;
+ continue; // try again using "non-portable format"
+ }
+
+ s_seg_counter++;
+
+ if (shm_fd == -1){
+ if (errno == EEXIST) // Named segment already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name);
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+ break;
+ }
+
+ // We've got a new shared memory segment fd open.
+ // Now set it's length to 2x what we really want and mmap it in.
+
+ if (ftruncate (shm_fd, (off_t) 2 * size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ void *first_copy = mmap (0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t) 0);
+
+ if (first_copy == MAP_FAILED){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: mmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // unmap the 2nd half
+ if (munmap ((char *) first_copy + size, size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: munmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+
+ void *second_copy = mmap ((char *) first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t) 0);
+
+ if (second_copy == MAP_FAILED){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: mmap (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+#if 0 // OS/X doesn't allow you to resize the segment
+
+ // cut the shared memory segment down to size
+ if (ftruncate (shm_fd, (off_t) size) == -1){
+ close (shm_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+#endif
+
+ close (shm_fd); // fd no longer needed. The mapping is retained.
+
+ if (shm_unlink (seg_name) == -1){ // unlink the seg_name.
+ perror ("gr_vmcircbuf_mmap_shm_open: shm_unlink");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
+ }
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_shm_open::~gr_vmcircbuf_mmap_shm_open ()
+{
+#if defined(HAVE_MMAP)
+ if (munmap (d_base, 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_mmap_shm_open: munmap (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_shm_open_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_shm_open_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_mmap_shm_open_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_shm_open_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_shm_open_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_mmap_shm_open (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
new file mode 100644
index 0000000000..4b1feafff2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.h
@@ -0,0 +1,65 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+#define _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_mmap_shm_open (int size);
+ virtual ~gr_vmcircbuf_mmap_shm_open ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_shm_open_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_mmap_shm_open_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
new file mode 100644
index 0000000000..a07df779c0
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc
@@ -0,0 +1,198 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_mmap_tmpfile.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <gr_pagesize.h>
+#include <gr_tmp_path.h>
+
+
+gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_MMAP)
+ fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+#else
+
+ if (size <= 0 || (size % gr_pagesize ()) != 0){
+ fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ int seg_fd = -1;
+ char seg_name[1024];
+
+ static int s_seg_counter = 0;
+
+
+ // open a temporary file that we'll map in a bit later
+
+ while (1){
+ snprintf (seg_name, sizeof (seg_name),
+ "%s/gnuradio-%d-%d-XXXXXX", gr_tmp_path (), getpid (), s_seg_counter);
+ s_seg_counter++;
+
+ seg_fd = open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if (seg_fd == -1){
+ if (errno == EEXIST) // File already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf (msg, sizeof (msg),
+ "gr_vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
+ perror (msg);
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+ break;
+ }
+
+ if (unlink (seg_name) == -1){
+ perror ("gr_vmcircbuf_mmap_tmpfile: unlink");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // We've got a valid file descriptor to a tmp file.
+ // Now set it's length to 2x what we really want and mmap it in.
+
+ if (ftruncate (seg_fd, (off_t) 2 * size) == -1){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ void *first_copy = mmap (0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t) 0);
+
+ if (first_copy == MAP_FAILED){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: mmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // unmap the 2nd half
+ if (munmap ((char *) first_copy + size, size) == -1){
+ close (seg_fd); // cleanup
+ perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+
+ void *second_copy = mmap ((char *) first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t) 0);
+
+ if (second_copy == MAP_FAILED){
+ munmap(first_copy, size); // cleanup
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: mmap (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // check for contiguity
+ if ((char *) second_copy != (char *) first_copy + size){
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: non-contiguous second copy");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ // cut the tmp file down to size
+ if (ftruncate (seg_fd, (off_t) size) == -1){
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close (seg_fd);
+ perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (2)");
+ throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
+ }
+
+ close (seg_fd); // fd no longer needed. The mapping is retained.
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_mmap_tmpfile::~gr_vmcircbuf_mmap_tmpfile ()
+{
+#if defined(HAVE_MMAP)
+ if (munmap (d_base, 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_mmap_tmpfile: munmap (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_mmap_tmpfile_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_mmap_tmpfile_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_mmap_tmpfile_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_mmap_tmpfile_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_mmap_tmpfile_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_mmap_tmpfile (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
new file mode 100644
index 0000000000..3b9f5dba8a
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.h
@@ -0,0 +1,65 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+#define _GR_VMCIRCBUF_MMAP_TMPFILE_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_mmap_tmpfile (int size);
+ virtual ~gr_vmcircbuf_mmap_tmpfile ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_mmap_tmpfile_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_mmap_tmpfile_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_MMAP_TMPFILE_H_ */
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
new file mode 100644
index 0000000000..4b6fcfe338
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.cc
@@ -0,0 +1,192 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <gr_vmcircbuf_sysv_shm.h>
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <gr_pagesize.h>
+
+
+gr_vmcircbuf_sysv_shm::gr_vmcircbuf_sysv_shm (int size)
+ : gr_vmcircbuf (size)
+{
+#if !defined(HAVE_SYS_SHM_H)
+ fprintf (stderr, "gr_vmcircbuf_sysv_shm: sysv shared memory is not available\n");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+#else
+
+ int pagesize = gr_pagesize();
+
+ if (size <= 0 || (size % pagesize) != 0){
+ fprintf (stderr, "gr_vmcircbuf_sysv_shm: invalid size = %d\n", size);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ int shmid_guard = -1;
+ int shmid1 = -1;
+ int shmid2 = -1;
+
+ // We use this as a guard page. We'll map it read-only on both ends of the buffer.
+ // Ideally we'd map it no access, but I don't think that's possible with SysV
+ if ((shmid_guard = shmget (IPC_PRIVATE, pagesize, IPC_CREAT | 0400)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (0)");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ if ((shmid2 = shmget (IPC_PRIVATE, 2 * size + 2 * pagesize, IPC_CREAT | 0700)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (1)");
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ if ((shmid1 = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmget (2)");
+ shmctl (shmid2, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ void *first_copy = shmat (shmid2, 0, 0);
+ if (first_copy == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (1)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid2, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ shmctl (shmid2, IPC_RMID, 0);
+
+ // There may be a race between our detach and attach.
+ //
+ // If the system allocates all shared memory segments at the same
+ // virtual addresses in all processes and if the system allocates
+ // some other segment to first_copy or first_copoy + size between
+ // our detach and attach, the attaches below could fail [I've never
+ // seen it fail for this reason].
+
+ shmdt (first_copy);
+
+ // first read-only guard page
+ if (shmat (shmid_guard, first_copy, SHM_RDONLY) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (2)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // first copy
+ if (shmat (shmid1, (char *) first_copy + pagesize, 0) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (3)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt (first_copy);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // second copy
+ if (shmat (shmid1, (char *) first_copy + pagesize + size, 0) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (4)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt ((char *)first_copy + pagesize);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ // second read-only guard page
+ if (shmat (shmid_guard, (char *) first_copy + pagesize + 2 * size, SHM_RDONLY) == (void *) -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmat (5)");
+ shmctl (shmid_guard, IPC_RMID, 0);
+ shmctl (shmid1, IPC_RMID, 0);
+ shmdt (first_copy);
+ shmdt ((char *)first_copy + pagesize);
+ shmdt ((char *)first_copy + pagesize + size);
+ throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
+ }
+
+ shmctl (shmid1, IPC_RMID, 0);
+ shmctl (shmid_guard, IPC_RMID, 0);
+
+ // Now remember the important stuff
+
+ d_base = (char *) first_copy + pagesize;
+ d_size = size;
+#endif
+}
+
+gr_vmcircbuf_sysv_shm::~gr_vmcircbuf_sysv_shm ()
+{
+#if defined(HAVE_SYS_SHM_H)
+ if (shmdt (d_base - gr_pagesize()) == -1
+ || shmdt (d_base) == -1
+ || shmdt (d_base + d_size) == -1
+ || shmdt (d_base + 2 * d_size) == -1){
+ perror ("gr_vmcircbuf_sysv_shm: shmdt (2)");
+ }
+#endif
+}
+
+// ----------------------------------------------------------------
+// The factory interface
+// ----------------------------------------------------------------
+
+
+gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::s_the_factory = 0;
+
+gr_vmcircbuf_factory *
+gr_vmcircbuf_sysv_shm_factory::singleton ()
+{
+ if (s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr_vmcircbuf_sysv_shm_factory ();
+ return s_the_factory;
+}
+
+int
+gr_vmcircbuf_sysv_shm_factory::granularity ()
+{
+ return gr_pagesize ();
+}
+
+gr_vmcircbuf *
+gr_vmcircbuf_sysv_shm_factory::make (int size)
+{
+ try {
+ return new gr_vmcircbuf_sysv_shm (size);
+ }
+ catch (...){
+ return 0;
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
new file mode 100644
index 0000000000..9a8c128a52
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_sysv_shm.h
@@ -0,0 +1,65 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GR_VMCIRCBUF_SYSV_SHM_H_
+#define _GR_VMCIRCBUF_SYSV_SHM_H_
+
+#include <gr_vmcircbuf.h>
+
+/*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm : public gr_vmcircbuf {
+ public:
+
+ // CREATORS
+
+ gr_vmcircbuf_sysv_shm (int size);
+ virtual ~gr_vmcircbuf_sysv_shm ();
+};
+
+/*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+class gr_vmcircbuf_sysv_shm_factory : public gr_vmcircbuf_factory {
+ private:
+ static gr_vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr_vmcircbuf_factory *singleton ();
+
+ virtual const char *name () const { return "gr_vmcircbuf_sysv_shm_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity ();
+
+ /*!
+ * \brief return a gr_vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr_vmcircbuf *make (int size);
+};
+
+#endif /* _GR_VMCIRCBUF_SYSV_SHM_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
new file mode 100644
index 0000000000..e3a21be350
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
@@ -0,0 +1,89 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_block.h>
+#include <gr_block.h>
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_null_sink.h>
+#include <gr_null_source.h>
+
+
+// ----------------------------------------------------------------
+
+
+void
+qa_gr_block::t0 ()
+{
+ // test creation of sources
+ gr_block_sptr src1 (gr_make_null_source (sizeof (int)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src1->name ());
+ CPPUNIT_ASSERT_EQUAL (0, src1->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src1->output_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (int),
+ src1->output_signature()->sizeof_stream_item (0));
+
+ gr_block_sptr src2 (gr_make_null_source (sizeof (short)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_source"), src2->name ());
+ CPPUNIT_ASSERT_EQUAL (0, src2->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, src2->output_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (short),
+ src2->output_signature()->sizeof_stream_item (0));
+}
+
+
+void
+qa_gr_block::t1 ()
+{
+ // test creation of sinks
+ gr_block_sptr dst1 (gr_make_null_sink (sizeof (int)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst1->name ());
+ CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, dst1->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (int),
+ dst1->input_signature()->sizeof_stream_item (0));
+
+ CPPUNIT_ASSERT_EQUAL (0, dst1->output_signature()->max_streams ());
+
+ gr_block_sptr dst2 (gr_make_null_sink (sizeof (short)));
+ CPPUNIT_ASSERT_EQUAL (std::string ("null_sink"), dst2->name ());
+ CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->min_streams ());
+ CPPUNIT_ASSERT_EQUAL (1, dst2->input_signature()->max_streams ());
+ CPPUNIT_ASSERT_EQUAL (sizeof (short),
+ dst2->input_signature()->sizeof_stream_item (0));
+ CPPUNIT_ASSERT_EQUAL (0, dst2->output_signature()->max_streams ());
+}
+
+void
+qa_gr_block::t2 ()
+{
+}
+
+void
+qa_gr_block::t3 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.h b/gnuradio-core/src/lib/runtime/qa_gr_block.h
new file mode 100644
index 0000000000..6e30825146
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.h
@@ -0,0 +1,48 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_BLOCK_H
+#define INCLUDED_QA_GR_BLOCK_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_block : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_block);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+
+#endif /* INCLUDED_QA_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
new file mode 100644
index 0000000000..5c549d0b98
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
@@ -0,0 +1,307 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_buffer.h>
+#include <gr_buffer.h>
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <gr_random.h>
+
+static void
+leak_check (void f ())
+{
+ long buffer_count = gr_buffer_ncurrently_allocated ();
+ long buffer_reader_count = gr_buffer_reader_ncurrently_allocated ();
+
+ f ();
+
+ CPPUNIT_ASSERT_EQUAL (buffer_reader_count, gr_buffer_reader_ncurrently_allocated ());
+ CPPUNIT_ASSERT_EQUAL (buffer_count, gr_buffer_ncurrently_allocated ());
+}
+
+
+// ----------------------------------------------------------------------------
+// test single writer, no readers...
+//
+
+static void
+t0_body ()
+{
+ int nitems = 4000 / sizeof (int);
+ int counter = 0;
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+
+ int last_sa;
+ int sa;
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+ last_sa = sa;
+
+ for (int i = 0; i < 5; i++){
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT_EQUAL (last_sa, sa);
+ last_sa = sa;
+
+ int *p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa; j++)
+ *p++ = counter++;
+
+ buf->update_write_pointer (sa);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// test single writer, single reader
+//
+
+static void
+t1_body ()
+ {
+ int nitems = 4000 / sizeof (int);
+ int write_counter = 0;
+ int read_counter = 0;
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+
+
+ int sa;
+
+ // write 1/3 of buffer
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+
+ int *p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa/3; j++){
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer (sa/3);
+
+
+ // write the next 1/3 (1/2 of what's left)
+
+ sa = buf->space_available ();
+ CPPUNIT_ASSERT (sa > 0);
+
+ p = (int *) buf->write_pointer ();
+ CPPUNIT_ASSERT (p != 0);
+
+ for (int j = 0; j < sa/2; j++){
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer (sa/2);
+
+
+ // check that we can read it OK
+
+ int ia = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (write_counter, ia);
+
+ int *rp = (int *) r1->read_pointer ();
+ CPPUNIT_ASSERT (rp != 0);
+
+ for (int i = 0; i < ia/2; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (ia/2);
+
+ // read the rest
+
+ ia = r1->items_available ();
+ rp = (int *) r1->read_pointer ();
+ CPPUNIT_ASSERT (rp != 0);
+
+ for (int i = 0; i < ia; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (ia);
+}
+
+// ----------------------------------------------------------------------------
+// single writer, single reader: check wrap-around
+//
+
+static void
+t2_body ()
+{
+ // 64K is the largest granularity we've seen so far (MS windows file mapping).
+ // This allows a bit of "white box testing"
+
+ int nitems = (64 * (1L << 10)) / sizeof (int); // 64K worth of ints
+
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 1));
+
+ int read_counter = 0;
+ int write_counter = 0;
+ int n;
+ int *wp = 0;
+ int *rp = 0;
+
+ // Write 3/4 of buffer
+
+ n = (int) (buf->space_available () * 0.75);
+ wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer (n);
+
+ // Now read it all
+
+ int m = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (n, m);
+ rp = (int *) r1->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (m);
+
+ // Now write as much as we can.
+ // This will wrap around the buffer
+
+ n = buf->space_available ();
+ CPPUNIT_ASSERT_EQUAL (nitems - 1, n); // white box test
+ wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer (n);
+
+ // now read it all
+
+ m = r1->items_available ();
+ CPPUNIT_ASSERT_EQUAL (n, m);
+ rp = (int *) r1->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer (m);
+
+}
+
+// ----------------------------------------------------------------------------
+// single writer, N readers, randomized order and lengths
+// ----------------------------------------------------------------------------
+
+static void
+t3_body ()
+{
+ int nitems = (64 * (1L << 10)) / sizeof (int);
+
+ static const int N = 5;
+ gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int)));
+ gr_buffer_reader_sptr reader[N];
+ int read_counter[N];
+ int write_counter = 0;
+ gr_random random;
+
+ for (int i = 0; i < N; i++){
+ read_counter[i] = 0;
+ reader[i] = gr_buffer_add_reader (buf, 1);
+ }
+
+ for (int lc = 0; lc < 1000; lc++){
+
+ // write some
+
+ int n = (int) (buf->space_available () * random.ran1 ());
+ int *wp = (int *) buf->write_pointer ();
+
+ for (int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+
+ buf->update_write_pointer (n);
+
+ // pick a random reader and read some
+
+ int r = (int) (N * random.ran1 ());
+ CPPUNIT_ASSERT (0 <= r && r < N);
+
+ int m = reader[r]->items_available ();
+ int *rp = (int *) reader[r]->read_pointer ();
+
+ for (int i = 0; i < m; i++){
+ CPPUNIT_ASSERT_EQUAL (read_counter[r], *rp);
+ read_counter[r]++;
+ rp++;
+ }
+ reader[r]->update_read_pointer (m);
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+void
+qa_gr_buffer::t0 ()
+{
+ leak_check (t0_body);
+}
+
+void
+qa_gr_buffer::t1 ()
+{
+ leak_check (t1_body);
+}
+
+void
+qa_gr_buffer::t2 ()
+{
+ leak_check (t2_body);
+}
+
+void
+qa_gr_buffer::t3 ()
+{
+ leak_check (t3_body);
+}
+
+void
+qa_gr_buffer::t4 ()
+{
+}
+
+void
+qa_gr_buffer::t5 ()
+{
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.h b/gnuradio-core/src/lib/runtime/qa_gr_buffer.h
new file mode 100644
index 0000000000..700629cc4c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_buffer.h
@@ -0,0 +1,53 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_BUFFER_H
+#define INCLUDED_QA_GR_BUFFER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_buffer : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_buffer);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST (t1);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST (t4);
+ CPPUNIT_TEST (t5);
+ CPPUNIT_TEST_SUITE_END ();
+
+
+ private:
+
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+ void t4 ();
+ void t5 ();
+};
+
+
+
+#endif /* INCLUDED_QA_GR_BUFFER_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc
new file mode 100644
index 0000000000..c180e7b742
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.cc
@@ -0,0 +1,55 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <qa_gr_io_signature.h>
+#include <gr_io_signature.h>
+
+void
+qa_gr_io_signature::t0 ()
+{
+ gr_make_io_signature (1, 1, sizeof (int));
+}
+
+void
+qa_gr_io_signature::t1 ()
+{
+ gr_make_io_signature (3, 1, sizeof (int)); // throws std::invalid_argument
+}
+
+void
+qa_gr_io_signature::t2 ()
+{
+ gr_io_signature_sptr p =
+ gr_make_io_signature (3, gr_io_signature::IO_INFINITE, sizeof (int));
+
+ CPPUNIT_ASSERT_EQUAL (p->min_streams (), 3);
+ CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item (0), sizeof (int));
+}
+
+void
+qa_gr_io_signature::t3 ()
+{
+}
+
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
new file mode 100644
index 0000000000..225ce80687
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_io_signature.h
@@ -0,0 +1,47 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef INCLUDED_QA_GR_IO_SIGNATURE_H
+#define INCLUDED_QA_GR_IO_SIGNATURE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_io_signature : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_io_signature);
+ CPPUNIT_TEST (t0);
+ CPPUNIT_TEST_EXCEPTION (t1, std::invalid_argument);
+ CPPUNIT_TEST (t2);
+ CPPUNIT_TEST (t3);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void t0 ();
+ void t1 ();
+ void t2 ();
+ void t3 ();
+
+};
+
+#endif /* INCLUDED_QA_GR_IO_SIGNATURE_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc
new file mode 100644
index 0000000000..f3c815a0d5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.cc
@@ -0,0 +1,40 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_vmcircbuf.h>
+#include <cppunit/TestAssert.h>
+#include <gr_vmcircbuf.h>
+#include <stdio.h>
+
+void
+qa_gr_vmcircbuf::test_all ()
+{
+ int verbose = 1; // summary
+
+ bool ok = gr_vmcircbuf_sysconfig::test_all_factories (verbose);
+
+ CPPUNIT_ASSERT_EQUAL (true, ok);
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h
new file mode 100644
index 0000000000..41f69c3534
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_vmcircbuf.h
@@ -0,0 +1,39 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef _QA_GR_VMCIRCBUF_H_
+#define _QA_GR_VMCIRCBUF_H_
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_gr_vmcircbuf : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE (qa_gr_vmcircbuf);
+ CPPUNIT_TEST (test_all);
+ CPPUNIT_TEST_SUITE_END ();
+
+ private:
+ void test_all ();
+};
+
+
+#endif /* _QA_GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
new file mode 100644
index 0000000000..668628f2ac
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -0,0 +1,49 @@
+/*
+ * 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the gr
+ * directory into a single test suite. As you create new test cases,
+ * add them here.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <qa_runtime.h>
+#include <qa_gr_vmcircbuf.h>
+#include <qa_gr_io_signature.h>
+#include <qa_gr_block.h>
+#include <qa_gr_buffer.h>
+
+CppUnit::TestSuite *
+qa_runtime::suite ()
+{
+ CppUnit::TestSuite *s = new CppUnit::TestSuite ("runtime");
+
+ s->addTest (qa_gr_vmcircbuf::suite ());
+ s->addTest (qa_gr_io_signature::suite ());
+ s->addTest (qa_gr_block::suite ());
+ s->addTest (qa_gr_buffer::suite ());
+
+ return s;
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.h b/gnuradio-core/src/lib/runtime/qa_runtime.h
new file mode 100644
index 0000000000..5862b1ea20
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.h
@@ -0,0 +1,37 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _QA_RUNTIME_H_
+#define _QA_RUNTIME_H_
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the runtime directory
+
+class qa_runtime {
+ public:
+ //! return suite of tests for all of runtime directory
+ static CppUnit::TestSuite *suite ();
+};
+
+
+#endif /* _QA_RUNTIME_H_ */
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
new file mode 100644
index 0000000000..d8dd34f1ee
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -0,0 +1,49 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+%{
+#include <gr_runtime.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+#include <gr_block.h>
+#include <gr_block_detail.h>
+#include <gr_single_threaded_scheduler.h>
+#include <gr_message.h>
+#include <gr_msg_handler.h>
+#include <gr_msg_queue.h>
+#include <gr_dispatcher.h>
+#include <gr_error_handler.h>
+#include <gr_realtime.h>
+%}
+
+%include <gr_io_signature.i>
+%include <gr_buffer.i>
+%include <gr_block.i>
+%include <gr_block_detail.i>
+%include <gr_swig_block_magic.i>
+%include <gr_single_threaded_scheduler.i>
+%include <gr_message.i>
+%include <gr_msg_handler.i>
+%include <gr_msg_queue.i>
+%include <gr_dispatcher.i>
+%include <gr_error_handler.i>
+%include <gr_realtime.i>
diff --git a/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc b/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc
new file mode 100644
index 0000000000..26bfa6d2db
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/test_shared_block_ptr.cc
@@ -0,0 +1,53 @@
+/* -*- 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 2, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <gr_shared_block_sptr.h>
+#include <gr_vector_source_i.h>
+
+gr_block_sptr
+foo (gr_vector_source_i_sptr s)
+{
+ return gr_block_sptr (s);
+}
+
+typedef gr_shared_block_sptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+//typedef boost::shared_ptr<gr_vector_source_i> gr_vector_source_i_ptrX;
+
+gr_vector_source_i_ptrX
+bar (gr_vector_source_i *s)
+{
+ return gr_vector_source_i_ptrX (s);
+}
+
+gr_block_sptr
+baz_1 (gr_vector_source_i_ptrX s)
+{
+ return gr_block_sptr (s);
+}
+
+#if 0
+gr_block_sptr
+baz_2 (gr_vector_source_i_ptrX s)
+{
+ return s.block_sptr ();
+}
+#endif