commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r4634 - in gnuradio/trunk: mblock/src/lib pmt/src/lib


From: eb
Subject: [Commit-gnuradio] r4634 - in gnuradio/trunk: mblock/src/lib pmt/src/lib
Date: Sun, 25 Feb 2007 17:40:38 -0700 (MST)

Author: eb
Date: 2007-02-25 17:40:37 -0700 (Sun, 25 Feb 2007)
New Revision: 4634

Added:
   gnuradio/trunk/mblock/src/lib/mb_endpoint.cc
   gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.cc
   gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.h
   gnuradio/trunk/mblock/src/lib/qa_mblock_send.cc
   gnuradio/trunk/mblock/src/lib/qa_mblock_send.h
Removed:
   gnuradio/trunk/mblock/src/lib/mb_port_detail.cc
   gnuradio/trunk/mblock/src/lib/mb_port_detail.h
   gnuradio/trunk/mblock/src/lib/mb_runtime_impl.cc
   gnuradio/trunk/mblock/src/lib/mb_runtime_impl.h
Modified:
   gnuradio/trunk/mblock/src/lib/Makefile.am
   gnuradio/trunk/mblock/src/lib/mb_common.h
   gnuradio/trunk/mblock/src/lib/mb_connection.cc
   gnuradio/trunk/mblock/src/lib/mb_connection.h
   gnuradio/trunk/mblock/src/lib/mb_endpoint.h
   gnuradio/trunk/mblock/src/lib/mb_exception.cc
   gnuradio/trunk/mblock/src/lib/mb_exception.h
   gnuradio/trunk/mblock/src/lib/mb_mblock.cc
   gnuradio/trunk/mblock/src/lib/mb_mblock.h
   gnuradio/trunk/mblock/src/lib/mb_mblock_impl.cc
   gnuradio/trunk/mblock/src/lib/mb_mblock_impl.h
   gnuradio/trunk/mblock/src/lib/mb_msg_queue.cc
   gnuradio/trunk/mblock/src/lib/mb_msg_queue.h
   gnuradio/trunk/mblock/src/lib/mb_port.cc
   gnuradio/trunk/mblock/src/lib/mb_port.h
   gnuradio/trunk/mblock/src/lib/mb_port_simple.cc
   gnuradio/trunk/mblock/src/lib/mb_port_simple.h
   gnuradio/trunk/mblock/src/lib/mb_runtime.cc
   gnuradio/trunk/mblock/src/lib/mb_runtime.h
   gnuradio/trunk/mblock/src/lib/mb_util.cc
   gnuradio/trunk/mblock/src/lib/qa_mblock.cc
   gnuradio/trunk/mblock/src/lib/qa_mblock_prims.cc
   gnuradio/trunk/pmt/src/lib/pmt.cc
   gnuradio/trunk/pmt/src/lib/pmt.h
Log:
Merged mblock work-in-progress from eb/mb -r4341:4633 into trunk.


Modified: gnuradio/trunk/mblock/src/lib/Makefile.am
===================================================================
--- gnuradio/trunk/mblock/src/lib/Makefile.am   2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/Makefile.am   2007-02-26 00:40:37 UTC (rev 
4634)
@@ -21,7 +21,7 @@
 
 include $(top_srcdir)/Makefile.common
 
-INCLUDES = $(PMT_INCLUDES) $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES)
+INCLUDES = $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(BOOST_CFLAGS) 
$(CPPUNIT_INCLUDES)
 
 TESTS = test_mblock
 
@@ -33,6 +33,7 @@
 # These are the source files that go into the mblock shared library
 libmblock_la_SOURCES =                 \
        mb_connection.cc                \
+       mb_endpoint.cc                  \
        mb_exception.cc                 \
        mb_mblock.cc                    \
        mb_mblock_impl.cc               \
@@ -44,7 +45,7 @@
        mb_port_simple.cc               \
        mb_protocol_class.cc            \
        mb_runtime.cc                   \
-       mb_runtime_impl.cc              \
+       mb_runtime_single_threaded.cc   \
        mb_util.cc                      
 
 
@@ -53,6 +54,7 @@
 
 # link the library against the c++ standard library
 libmblock_la_LIBADD =                  \
+       $(OMNITHREAD_LIBS)              \
        $(PMT_LIBS)                     \
        -lstdc++                        
 
@@ -67,6 +69,7 @@
        mb_port_simple.h                \
        mb_protocol_class.h             \
        mb_runtime.h                    \
+       mb_runtime_single_threaded.h    \
        mb_util.h                       
 
 
@@ -75,17 +78,17 @@
        mb_endpoint.h                   \
        mb_mblock_impl.h                \
        mb_msg_accepter_smp.h           \
-       mb_port_detail.h                \
-       mb_runtime_impl.h               \
        qa_mblock.h                     \
-       qa_mblock_prims.h               
+       qa_mblock_prims.h               \
+       qa_mblock_send.h                
 
 
 # Build the qa code into its own library
 
 libmblock_qa_la_SOURCES =              \
        qa_mblock.cc                    \
-       qa_mblock_prims.cc              
+       qa_mblock_prims.cc              \
+       qa_mblock_send.cc               
 
 
 # magic flags

Modified: gnuradio/trunk/mblock/src/lib/mb_common.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_common.h   2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_common.h   2007-02-26 00:40:37 UTC (rev 
4634)
@@ -67,8 +67,8 @@
 class mb_runtime;
 typedef boost::shared_ptr<mb_runtime> mb_runtime_sptr;
 
-class mb_runtime_impl;
-typedef boost::shared_ptr<mb_runtime_impl> mb_runtime_impl_sptr;
+//class mb_runtime_impl;
+//typedef boost::shared_ptr<mb_runtime_impl> mb_runtime_impl_sptr;
 
 class mb_mblock;
 typedef boost::shared_ptr<mb_mblock> mb_mblock_sptr;
@@ -79,8 +79,8 @@
 class mb_port;
 typedef boost::shared_ptr<mb_port> mb_port_sptr;
 
-class mb_port_detail;
-typedef boost::shared_ptr<mb_port_detail> mb_port_detail_sptr;
+//class mb_port_detail;
+//typedef boost::shared_ptr<mb_port_detail> mb_port_detail_sptr;
 
 class mb_msg_accepter;
 typedef boost::shared_ptr<mb_msg_accepter> mb_msg_accepter_sptr;

Modified: gnuradio/trunk/mblock/src/lib/mb_connection.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_connection.cc      2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_connection.cc      2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -52,17 +52,17 @@
 }
 
 bool
-mb_conn_table::lookup_conn_by_port(mb_port_sptr port,
+mb_conn_table::lookup_conn_by_port(const mb_port *port,
                                   mb_conn_iter *itp, int *which_ep)
 {
   mb_conn_iter end = d_connections.end();
   for (mb_conn_iter it = d_connections.begin(); it != end; ++it){
-    if (it->d_ep[0].port() == port){
+    if (it->d_ep[0].port().get() == port){
       *itp = it;
       *which_ep = 0;
       return true;
     }
-    if (it->d_ep[1].port() == port){
+    if (it->d_ep[1].port().get() == port){
       *itp = it;
       *which_ep = 1;
       return true;

Modified: gnuradio/trunk/mblock/src/lib/mb_connection.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_connection.h       2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_connection.h       2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -53,8 +53,8 @@
                      mb_conn_iter *it, int *which_ep);
 
   bool
-  lookup_conn_by_port(mb_port_sptr port,
-                      mb_conn_iter *it, int *which_ep);
+  lookup_conn_by_port(const mb_port *port,
+                     mb_conn_iter *it, int *which_ep);
 
   void
   create_conn(const mb_endpoint &ep0, const mb_endpoint &ep1);

Copied: gnuradio/trunk/mblock/src/lib/mb_endpoint.cc (from rev 4633, 
gnuradio/branches/developers/eb/mb/mblock/src/lib/mb_endpoint.cc)
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_endpoint.cc                                
(rev 0)
+++ gnuradio/trunk/mblock/src/lib/mb_endpoint.cc        2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_endpoint.h>
+
+bool
+mb_endpoint::inside_of_relay_port_p() const
+{
+  return d_port->port_type() == mb_port::RELAY && d_component_name == "self";
+}
+
+pmt_t
+mb_endpoint::incoming_message_set() const
+{
+  if (inside_of_relay_port_p())                        // swap incoming and 
outgoing
+    return port()->outgoing_message_set();
+  else
+    return port()->incoming_message_set();
+}
+
+pmt_t
+mb_endpoint::outgoing_message_set() const
+{
+  if (inside_of_relay_port_p())                        // swap incoming and 
outgoing
+    return port()->incoming_message_set();
+  else
+    return port()->outgoing_message_set();
+}

Modified: gnuradio/trunk/mblock/src/lib/mb_endpoint.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_endpoint.h 2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_endpoint.h 2007-02-26 00:40:37 UTC (rev 
4634)
@@ -47,6 +47,12 @@
   const std::string &component_name() const { return d_component_name; }
   const std::string &port_name() const { return d_port_name; }
   mb_port_sptr port() const { return d_port; }
+
+  //! Does this endpoint represent the inside of a relay port
+  bool inside_of_relay_port_p() const;
+
+  pmt_t        incoming_message_set() const;
+  pmt_t        outgoing_message_set() const;
 };
 
 #endif /* INCLUDED_MB_ENDPOINT_H */

Modified: gnuradio/trunk/mblock/src/lib/mb_exception.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_exception.cc       2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_exception.cc       2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -33,6 +33,11 @@
 {
 }
 
+mbe_not_implemented::mbe_not_implemented(mb_mblock *mb, const std::string &msg)
+  : mbe_base(mb, "Not implemented: " + msg)
+{
+}
+
 mbe_no_such_component::mbe_no_such_component(mb_mblock *mb, const std::string 
&component_name)
   : mbe_base(mb, "No such component: " + component_name)
 {

Modified: gnuradio/trunk/mblock/src/lib/mb_exception.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_exception.h        2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_exception.h        2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -32,6 +32,11 @@
   mbe_base(mb_mblock *mb, const std::string &msg);
 };
 
+class mbe_not_implemented : public mbe_base
+{
+public:
+  mbe_not_implemented(mb_mblock *mb, const std::string &msg);
+};
 
 
 class mbe_no_such_component : public mbe_base

Modified: gnuradio/trunk/mblock/src/lib/mb_mblock.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_mblock.cc  2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_mblock.cc  2007-02-26 00:40:37 UTC (rev 
4634)
@@ -27,6 +27,12 @@
 #include <mb_mblock_impl.h>
 
 
+mb_visitor::~mb_visitor()
+{
+  // nop base case for virtual destructor.
+}
+
+
 mb_mblock::mb_mblock()
   : d_impl(mb_mblock_impl_sptr(new mb_mblock_impl(this)))
 {
@@ -113,3 +119,21 @@
 {
   return d_impl->walk_tree(visitor, path);
 }
+
+std::string
+mb_mblock::fullname() const
+{
+  return d_impl->fullname();
+}
+
+void
+mb_mblock::set_fullname(const std::string name)
+{
+  d_impl->set_fullname(name);
+}
+
+mb_mblock *
+mb_mblock::parent() const
+{
+  return d_impl->mblock_parent();
+}

Modified: gnuradio/trunk/mblock/src/lib/mb_mblock.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_mblock.h   2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_mblock.h   2007-02-26 00:40:37 UTC (rev 
4634)
@@ -35,8 +35,7 @@
 {
 public:
   virtual ~mb_visitor();
-  bool operator()(mb_mblock *mblock, const std::string &path) { return 
visit(mblock, path); }
-  virtual bool visit(mb_mblock *mblock, const std::string &path) = 0;
+  virtual bool operator()(mb_mblock *mblock, const std::string &path) = 0;
 };
 
 // ----------------------------------------------------------------------
@@ -69,6 +68,7 @@
    */
   mb_mblock();
 
+public:
   /*!
    * \brief Called by the runtime system to execute the initial
    * transition of the finite state machine.
@@ -77,6 +77,7 @@
    */
   virtual void init_fsm();
 
+protected:
   /*!
    * \brief Called by the runtime system when there's a message to handle.
    *
@@ -178,13 +179,21 @@
 public:
   virtual ~mb_mblock();
 
+  void set_fullname(const std::string name);
+  
+  //! Return full name of this block
+  std::string fullname() const;
+
+  //! Return the parent of this mblock, or 0 if we're the top-level block.
+  mb_mblock *parent() const;
+
   /*!
    * \brief Perform a pre-order depth-first traversal of the hierarchy.
    *
    * The traversal stops and returns false if any call to visitor returns 
false.
    */
   bool
-  walk_tree(mb_visitor *visitor, const std::string &path="");
+  walk_tree(mb_visitor *visitor, const std::string &path="top");
 
 
   //! \implementation

Modified: gnuradio/trunk/mblock/src/lib/mb_mblock_impl.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_mblock_impl.cc     2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_mblock_impl.cc     2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -51,7 +51,7 @@
 ////////////////////////////////////////////////////////////////////////
 
 mb_mblock_impl::mb_mblock_impl(mb_mblock *mb)
-  : d_mb(mb), d_mb_parent(0)
+  : d_mb(mb), d_mb_parent(0), d_fullname("<unknown>")
 {
 }
 
@@ -67,11 +67,6 @@
                            bool conjugated,
                            mb_port::port_type_t port_type)
 {
-  if (port_type == mb_port::RELAY)
-    throw mbe_base(d_mb,
-            "mb_block_impl::define_port: RELAY ports are not implemented: "
-            + port_name);
-  
   if (port_is_defined(port_name))
     throw mbe_duplicate_port(d_mb, port_name);
 
@@ -90,7 +85,7 @@
   if (comp_is_defined(name))   // check for duplicate name
     throw mbe_duplicate_component(d_mb, name);
 
-  component->d_impl->d_mb_parent = d_mb;    // set component's parent link
+  component->d_impl->d_mb_parent = d_mb;     // set component's parent link
   d_comp_map[name] = component;
 }
 
@@ -103,7 +98,7 @@
   mb_endpoint  ep0 = check_and_resolve_endpoint(comp_name1, port_name1);
   mb_endpoint  ep1 = check_and_resolve_endpoint(comp_name2, port_name2);
 
-  if (!ports_are_compatible(ep0.port(), ep1.port()))
+  if (!endpoints_are_compatible(ep0, ep1))
     throw mbe_incompatible_ports(d_mb,
                                 comp_name1, port_name1,
                                 comp_name2, port_name2);
@@ -194,17 +189,15 @@
 
 
 bool
-mb_mblock_impl::ports_are_compatible(mb_port_sptr p0, mb_port_sptr p1)
+mb_mblock_impl::endpoints_are_compatible(const mb_endpoint &ep0,
+                                        const mb_endpoint &ep1)
 {
-  using std::cout;
-  using std::endl;
+  pmt_t p0_outgoing = ep0.outgoing_message_set();
+  pmt_t p0_incoming = ep0.incoming_message_set();
 
-  pmt_t p0_outgoing = p0->outgoing_message_set();
-  pmt_t p0_incoming = p0->incoming_message_set();
+  pmt_t p1_outgoing = ep1.outgoing_message_set();
+  pmt_t p1_incoming = ep1.incoming_message_set();
 
-  pmt_t p1_outgoing = p1->outgoing_message_set();
-  pmt_t p1_incoming = p1->incoming_message_set();
-
   return (pmt_subsetp(p0_outgoing, p1_incoming)
          && pmt_subsetp(p1_outgoing, p0_incoming));
 }
@@ -232,3 +225,35 @@
 
   return mb_msg_accepter_sptr(ma);
 }
+
+bool
+mb_mblock_impl::lookup_other_endpoint(const mb_port *port, mb_endpoint *ep)
+{
+  mb_conn_iter it;
+  int          which_ep = 0;
+
+  if (!d_conn_table.lookup_conn_by_port(port, &it, &which_ep))
+    return false;
+  
+  *ep = it->d_ep[which_ep^1];
+  return true;
+}
+
+mb_mblock_sptr
+mb_mblock_impl::component(const std::string &comp_name)
+{
+  if (comp_name == "self")
+    return d_mb->shared_from_this();
+
+  if (d_comp_map.count(comp_name) == 0)
+    return mb_mblock_sptr();   // null pointer
+
+  return d_comp_map[comp_name];
+}
+
+void
+mb_mblock_impl::set_fullname(const std::string &name)
+{
+  d_fullname = name;
+}
+

Modified: gnuradio/trunk/mblock/src/lib/mb_mblock_impl.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_mblock_impl.h      2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_mblock_impl.h      2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -40,6 +40,8 @@
   mb_mblock                   *d_mb;           // pointer to our associated 
mblock
   mb_mblock                   *d_mb_parent;    // pointer to our parent
 
+  std::string                  d_fullname;     // hierarchical name
+
   mb_port_map_t                        d_port_map;     // our ports
   mb_comp_map_t                        d_comp_map;     // our components
   mb_conn_table                        d_conn_table;   // our connections
@@ -145,6 +147,34 @@
   mb_msg_queue &
   msgq() { return d_msgq; }
 
+  //! Return full name of this block
+  std::string fullname() const { return d_fullname; }
+
+  //! Set the name of this block
+  void set_fullname(const std::string &name);
+
+  /*!
+   * \brief If bound, store endpoint from the other end of the connection.
+   *
+   * \param port [in]  port the port that we're searching for.
+   * \param ep   [out] the other end point from the matching connection.
+   *
+   * \returns true iff there's a matching connection.
+   */
+  bool
+  lookup_other_endpoint(const mb_port *port, mb_endpoint *ep);
+
+
+  mb_mblock *
+  mblock() const { return d_mb; }
+
+  mb_mblock *
+  mblock_parent() const { return d_mb_parent; }
+
+  mb_mblock_sptr
+  component(const std::string &comp_name);
+
+
   /*
    * Our implementation methods
    */
@@ -164,7 +194,8 @@
               const std::string &port_name);
 
   static bool
-  ports_are_compatible(mb_port_sptr p0, mb_port_sptr p1);
+  endpoints_are_compatible(const mb_endpoint &ep0,
+                          const mb_endpoint &ep1);
 
 };
 

Modified: gnuradio/trunk/mblock/src/lib/mb_msg_queue.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_msg_queue.cc       2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_msg_queue.cc       2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -38,7 +38,7 @@
 void
 mb_msg_queue::insert(mb_message_sptr msg)
 {
-  // omni_mutex_lock   l(d_mutex);             FIXME
+  omni_mutex_lock      l(d_mutex);
   
   mb_pri_t q = mb_pri_clamp(msg->priority());
 
@@ -57,7 +57,7 @@
 mb_message_sptr
 mb_msg_queue::get_highest_pri_msg()
 {
-  // omni_mutex_lock   l(d_mutex);             FIXME
+  omni_mutex_lock      l(d_mutex);
 
   // FIXME use bitmap and ffz to find best queue in O(1)
 

Modified: gnuradio/trunk/mblock/src/lib/mb_msg_queue.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_msg_queue.h        2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_msg_queue.h        2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -22,7 +22,7 @@
 #define INCLUDED_MB_MSG_QUEUE_H
 
 #include <mb_common.h>
-//#include <omnithread.h>      FIXME
+#include <omnithread.h>
 
 /*!
  * \brief priority queue for mblock messages
@@ -37,7 +37,7 @@
     bool empty_p() const { return head == 0; }
   };
 
-  // omni_mutex        d_mutex;        FIXME
+  omni_mutex   d_mutex;
 
   // FIXME add bitmap to indicate which queues are non-empty.
   subq         d_queue[MB_NPRI];

Modified: gnuradio/trunk/mblock/src/lib/mb_port.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_port.cc    2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_port.cc    2007-02-26 00:40:37 UTC (rev 
4634)
@@ -24,7 +24,6 @@
 #endif
 
 #include <mb_port.h>
-#include <mb_port_detail.h>
 #include <mb_protocol_class.h>
 
 mb_port::mb_port(mb_mblock *mblock,

Modified: gnuradio/trunk/mblock/src/lib/mb_port.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_port.h     2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_port.h     2007-02-26 00:40:37 UTC (rev 
4634)
@@ -54,6 +54,8 @@
          bool conjugated,
          mb_port::port_type_t port_type);
 
+  mb_mblock *mblock() const { return d_mblock; }
+
 public:
   std::string  port_name() const { return d_port_name; }
   pmt_t                protocol_class() const { return d_protocol_class; }

Deleted: gnuradio/trunk/mblock/src/lib/mb_port_detail.cc

Deleted: gnuradio/trunk/mblock/src/lib/mb_port_detail.h

Modified: gnuradio/trunk/mblock/src/lib/mb_port_simple.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_port_simple.cc     2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_port_simple.cc     2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -25,7 +25,12 @@
 
 #include <mb_port_simple.h>
 #include <mb_msg_accepter.h>
+#include <mb_exception.h>
+#include <mb_mblock.h>
+#include <mb_mblock_impl.h>
+#include <assert.h>
 
+
 mb_port_simple::mb_port_simple(mb_mblock *mblock,
                               const std::string &port_name,
                               const std::string &protocol_class_name,
@@ -43,17 +48,84 @@
 void
 mb_port_simple::send(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t 
priority)
 {
-  mb_msg_accepter_sptr  accepter = find_accepter();
+  if (port_type() == mb_port::RELAY)  // Can't send directly to a RELAY port
+    throw mbe_invalid_port_type(mblock(), mblock()->fullname(), port_name());
+
+  mb_msg_accepter_sptr  accepter = find_accepter(this);
   if (accepter)
     (*accepter)(signal, data, metadata, priority);
 }
 
+
 mb_msg_accepter_sptr
-mb_port_simple::find_accepter()
+mb_port_simple::find_accepter(mb_port_simple *start)
 {
+  mb_port_simple       *p = start;
+  mb_port_simple       *pp = 0;
+  mb_mblock            *context = 0;
+  mb_endpoint          peer_ep;
   mb_msg_accepter_sptr r;
 
-  // FIXME, actually do the work ;)
+  // Set up initial context.
 
-  return r;
+  switch(p->port_type()){
+  case mb_port::INTERNAL:      // binding is in our name space
+    context = p->mblock();
+    break;
+
+  case mb_port::EXTERNAL:      // binding is in parent's name space
+    context = p->mblock()->parent();
+    break;
+
+  default:
+    throw std::logic_error("Can't happen: mb_port_simple::find_accepter [1]");
+  }
+
+
+ traverse:
+
+  if (!context->impl()->lookup_other_endpoint(p, &peer_ep))
+    return mb_msg_accepter_sptr();     // not bound
+  
+  pp = dynamic_cast<mb_port_simple *>(peer_ep.port().get());   // peer port
+  assert(pp);
+
+  switch (pp->port_type()){    
+  case mb_port::INTERNAL:      // Terminate here.
+  case mb_port::EXTERNAL:
+    r = pp->make_accepter();
+    // FIXME cache the result
+    return r;
+
+  case mb_port::RELAY:         // Traverse to other side of relay port.
+    if (peer_ep.inside_of_relay_port_p()){
+      // We're on inside of relay port, headed out.
+      p = pp;
+      context = p->mblock()->parent();
+
+      // Corner case: we're attempting to traverse a relay port on the border
+      // of the top block...
+      if (!context)
+       return mb_msg_accepter_sptr();  // not bound
+
+      goto traverse;
+    }
+    else {
+      // We're on the outside of relay port, headed in.
+      p = pp;
+      context = p->mblock();
+      goto traverse;
+    }
+    break;
+
+  default:
+    throw std::logic_error("Can't happen: mb_port_simple::find_accepter [2]");
+  }
 }
+
+
+mb_msg_accepter_sptr
+mb_port_simple::make_accepter()
+{
+  return d_mblock->impl()->make_accepter(port_name());
+}

Modified: gnuradio/trunk/mblock/src/lib/mb_port_simple.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_port_simple.h      2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/mb_port_simple.h      2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -29,8 +29,11 @@
 class mb_port_simple : public mb_port
 {
 protected:
+  static mb_msg_accepter_sptr
+  find_accepter(mb_port_simple *start);
+
   mb_msg_accepter_sptr
-  find_accepter();
+  make_accepter();
 
 public:
   mb_port_simple(mb_mblock *mblock,

Modified: gnuradio/trunk/mblock/src/lib/mb_runtime.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_runtime.cc 2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_runtime.cc 2007-02-26 00:40:37 UTC (rev 
4634)
@@ -24,29 +24,15 @@
 #endif
 
 #include <mb_runtime.h>
-#include <mb_runtime_impl.h>
+#include <mb_runtime_single_threaded.h>
 
 mb_runtime_sptr
 mb_make_runtime()
 {
-  return mb_runtime_sptr(new mb_runtime());
+  return mb_runtime_sptr(new mb_runtime_single_threaded());
 }
 
-mb_runtime::mb_runtime()
-  : d_impl(mb_runtime_impl_sptr(new mb_runtime_impl()))
-{
-  // FIXME
-  
-}
-
 mb_runtime::~mb_runtime()
 {
-  // FIXME
+  // nop
 }
-
-bool
-mb_runtime::run()
-{
-  // FIXME
-  return true;
-}

Modified: gnuradio/trunk/mblock/src/lib/mb_runtime.h
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_runtime.h  2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_runtime.h  2007-02-26 00:40:37 UTC (rev 
4634)
@@ -24,40 +24,31 @@
 #include <mb_common.h>
 
 /*!
- * \brief Public constructor for mb_runtime.
+ * \brief Public constructor (factory) for mb_runtime objects.
  */
 mb_runtime_sptr mb_make_runtime();
 
 /*!
- * \brief Runtime support for m-blocks
+ * \brief Abstract runtime support for m-blocks
  *
  * There should generally be only a single instance of this class.
- *
- * It should be created by the top-level initialization code,
- * and that instance should be passed into the constructor of the
- * top-level mblock.
  */
 class mb_runtime : boost::noncopyable
 {
-private:
-  mb_runtime_impl_sptr         d_impl;           // implementation details
-
-  mb_runtime();
-
-  friend mb_runtime_sptr mb_make_runtime();
-
 public:
-  ~mb_runtime();
+  mb_runtime(){}
+  virtual ~mb_runtime();
 
   /*!
-   * \brief Run the mblocks...
+   * \brief Run the mblock hierarchy rooted at \p top
    *
    * This routine turns into the m-block scheduler, and
    * blocks until the system is shutdown.
    *
+   * \param top top-level mblock
    * \returns true if the system ran successfully.
    */
-  bool run();
+  virtual bool run(mb_mblock_sptr top) = 0;
 };
 
 #endif /* INCLUDED_MB_RUNTIME_H */

Deleted: gnuradio/trunk/mblock/src/lib/mb_runtime_impl.cc

Deleted: gnuradio/trunk/mblock/src/lib/mb_runtime_impl.h

Copied: gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.cc (from rev 
4633, 
gnuradio/branches/developers/eb/mb/mblock/src/lib/mb_runtime_single_threaded.cc)
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.cc                 
        (rev 0)
+++ gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.cc 2007-02-26 
00:40:37 UTC (rev 4634)
@@ -0,0 +1,60 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <mb_runtime_single_threaded.h>
+#include <mb_mblock.h>
+
+
+mb_runtime_single_threaded::mb_runtime_single_threaded()
+{
+  // nop for now
+}
+
+mb_runtime_single_threaded::~mb_runtime_single_threaded()
+{
+  // nop for now
+}
+
+bool
+mb_runtime_single_threaded::run(mb_mblock_sptr top)
+{
+  class initial_visitor : public mb_visitor
+  {
+  public:
+    bool operator()(mb_mblock *mblock, const std::string &path)
+    {
+      mblock->set_fullname(path);
+      mblock->init_fsm();
+      return true;
+    }
+  };
+
+  initial_visitor      visitor;
+
+  d_top = top;         // remember top of tree
+
+  d_top->walk_tree(&visitor);
+
+  return true;
+}

Copied: gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.h (from rev 
4633, 
gnuradio/branches/developers/eb/mb/mblock/src/lib/mb_runtime_single_threaded.h)
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.h                  
        (rev 0)
+++ gnuradio/trunk/mblock/src/lib/mb_runtime_single_threaded.h  2007-02-26 
00:40:37 UTC (rev 4634)
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_MB_RUNTIME_SINGLE_THREADED_H
+#define INCLUDED_MB_RUNTIME_SINGLE_THREADED_H
+
+#include <mb_runtime.h>
+
+/*!
+ * \brief Concrete runtime that uses a single thread for all work.
+ */
+class mb_runtime_single_threaded : public mb_runtime
+{
+  mb_mblock_sptr       d_top;          // top mblock
+
+public:
+  mb_runtime_single_threaded();
+  ~mb_runtime_single_threaded();
+
+  bool run(mb_mblock_sptr top);
+};
+
+
+
+#endif /* INCLUDED_MB_RUNTIME_SINGLE_THREADED_H */

Modified: gnuradio/trunk/mblock/src/lib/mb_util.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/mb_util.cc    2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/mb_util.cc    2007-02-26 00:40:37 UTC (rev 
4634)
@@ -30,5 +30,5 @@
 mb_util::join_names(const std::string &comp_name,
                    const std::string &port_name)
 {
-  return comp_name + "/" + port_name;
+  return comp_name + ":" + port_name;
 }

Modified: gnuradio/trunk/mblock/src/lib/qa_mblock.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/qa_mblock.cc  2007-02-25 23:33:37 UTC (rev 
4633)
+++ gnuradio/trunk/mblock/src/lib/qa_mblock.cc  2007-02-26 00:40:37 UTC (rev 
4634)
@@ -26,6 +26,7 @@
 
 #include <qa_mblock.h>
 #include <qa_mblock_prims.h>
+#include <qa_mblock_send.h>
 
 CppUnit::TestSuite *
 qa_mblock::suite()
@@ -33,6 +34,7 @@
   CppUnit::TestSuite   *s = new CppUnit::TestSuite("mblock");
 
   s->addTest (qa_mblock_prims::suite());
+  s->addTest (qa_mblock_send::suite());
   
   return s;
 }

Modified: gnuradio/trunk/mblock/src/lib/qa_mblock_prims.cc
===================================================================
--- gnuradio/trunk/mblock/src/lib/qa_mblock_prims.cc    2007-02-25 23:33:37 UTC 
(rev 4633)
+++ gnuradio/trunk/mblock/src/lib/qa_mblock_prims.cc    2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -20,6 +20,10 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <qa_mblock_prims.h>
 #include <cppunit/TestAssert.h>
 #include <mb_mblock.h>
@@ -103,32 +107,16 @@
 
   // define the protocol class
   pmt_t pc = mb_make_protocol_class(pmt_intern("cs-protocol"),
-                                   pmt_cons(pmt_intern("start"),
-                                            pmt_cons(pmt_intern("stop"),
-                                                     PMT_NIL)),
+                                   pmt_list2(pmt_intern("start"),
+                                             pmt_intern("stop")),
                                    PMT_NIL);
 
   // std::cout << "pc = " << pc << '\n';
 
   mb_mblock_sptr mb2 = mb_mblock_sptr(new dp_2());
 
-  // intf = mb2->peer_interface();
-  // CPPUNIT_ASSERT_EQUAL(size_t(1), intf.size());
-  // CPPUNIT_ASSERT(pmt_eq(s_cs, intf[0]->port_name()));
-
-
   // raises pmt_exception because of duplicate port definition of "cs"
   CPPUNIT_ASSERT_THROW(mb_mblock_sptr(new dp_3()), mbe_duplicate_port);
-
-#if 0
-  try {
-    mb_mblock_sptr mb2 = mb_mblock_sptr(new dp_2());
-  }
-  catch (pmt_exception &e){
-    std::cerr << e.msg() << ' ' << e.obj() << '\n';
-  }
-#endif
-
 }
 
 // ================================================================
@@ -321,13 +309,13 @@
 qa_mblock_prims::test_connect()
 {
   // define the protocol class
-  mb_make_protocol_class(pmt_intern("data"),                           // name 
of class
-                        pmt_cons(pmt_intern("data"), PMT_NIL),         // in
-                        PMT_NIL);                                      // out
+  mb_make_protocol_class(pmt_intern("data"),                   // name of class
+                        pmt_list1(pmt_intern("data")),         // in
+                        PMT_NIL);                              // out
 
-  mb_make_protocol_class(pmt_intern("i/o"),                            // name 
of class
-                        pmt_cons(pmt_intern("in"), PMT_NIL),           // in
-                        pmt_cons(pmt_intern("out"), PMT_NIL));         // out
+  mb_make_protocol_class(pmt_intern("i/o"),                    // name of class
+                        pmt_list1(pmt_intern("in")),           // in
+                        pmt_list1(pmt_intern("out")));         // out
 
 
   mb_runtime_sptr      rt = mb_make_runtime();
@@ -416,4 +404,3 @@
   CPPUNIT_ASSERT_EQUAL(1L, 
pmt_to_long(mb->impl()->msgq().get_highest_pri_msg()->data()));
   CPPUNIT_ASSERT_EQUAL(2L, 
pmt_to_long(mb->impl()->msgq().get_highest_pri_msg()->data()));
 }
-

Copied: gnuradio/trunk/mblock/src/lib/qa_mblock_send.cc (from rev 4633, 
gnuradio/branches/developers/eb/mb/mblock/src/lib/qa_mblock_send.cc)
===================================================================
--- gnuradio/trunk/mblock/src/lib/qa_mblock_send.cc                             
(rev 0)
+++ gnuradio/trunk/mblock/src/lib/qa_mblock_send.cc     2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -0,0 +1,450 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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_mblock_send.h>
+#include <cppunit/TestAssert.h>
+#include <mb_mblock.h>
+#include <mb_runtime.h>
+#include <mb_protocol_class.h>
+#include <mb_exception.h>
+#include <mb_msg_queue.h>
+#include <mb_message.h>
+#include <mb_mblock_impl.h>
+#include <mb_msg_accepter.h>
+#include <stdio.h>
+
+static pmt_t s_data    = pmt_intern("data");
+static pmt_t s_status  = pmt_intern("status");
+static pmt_t s_control = pmt_intern("control");
+static pmt_t s_p0   = pmt_intern("p0");
+static pmt_t s_p1   = pmt_intern("p1");
+static pmt_t s_p2   = pmt_intern("p2");
+static pmt_t s_p3   = pmt_intern("p3");
+static pmt_t s_e1   = pmt_intern("e1");
+static pmt_t s_r1   = pmt_intern("r1");
+
+static void
+define_protocol_classes()
+{
+  // Defined from client point-of-view.
+  mb_make_protocol_class(pmt_intern("qa-send-cs"),     // name
+                        pmt_list1(s_status),           // incoming
+                        pmt_list1(s_control));         // outgoing
+
+}
+
+// ================================================================
+//                    test_simple_routing
+// ================================================================
+
+// sub-block for test_simple_routing
+
+class sr1 : public mb_mblock
+{
+  mb_port_sptr d_p1;
+  mb_port_sptr d_p2;
+  mb_port_sptr d_p3;
+
+public:
+  sr1();
+  ~sr1();
+  void init_fsm();
+};
+
+sr1::sr1()
+{
+  d_p1 = define_port("p1", "qa-send-cs", true, mb_port::EXTERNAL);
+  d_p2 = define_port("p2", "qa-send-cs", true, mb_port::EXTERNAL);
+  d_p3 = define_port("p3", "qa-send-cs", false, mb_port::EXTERNAL);
+}
+
+sr1::~sr1(){}
+  
+void
+sr1::init_fsm()
+{
+  // std::cout << fullname() << "[sr1]: init_fsm\n";
+
+  // send two messages to each port
+  pmt_t our_name = pmt_intern(fullname());
+  d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(0)));
+  d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(1)));
+
+  d_p2->send(s_status, pmt_list3(our_name, s_p2, pmt_from_long(0)));
+  d_p2->send(s_status, pmt_list3(our_name, s_p2, pmt_from_long(1)));
+}
+
+// ----------------------------------------------------------------
+
+// top-level container block for test_simple_routing
+class sr0 : public mb_mblock
+{
+  mb_port_sptr d_p0;
+  
+public:
+  sr0();
+  ~sr0();
+  void init_fsm();
+};
+
+sr0::sr0()
+{
+  d_p0 = define_port("p0", "qa-send-cs", false, mb_port::INTERNAL);
+
+  define_component("mb1", mb_mblock_sptr(new sr1()));
+  define_component("mb2", mb_mblock_sptr(new sr1()));
+
+  connect("self", "p0", "mb1", "p1");
+  connect("mb1", "p2", "mb2", "p3");
+  connect("mb1", "p3", "mb2", "p2");
+}
+
+sr0::~sr0(){}
+
+void
+sr0::init_fsm()
+{
+  // std::cout << fullname() << "[sr0]: init_fsm\n";
+
+  // send two messages to p0
+  pmt_t our_name = pmt_intern(fullname());
+  d_p0->send(s_control, pmt_list3(our_name, s_p0, pmt_from_long(0)));
+  d_p0->send(s_control, pmt_list3(our_name, s_p0, pmt_from_long(1)));
+}
+  
+// ----------------------------------------------------------------
+
+/*
+ * This tests basic message routing using INTERNAL and EXTERNAL ports.
+ * It does not rely on the guts of the runtime being complete,
+ * which is good, because at the time this is being written, it isn't.
+ */
+void
+qa_mblock_send::test_simple_routing()
+{
+  define_protocol_classes();
+
+  mb_message_sptr msg;
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  mb_mblock_sptr mb0 = mb_mblock_sptr(new sr0());
+  rt->run(mb0);
+
+  // Reach into the guts and see if the messages ended up where they should 
have
+
+  // mb0 should have received two messages sent from mb1 via its p1
+  msg = mb0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p0, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p1, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = mb0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p0, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p1, 
pmt_from_long(1)),
+                          msg->data()));
+
+  // mb1 should have received
+  //   two messages from mb0 via its p0 and
+  //   two messages from mb2 via its p3
+
+  mb_mblock_sptr mb1 = mb0->impl()->component("mb1");
+
+  msg = mb1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p1, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top"), s_p0, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = mb1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p1, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top"), s_p0, 
pmt_from_long(1)),
+                          msg->data()));
+
+  msg = mb1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb2"), s_p2, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = mb1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb2"), s_p2, 
pmt_from_long(1)),
+                          msg->data()));
+
+
+  // mb2 should have received
+  //   two messages from mb2 via its p2
+
+  mb_mblock_sptr mb2 = mb0->impl()->component("mb2");
+
+  msg = mb2->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p2, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = mb2->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p3, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/mb1"), s_p2, 
pmt_from_long(1)),
+                          msg->data()));
+}
+
+// ================================================================
+//                    test_relay_routing_1
+// ================================================================
+
+// internal block for test_relay_routing
+
+class rr2 : public mb_mblock
+{
+  mb_port_sptr d_p1;
+  mb_port_sptr d_p2;
+
+public:
+  rr2();
+  ~rr2();
+  void init_fsm();
+};
+
+rr2::rr2()
+{
+  d_p1 = define_port("p1", "qa-send-cs", true,  mb_port::EXTERNAL);
+  d_p2 = define_port("p2", "qa-send-cs", false, mb_port::EXTERNAL);
+}
+
+rr2::~rr2(){}
+  
+void
+rr2::init_fsm()
+{
+  // std::cout << fullname() << "[rr2]: init_fsm\n";
+
+  // send two messages via p1
+  pmt_t our_name = pmt_intern(fullname());
+  d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(0)));
+  d_p1->send(s_status, pmt_list3(our_name, s_p1, pmt_from_long(1)));
+}
+
+// ----------------------------------------------------------------
+
+// intermediate block for test_relay_routing
+
+class rr1 : public mb_mblock
+{
+  mb_port_sptr d_p1;
+  mb_port_sptr d_p2;
+
+public:
+  rr1();
+  ~rr1();
+};
+
+rr1::rr1()
+{
+  d_p1 = define_port("p1", "qa-send-cs", true,  mb_port::RELAY);
+  d_p2 = define_port("p2", "qa-send-cs", false, mb_port::RELAY);
+
+  define_component("c0", mb_mblock_sptr(new rr2()));
+
+  connect("self", "p1", "c0", "p1");
+  connect("self", "p2", "c0", "p2");
+}
+
+rr1::~rr1(){}
+
+// ----------------------------------------------------------------
+
+// top-level container for test_relay_routing
+
+class rr0_a : public mb_mblock
+{
+public:
+  rr0_a();
+  ~rr0_a();
+};
+
+rr0_a::rr0_a()
+{
+  define_component("c0", mb_mblock_sptr(new rr1()));
+  define_component("c1", mb_mblock_sptr(new rr2()));
+
+  connect("c0", "p1", "c1", "p2");
+  connect("c0", "p2", "c1", "p1");
+}
+
+rr0_a::~rr0_a(){}
+
+
+/*
+ * This tests basic message routing using RELAY and EXTERNAL ports.
+ * It does not rely on the guts of the runtime being complete,
+ * which is good, because at the time this is being written, it isn't.
+ */
+void
+qa_mblock_send::test_relay_routing_1()
+{
+  mb_message_sptr msg;
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  mb_mblock_sptr  top = mb_mblock_sptr(new rr0_a());
+  rt->run(top);
+
+  // Reach into the guts and see if the messages ended up where they should 
have
+
+  mb_mblock_sptr c0 = top->impl()->component("c0");
+  mb_mblock_sptr c0c0 = c0->impl()->component("c0");
+
+  mb_mblock_sptr c1 = top->impl()->component("c1");
+
+  // c0c0 should have received
+  //   two message from c1 via its p2
+
+  msg = c0c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  //std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1"), s_p1, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = c0c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  //std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1"), s_p1, 
pmt_from_long(1)),
+                          msg->data()));
+
+  // c1 should have received
+  //   two message from c0c0 via its p2
+
+  msg = c1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  //std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = c1->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  //std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, 
pmt_from_long(1)),
+                          msg->data()));
+}
+
+// ================================================================
+//                    test_relay_routing_2
+// ================================================================
+
+// top-level container for test_relay_routing_2
+
+class rr0_b : public mb_mblock
+{
+public:
+  rr0_b();
+  ~rr0_b();
+};
+
+rr0_b::rr0_b()
+{
+  define_component("c0", mb_mblock_sptr(new rr1()));
+  define_component("c1", mb_mblock_sptr(new rr1()));
+
+  connect("c0", "p1", "c1", "p2");
+  connect("c0", "p2", "c1", "p1");
+}
+
+rr0_b::~rr0_b(){}
+
+
+/*
+ * This tests basic message routing using RELAY and EXTERNAL ports.
+ * It does not rely on the guts of the runtime being complete,
+ * which is good, because at the time this is being written, it isn't.
+ */
+void
+qa_mblock_send::test_relay_routing_2()
+{
+  mb_message_sptr msg;
+
+  mb_runtime_sptr rt = mb_make_runtime();
+  mb_mblock_sptr  top = mb_mblock_sptr(new rr0_b());
+  rt->run(top);
+
+  // Reach into the guts and see if the messages ended up where they should 
have
+
+  mb_mblock_sptr c0 = top->impl()->component("c0");
+  mb_mblock_sptr c0c0 = c0->impl()->component("c0");
+
+  mb_mblock_sptr c1 = top->impl()->component("c1");
+  mb_mblock_sptr c1c0 = c1->impl()->component("c0");
+
+  // c0c0 should have received
+  //   two message from c1c0 via its p2
+
+  msg = c0c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1/c0"), s_p1, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = c0c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c1/c0"), s_p1, 
pmt_from_long(1)),
+                          msg->data()));
+
+  // c1c0 should have received
+  //   two message from c0c0 via its p2
+
+  msg = c1c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, 
pmt_from_long(0)),
+                          msg->data()));
+
+  msg = c1c0->impl()->msgq().get_highest_pri_msg();
+  CPPUNIT_ASSERT(msg);
+  // std::cerr << msg->data() << std::endl;
+  CPPUNIT_ASSERT_EQUAL(s_p2, msg->port_id());
+  CPPUNIT_ASSERT(pmt_equal(pmt_list3(pmt_intern("top/c0/c0"), s_p1, 
pmt_from_long(1)),
+                          msg->data()));
+}

Copied: gnuradio/trunk/mblock/src/lib/qa_mblock_send.h (from rev 4633, 
gnuradio/branches/developers/eb/mb/mblock/src/lib/qa_mblock_send.h)
===================================================================
--- gnuradio/trunk/mblock/src/lib/qa_mblock_send.h                              
(rev 0)
+++ gnuradio/trunk/mblock/src/lib/qa_mblock_send.h      2007-02-26 00:40:37 UTC 
(rev 4634)
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 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_MBLOCK_SEND_H
+#define INCLUDED_QA_MBLOCK_SEND_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_mblock_send : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_mblock_send);
+  CPPUNIT_TEST(test_simple_routing);
+  CPPUNIT_TEST(test_relay_routing_1);
+  CPPUNIT_TEST(test_relay_routing_2);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void test_simple_routing();
+  void test_relay_routing_1();
+  void test_relay_routing_2();
+};
+
+#endif /* INCLUDED_QA_MBLOCK_SEND_H */
+

Modified: gnuradio/trunk/pmt/src/lib/pmt.cc
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt.cc   2007-02-25 23:33:37 UTC (rev 4633)
+++ gnuradio/trunk/pmt/src/lib/pmt.cc   2007-02-26 00:40:37 UTC (rev 4634)
@@ -841,3 +841,27 @@
   }
   return true;
 }
+
+pmt_t
+pmt_list1(pmt_t x1)
+{
+  return pmt_cons(x1, PMT_NIL);
+}
+
+pmt_t
+pmt_list2(pmt_t x1, pmt_t x2)
+{
+  return pmt_cons(x1, pmt_cons(x2, PMT_NIL));
+}
+
+pmt_t
+pmt_list3(pmt_t x1, pmt_t x2, pmt_t x3)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, PMT_NIL)));
+}
+
+pmt_t
+pmt_list4(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4)
+{
+  return pmt_cons(x1, pmt_cons(x2, pmt_cons(x3, pmt_cons(x4, PMT_NIL))));
+}

Modified: gnuradio/trunk/pmt/src/lib/pmt.h
===================================================================
--- gnuradio/trunk/pmt/src/lib/pmt.h    2007-02-25 23:33:37 UTC (rev 4633)
+++ gnuradio/trunk/pmt/src/lib/pmt.h    2007-02-26 00:40:37 UTC (rev 4634)
@@ -548,6 +548,26 @@
  */
 bool pmt_subsetp(pmt_t list1, pmt_t list2);
 
+/*!
+ * \brief Return a list of length 1 containing \p x1
+ */
+pmt_t pmt_list1(pmt_t x1);
+
+/*!
+ * \brief Return a list of length 2 containing \p x1, \p x2
+ */
+pmt_t pmt_list2(pmt_t x1, pmt_t x2);
+
+/*!
+ * \brief Return a list of length 3 containing \p x1, \p x2, \p x3
+ */
+pmt_t pmt_list3(pmt_t x1, pmt_t x2, pmt_t x3);
+
+/*!
+ * \brief Return a list of length 4 containing \p x1, \p x2, \p x3, \p x4
+ */
+pmt_t pmt_list4(pmt_t x1, pmt_t x2, pmt_t x3, pmt_t x4);
+
 /*
  * ------------------------------------------------------------------------
  *                          read / write





reply via email to

[Prev in Thread] Current Thread [Next in Thread]