Merged r11500:11506 from features/msg-passing into trunk. Work-in-progress, passes...
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Sat, 1 Aug 2009 14:56:28 +0000 (14:56 +0000)
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>
Sat, 1 Aug 2009 14:56:28 +0000 (14:56 +0000)
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11524 221aa14e-8319-0410-a670-987f0aec2ac5

12 files changed:
config/grc_gruel.m4
gnuradio-core/src/lib/runtime/gr_basic_block.cc
gnuradio-core/src/lib/runtime/gr_basic_block.h
gruel/src/include/gruel/Makefile.am
gruel/src/include/gruel/msg_accepter.h [new file with mode: 0644]
gruel/src/include/gruel/msg_accepter_msgq.h [new file with mode: 0644]
gruel/src/include/gruel/msg_queue.h [new file with mode: 0644]
gruel/src/lib/Makefile.am
gruel/src/lib/msg/Makefile.am [new file with mode: 0644]
gruel/src/lib/msg/msg_accepter.cc [new file with mode: 0644]
gruel/src/lib/msg/msg_accepter_msgq.cc [new file with mode: 0644]
gruel/src/lib/msg/msg_queue.cc [new file with mode: 0644]

index ae8fe81ad0445347cd1dc5fd740a4ed79b163ec4..7295714341b63edcb9ad43417db5933aeffe2a34 100644 (file)
@@ -43,6 +43,7 @@ AC_DEFUN([GRC_GRUEL],[
        gruel/src/include/gruel/inet.h \
         gruel/src/lib/Makefile \
        gruel/src/lib/pmt/Makefile \
+       gruel/src/lib/msg/Makefile \
        gruel/src/scheme/Makefile \
        gruel/src/scheme/gnuradio/Makefile \
     ])
index e94e089e2fcdd7d49981c5cd0954974f2a086b92..71ccc02454c591d21eb31efd094c7da063de5725 100644 (file)
@@ -27,6 +27,8 @@
 #include <gr_basic_block.h>
 #include <stdexcept>
 
+using namespace pmt;
+
 static long s_next_id = 0;
 static long s_ncurrently_allocated = 0;
 
@@ -39,7 +41,8 @@ gr_basic_block_ncurrently_allocated()
 gr_basic_block::gr_basic_block(const std::string &name,
                                gr_io_signature_sptr input_signature,
                                gr_io_signature_sptr output_signature) 
-  : d_name(name),
+  : gruel::msg_accepter_msgq(gruel::make_msg_queue(0)),
+    d_name(name),
     d_input_signature(input_signature),
     d_output_signature(output_signature),
     d_unique_id(s_next_id++),
index faaba1c8313ed294ee9c0ca70e4256c1dd0ff2e9..27ec0fd89b1d44ed39745fd835956cb92122b307 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2006,2008 Free Software Foundation, Inc.
+ * Copyright 2006,2008,2009 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
 #include <gr_runtime_types.h>
 #include <gr_sptr_magic.h>
 #include <boost/enable_shared_from_this.hpp>
+#include <gruel/msg_accepter_msgq.h>
 #include <string>
 
 /*!
  * \brief The abstract base class for all signal processing blocks.
  * \ingroup internal
  *
- * Basic blocks are the bare abstraction of an entity that has a name
- * and a set of inputs and outputs.  These are never instantiated
+ * Basic blocks are the bare abstraction of an entity that has a name,
+ * a set of inputs and outputs, and a message queue.  These are never instantiated
  * directly; rather, this is the abstract parent class of both gr_hier_block,
  * which is a recursive container, and gr_block, which implements actual
  * signal processing functions.
  */
 
-class gr_basic_block : public boost::enable_shared_from_this<gr_basic_block>
+class gr_basic_block : gruel::msg_accepter_msgq, public boost::enable_shared_from_this<gr_basic_block>
 {
 protected:
     friend class gr_flowgraph;
@@ -96,6 +97,17 @@ public:
      * and output gr_io_signatures.
      */
     virtual bool check_topology(int ninputs, int noutputs) { return true; }
+
+    /*!
+     * \brief Block message handler.
+     * 
+     * \param msg  Arbitrary message encapsulated as pmt::pmt_t
+     *
+     * This function is called by the runtime system whenever there are
+     * messages in its queue.  Blocks should override this to receive
+     * messages; the default behavior is to drop them on the floor.
+     */
+    virtual void handle_msg(pmt::pmt_t msg) { };
 };
 
 inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs)
index 622fbc2d3cb62ae68c3bee873c3b36ef974e03f0..c38c7fa3833d842a75e423446867ea6155492a90 100644 (file)
@@ -28,6 +28,9 @@ gruelincludedir = $(prefix)/include/gruel
 
 gruelinclude_HEADERS = \
        $(BUILT_SOURCES) \
+       msg_accepter.h \
+       msg_accepter_msgq.h \
+       msg_queue.h \
        pmt.h \
        pmt_pool.h \
        pmt_serial_tags.h \
diff --git a/gruel/src/include/gruel/msg_accepter.h b/gruel/src/include/gruel/msg_accepter.h
new file mode 100644 (file)
index 0000000..bc287af
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_MSG_ACCEPTER_H
+#define INCLUDED_MSG_ACCEPTER_H
+
+#include <gruel/pmt.h>
+
+namespace gruel {
+
+  /*!
+   * \brief Virtual base class that accepts messages
+   */
+  class msg_accepter
+  {
+  public:
+    msg_accepter() {};
+    virtual ~msg_accepter();
+
+    virtual void post(pmt::pmt_t msg) = 0;
+  };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_ACCEPTER_H */
diff --git a/gruel/src/include/gruel/msg_accepter_msgq.h b/gruel/src/include/gruel/msg_accepter_msgq.h
new file mode 100644 (file)
index 0000000..b14049d
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_MSG_ACCEPTER_MSGQ_H
+#define INCLUDED_MSG_ACCEPTER_MSGQ_H
+
+#include <gruel/msg_accepter.h>
+#include <gruel/msg_queue.h>
+
+namespace gruel {
+
+  /*!
+   * \brief Concrete class that accepts messages and inserts them into a message queue.
+   */
+  class msg_accepter_msgq : public msg_accepter 
+  {
+    msg_queue_sptr d_msg_queue;
+    
+  public:
+    msg_accepter_msgq(msg_queue_sptr msgq);
+    ~msg_accepter_msgq();
+
+    void post(pmt::pmt_t msg);
+
+    msg_queue_sptr msg_queue() const { return d_msg_queue; }
+  };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_ACCEPTER_MSGQ_H */
diff --git a/gruel/src/include/gruel/msg_queue.h b/gruel/src/include/gruel/msg_queue.h
new file mode 100644 (file)
index 0000000..c24313d
--- /dev/null
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+#ifndef INCLUDED_MSG_QUEUE_H
+#define INCLUDED_MSG_QUEUE_H
+
+#include <gruel/thread.h>
+#include <gruel/pmt.h>
+#include <deque>
+
+namespace gruel {
+
+  class msg_queue;
+  typedef boost::shared_ptr<msg_queue> msg_queue_sptr;
+
+  msg_queue_sptr make_msg_queue(unsigned int limit=0);
+
+  /*!
+   * \brief thread-safe message queue
+   */
+  class msg_queue {
+
+    gruel::mutex              d_mutex;
+    gruel::condition_variable d_not_empty;
+    gruel::condition_variable d_not_full;
+    unsigned int             d_limit;    // max # of messages in queue.  0 -> unbounded
+
+    std::deque<pmt::pmt_t>    d_msgs;
+
+  public:
+    msg_queue(unsigned int limit);
+    ~msg_queue();
+
+    /*!
+     * \brief Insert message at tail of queue.
+     * \param msg message
+     *
+     * Block if queue if full.
+     */
+    void insert_tail(pmt::pmt_t msg);
+
+    /*!
+     * \brief Delete message from head of queue and return it.
+     * Block if no message is available.
+     */
+    pmt::pmt_t delete_head();
+    
+    /*!
+     * \brief If there's a message in the q, delete it and return it.
+     * If no message is available, return pmt_t().
+     */
+    pmt::pmt_t delete_head_nowait();
+    
+    //! Delete all messages from the queue
+    void flush();
+
+    //! is the queue empty?
+    bool empty_p() const { return d_msgs.empty(); }
+  
+    //! is the queue full?
+    bool full_p() const { return d_limit != 0 && count() >= d_limit; }
+  
+    //! return number of messages in queue
+    unsigned int count() const { return d_msgs.size(); }
+
+    //! return limit on number of message in queue.  0 -> unbounded
+    unsigned int limit() const { return d_limit; }
+  };
+
+} /* namespace gruel */
+
+#endif /* INCLUDED_MSG_QUEUE_H */
index bf1ae731ad357e099d59dab10a9eb9b6360419fb..6dfb6787c804ad2f89aafff23c86d51a7488a1fc 100644 (file)
@@ -21,7 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
-SUBDIRS = pmt
+SUBDIRS = pmt msg
 
 AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
 
@@ -33,6 +33,7 @@ libgruel_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) -version-info 0:0:0
 # ----------------------------------------------------------------
 
 PMT_LIB = pmt/libpmt.la
+MSG_LIB = msg/libmsg.la
 
 # These are the source files that go into the gruel shared library
 libgruel_la_SOURCES =                  \
@@ -44,6 +45,5 @@ libgruel_la_SOURCES =                         \
 libgruel_la_LIBADD =                   \
        $(BOOST_THREAD_LIB)             \
        $(PMT_LIB)                      \
+       $(MSG_LIB)                      \
        -lstdc++
-
-
diff --git a/gruel/src/lib/msg/Makefile.am b/gruel/src/lib/msg/Makefile.am
new file mode 100644 (file)
index 0000000..13a6570
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Copyright 2009 Free Software Foundation, Inc.
+# 
+# This file is part of GNU Radio
+# 
+# GNU Radio is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+# 
+# GNU Radio is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GNU Radio; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street,
+# Boston, MA 02110-1301, USA.
+# 
+
+include $(top_srcdir)/Makefile.common
+
+AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(GRUEL_INCLUDES) $(WITH_INCLUDES)
+
+noinst_LTLIBRARIES = libmsg.la
+
+libmsg_la_SOURCES = \
+       msg_accepter.cc \
+       msg_accepter_msgq.cc \
+       msg_queue.cc
+
diff --git a/gruel/src/lib/msg/msg_accepter.cc b/gruel/src/lib/msg/msg_accepter.cc
new file mode 100644 (file)
index 0000000..64878f7
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gruel/msg_accepter.h>
+
+namespace gruel {
+
+  msg_accepter::~msg_accepter()
+  {
+    // NOP, required as virtual destructor
+  }
+
+} /* namespace gruel */
diff --git a/gruel/src/lib/msg/msg_accepter_msgq.cc b/gruel/src/lib/msg/msg_accepter_msgq.cc
new file mode 100644 (file)
index 0000000..64fe501
--- /dev/null
@@ -0,0 +1,48 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gruel/msg_accepter_msgq.h>
+
+using namespace pmt;
+
+namespace gruel {
+
+  msg_accepter_msgq::msg_accepter_msgq(msg_queue_sptr msgq)
+    : d_msg_queue(msgq)
+  {
+  }
+
+  msg_accepter_msgq::~msg_accepter_msgq()
+  {
+    // NOP, required as virtual destructor
+  }
+
+  void
+  msg_accepter_msgq::post(pmt_t msg)
+  {
+    d_msg_queue->insert_tail(msg);
+  }
+
+} /* namespace gruel */
diff --git a/gruel/src/lib/msg/msg_queue.cc b/gruel/src/lib/msg/msg_queue.cc
new file mode 100644 (file)
index 0000000..8d15f08
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2009 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gruel/msg_queue.h>
+#include <stdexcept>
+
+using namespace pmt;
+
+namespace gruel {
+
+  msg_queue_sptr
+  make_msg_queue(unsigned int limit)
+  {
+    return msg_queue_sptr(new msg_queue(limit));
+  }
+  
+  msg_queue::msg_queue(unsigned int limit)
+    : d_limit(limit)
+  {
+  }
+  
+  msg_queue::~msg_queue()
+  {
+    flush();
+  }
+
+  void
+  msg_queue::insert_tail(pmt_t msg)
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    while (full_p())
+      d_not_full.wait(guard);
+
+    d_msgs.push_back(msg);
+    d_not_empty.notify_one();
+  }
+
+  pmt_t
+  msg_queue::delete_head()
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    while (empty_p())
+      d_not_empty.wait(guard);
+
+    pmt_t m(d_msgs.front());
+    d_msgs.pop_front();
+
+    if (d_limit > 0)           // Unlimited length queues never block on write
+      d_not_full.notify_one();
+
+    return m;
+  }
+
+  pmt_t
+  msg_queue::delete_head_nowait()
+  {
+    gruel::scoped_lock guard(d_mutex);
+
+    if (empty_p())
+      return pmt_t();
+       
+    pmt_t m(d_msgs.front());
+    d_msgs.pop_front();
+
+    if (d_limit > 0)           // Unlimited length queues never block on write
+      d_not_full.notify_one();
+
+    return m;
+  }
+
+  void
+  msg_queue::flush()
+  {
+    while (delete_head_nowait() != pmt_t())
+      ;
+  }
+
+} /* namespace gruel */