summaryrefslogtreecommitdiff
path: root/mblock/src
diff options
context:
space:
mode:
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>2007-01-29 00:10:51 +0000
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>2007-01-29 00:10:51 +0000
commita6db1d097d7be5e562c07f60a1ff711bddc5e99c (patch)
tree28e454b14c23b4cfc991fafad0e9d9d183d7d7de /mblock/src
parentf8af5803ca8b87aa6c5f8c97d5abbabe2b837619 (diff)
Merged mblock work-in-progress (eb/mb r4273:4312) into trunk.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4313 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'mblock/src')
-rw-r--r--mblock/src/lib/Makefile.am11
-rw-r--r--mblock/src/lib/mb_common.h45
-rw-r--r--mblock/src/lib/mb_mblock.h22
-rw-r--r--mblock/src/lib/mb_mblock_impl.cc38
-rw-r--r--mblock/src/lib/mb_mblock_impl.h20
-rw-r--r--mblock/src/lib/mb_message.cc3
-rw-r--r--mblock/src/lib/mb_message.h21
-rw-r--r--mblock/src/lib/mb_msg_accepter.cc31
-rw-r--r--mblock/src/lib/mb_msg_accepter.h48
-rw-r--r--mblock/src/lib/mb_msg_accepter_smp.cc50
-rw-r--r--mblock/src/lib/mb_msg_accepter_smp.h42
-rw-r--r--mblock/src/lib/mb_msg_queue.cc80
-rw-r--r--mblock/src/lib/mb_msg_queue.h59
-rw-r--r--mblock/src/lib/mb_port.cc7
-rw-r--r--mblock/src/lib/mb_port.h24
-rw-r--r--mblock/src/lib/mb_port_simple.cc59
-rw-r--r--mblock/src/lib/mb_port_simple.h59
-rw-r--r--mblock/src/lib/qa_mblock_prims.cc90
-rw-r--r--mblock/src/lib/qa_mblock_prims.h6
19 files changed, 665 insertions, 50 deletions
diff --git a/mblock/src/lib/Makefile.am b/mblock/src/lib/Makefile.am
index 4174730071..c049bd3473 100644
--- a/mblock/src/lib/Makefile.am
+++ b/mblock/src/lib/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2006 Free Software Foundation, Inc.
+# Copyright 2006,2007 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -37,8 +37,11 @@ libmblock_la_SOURCES = \
mb_mblock.cc \
mb_mblock_impl.cc \
mb_message.cc \
+ mb_msg_accepter.cc \
+ mb_msg_accepter_smp.cc \
+ mb_msg_queue.cc \
mb_port.cc \
- mb_port_detail.cc \
+ mb_port_simple.cc \
mb_protocol_class.cc \
mb_runtime.cc \
mb_runtime_impl.cc \
@@ -58,7 +61,10 @@ include_HEADERS = \
mb_exception.h \
mb_mblock.h \
mb_message.h \
+ mb_msg_accepter.h \
+ mb_msg_queue.h \
mb_port.h \
+ mb_port_simple.h \
mb_protocol_class.h \
mb_runtime.h \
mb_util.h
@@ -68,6 +74,7 @@ noinst_HEADERS = \
mb_connection.h \
mb_endpoint.h \
mb_mblock_impl.h \
+ mb_msg_accepter_smp.h \
mb_port_detail.h \
mb_runtime_impl.h \
qa_mblock.h \
diff --git a/mblock/src/lib/mb_common.h b/mblock/src/lib/mb_common.h
index f54fa56a2e..13837a8c55 100644
--- a/mblock/src/lib/mb_common.h
+++ b/mblock/src/lib/mb_common.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -25,11 +25,44 @@
#include <vector>
#include <stdexcept>
#include <boost/utility.hpp>
+#include <boost/enable_shared_from_this.hpp>
+/*
+ * The priority type and valid range
+ */
typedef unsigned int mb_pri_t;
-static const mb_pri_t MB_PRI_DEFAULT = 5;
+static const mb_pri_t MB_PRI_BEST = 0;
+static const mb_pri_t MB_PRI_DEFAULT = 4;
+static const mb_pri_t MB_PRI_WORST = 7;
+static const mb_pri_t MB_NPRI = MB_PRI_WORST + 1; // number of valid priorities
+/*!
+ * \brief return true iff priority a is better than priority b
+ */
+inline static bool
+mb_pri_better(mb_pri_t a, mb_pri_t b)
+{
+ return a < b;
+}
+
+/*!
+ * \brief return true iff priority a is worse than priority b
+ */
+inline static bool
+mb_pri_worse(mb_pri_t a, mb_pri_t b)
+{
+ return a > b;
+}
+
+/*!
+ * \brief ensure that pri is valid
+ */
+inline static mb_pri_t
+mb_pri_clamp(mb_pri_t p)
+{
+ return p < MB_NPRI ? p : MB_NPRI - 1;
+}
class mb_runtime;
typedef boost::shared_ptr<mb_runtime> mb_runtime_sptr;
@@ -49,5 +82,13 @@ 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_msg_accepter;
+typedef boost::shared_ptr<mb_msg_accepter> mb_msg_accepter_sptr;
+
+class mb_message;
+typedef boost::shared_ptr<mb_message> mb_message_sptr;
+
+class mb_msg_queue;
+typedef boost::shared_ptr<mb_msg_queue> mb_msg_queue_sptr;
#endif /* INCLUDED_MB_COMMON_H */
diff --git a/mblock/src/lib/mb_mblock.h b/mblock/src/lib/mb_mblock.h
index ce0065f2db..c656f90f22 100644
--- a/mblock/src/lib/mb_mblock.h
+++ b/mblock/src/lib/mb_mblock.h
@@ -24,6 +24,7 @@
#include <mb_common.h>
#include <mb_message.h>
#include <mb_port.h>
+#include <boost/enable_shared_from_this.hpp>
/*!
@@ -45,7 +46,8 @@ public:
*
* Subclass this to define your mblocks.
*/
-class mb_mblock : boost::noncopyable
+class mb_mblock : boost::noncopyable,
+ public boost::enable_shared_from_this<mb_mblock>
{
private:
mb_mblock_impl_sptr d_impl; // implementation details
@@ -120,9 +122,9 @@ protected:
/*!
* \brief connect endpoint_1 to endpoint_2
*
- * \param comp_name1 component on one of the connection
+ * \param comp_name1 component on one end of the connection
* \param port_name1 the name of the port on comp1
- * \param comp_name2 component on the other end the connection
+ * \param comp_name2 component on the other end of the connection
* \param port_name2 the name of the port on comp2
*
* An endpoint is specified by the component's local name (given as
@@ -138,9 +140,9 @@ protected:
/*!
* \brief disconnect endpoint_1 from endpoint_2
*
- * \param comp_name1 component on one of the connection
+ * \param comp_name1 component on one end of the connection
* \param port_name1 the name of the port on comp1
- * \param comp_name2 component on the other end the connection
+ * \param comp_name2 component on the other end of the connection
* \param port_name2 the name of the port on comp2
*
* An endpoint is specified by the component's local name (given as
@@ -181,7 +183,15 @@ public:
*
* The traversal stops and returns false if any call to visitor returns false.
*/
- bool walk_tree(mb_visitor *visitor, const std::string &path="");
+ bool
+ walk_tree(mb_visitor *visitor, const std::string &path="");
+
+
+ //! \implementation
+ // internal use only
+ mb_mblock_impl_sptr
+ impl() const { return d_impl; }
+
};
diff --git a/mblock/src/lib/mb_mblock_impl.cc b/mblock/src/lib/mb_mblock_impl.cc
index 8a9efe2ba7..f4fa523ee5 100644
--- a/mblock/src/lib/mb_mblock_impl.cc
+++ b/mblock/src/lib/mb_mblock_impl.cc
@@ -26,8 +26,10 @@
#include <mb_mblock.h>
#include <mb_protocol_class.h>
#include <mb_port.h>
+#include <mb_port_simple.h>
#include <mb_exception.h>
#include <mb_util.h>
+#include <mb_msg_accepter_smp.h>
static pmt_t s_self = pmt_intern("self");
@@ -49,7 +51,7 @@ mb_mblock_impl::comp_is_defined(const std::string &name)
////////////////////////////////////////////////////////////////////////
mb_mblock_impl::mb_mblock_impl(mb_mblock *mb)
- : d_mb(mb)
+ : d_mb(mb), d_mb_parent(0)
{
}
@@ -66,13 +68,17 @@ mb_mblock_impl::define_port(const std::string &port_name,
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);
+ 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);
- mb_port_sptr p = mb_port_sptr(new mb_port(port_name, protocol_class_name,
- conjugated, port_type));
+ mb_port_sptr p =
+ mb_port_sptr(new mb_port_simple(d_mb,
+ port_name, protocol_class_name,
+ conjugated, port_type));
d_port_map[port_name] = p;
return p;
}
@@ -84,12 +90,15 @@ mb_mblock_impl::define_component(const std::string &name,
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
d_comp_map[name] = component;
}
void
-mb_mblock_impl::connect(const std::string &comp_name1, const std::string &port_name1,
- const std::string &comp_name2, const std::string &port_name2)
+mb_mblock_impl::connect(const std::string &comp_name1,
+ const std::string &port_name1,
+ const std::string &comp_name2,
+ const std::string &port_name2)
{
mb_endpoint ep0 = check_and_resolve_endpoint(comp_name1, port_name1);
mb_endpoint ep1 = check_and_resolve_endpoint(comp_name2, port_name2);
@@ -104,8 +113,10 @@ mb_mblock_impl::connect(const std::string &comp_name1, const std::string &port_n
}
void
-mb_mblock_impl::disconnect(const std::string &comp_name1, const std::string &port_name1,
- const std::string &comp_name2, const std::string &port_name2)
+mb_mblock_impl::disconnect(const std::string &comp_name1,
+ const std::string &port_name1,
+ const std::string &comp_name2,
+ const std::string &port_name2)
{
d_conn_table.disconnect(comp_name1, port_name1, comp_name2, port_name2);
}
@@ -173,7 +184,7 @@ mb_mblock_impl::resolve_port(const std::string &comp_name,
mb_port_sptr c_port = c_impl->d_port_map[port_name];
- if (c_port->port_type() == mb_port::INTERNAL) // can't "see" a child's internal ports
+ if (c_port->port_type() == mb_port::INTERNAL) // can't "see" a child's internal ports
throw mbe_no_such_port(d_mb, mb_util::join_names(comp_name, port_name));
return c_port;
@@ -212,3 +223,12 @@ mb_mblock_impl::walk_tree(mb_visitor *visitor, const std::string &path)
return true;
}
+mb_msg_accepter_sptr
+mb_mblock_impl::make_accepter(const std::string port_name)
+{
+ mb_msg_accepter *ma =
+ new mb_msg_accepter_smp(d_mb->shared_from_this(),
+ pmt_intern(port_name));
+
+ return mb_msg_accepter_sptr(ma);
+}
diff --git a/mblock/src/lib/mb_mblock_impl.h b/mblock/src/lib/mb_mblock_impl.h
index c5610eddd2..1e62dd8d7e 100644
--- a/mblock/src/lib/mb_mblock_impl.h
+++ b/mblock/src/lib/mb_mblock_impl.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,6 +23,7 @@
#include <mb_mblock.h>
#include <mb_connection.h>
+#include <mb_msg_queue.h>
#include <list>
#include <map>
@@ -37,11 +38,14 @@ typedef std::map<std::string, mb_mblock_sptr> mb_comp_map_t;
class mb_mblock_impl : boost::noncopyable
{
mb_mblock *d_mb; // pointer to our associated mblock
+ mb_mblock *d_mb_parent; // pointer to our parent
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
+ mb_msg_queue d_msgq; // incoming messages for us
+
public:
mb_mblock_impl(mb_mblock *mb);
~mb_mblock_impl();
@@ -80,9 +84,9 @@ public:
/*!
* \brief connect endpoint_1 to endpoint_2
*
- * \param comp_name1 component on one of the connection
+ * \param comp_name1 component on one end of the connection
* \param port_name1 the name of the port on comp1
- * \param comp_name2 component on the other end the connection
+ * \param comp_name2 component on the other end of the connection
* \param port_name2 the name of the port on comp2
*
* An endpoint is specified by the component's local name (given as
@@ -98,9 +102,9 @@ public:
/*!
* \brief disconnect endpoint_1 from endpoint_2
*
- * \param comp_name1 component on one of the connection
+ * \param comp_name1 component on one end of the connection
* \param port_name1 the name of the port on comp1
- * \param comp_name2 component on the other end the connection
+ * \param comp_name2 component on the other end of the connection
* \param port_name2 the name of the port on comp2
*
* An endpoint is specified by the component's local name (given as
@@ -135,6 +139,12 @@ public:
bool
walk_tree(mb_visitor *visitor, const std::string &path="");
+ mb_msg_accepter_sptr
+ make_accepter(const std::string port_name);
+
+ mb_msg_queue &
+ msgq() { return d_msgq; }
+
/*
* Our implementation methods
*/
diff --git a/mblock/src/lib/mb_message.cc b/mblock/src/lib/mb_message.cc
index f494201ace..23803726a4 100644
--- a/mblock/src/lib/mb_message.cc
+++ b/mblock/src/lib/mb_message.cc
@@ -31,7 +31,8 @@ mb_make_message(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority)
}
mb_message::mb_message(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority)
- : d_signal(signal), d_data(data), d_metadata(metadata), d_priority(priority)
+ : d_signal(signal), d_data(data), d_metadata(metadata), d_priority(priority),
+ d_port_id(PMT_NIL)
{
}
diff --git a/mblock/src/lib/mb_message.h b/mblock/src/lib/mb_message.h
index ee88d79f74..95440f8b74 100644
--- a/mblock/src/lib/mb_message.h
+++ b/mblock/src/lib/mb_message.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -34,18 +34,21 @@ typedef boost::shared_ptr<mb_message> mb_message_sptr;
* \param metadata information about the data
* \param priority urgency
*/
-mb_message_sptr
+mb_message_sptr
mb_make_message(pmt_t signal,
pmt_t data = PMT_NIL,
pmt_t metadata = PMT_NIL,
mb_pri_t priority = MB_PRI_DEFAULT);
class mb_message {
- pmt_t d_signal;
- pmt_t d_data;
- pmt_t d_metadata;
- mb_pri_t d_priority;
- // foo d_rcvd_port_id;
+ mb_message_sptr d_next; // link field for msg queue
+ pmt_t d_signal;
+ pmt_t d_data;
+ pmt_t d_metadata;
+ mb_pri_t d_priority;
+ pmt_t d_port_id; // name of port msg was rcvd on (symbol)
+
+ friend class mb_msg_queue;
friend mb_message_sptr
mb_make_message(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority);
@@ -60,7 +63,9 @@ public:
pmt_t data() const { return d_data; }
pmt_t metadata() const { return d_metadata; }
mb_pri_t priority() const { return d_priority; }
- // foo rcvd_port_id const { return d_rcvd_port_id; }
+ pmt_t port_id() const { return d_port_id; }
+
+ void set_port_id(pmt_t port_id){ d_port_id = port_id; }
};
#endif /* INCLUDED_MB_MESSAGE_H */
diff --git a/mblock/src/lib/mb_msg_accepter.cc b/mblock/src/lib/mb_msg_accepter.cc
new file mode 100644
index 0000000000..1eded2418c
--- /dev/null
+++ b/mblock/src/lib/mb_msg_accepter.cc
@@ -0,0 +1,31 @@
+/* -*- 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_msg_accepter.h>
+
+mb_msg_accepter::~mb_msg_accepter()
+{
+ // nop
+}
diff --git a/mblock/src/lib/mb_msg_accepter.h b/mblock/src/lib/mb_msg_accepter.h
new file mode 100644
index 0000000000..4f39fda61f
--- /dev/null
+++ b/mblock/src/lib/mb_msg_accepter.h
@@ -0,0 +1,48 @@
+/* -*- 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_MSG_ACCEPTER_H
+#define INCLUDED_MB_MSG_ACCEPTER_H
+
+#include <mb_common.h>
+
+/*!
+ * \brief Abstract class that accepts messages
+ *
+ * The mb_port::send method ultimately resolves the (local)
+ * destination of a send to an object of this type. The resulting
+ * object is called to deliver the message.
+ *
+ * Expect derived classes such as these:
+ *
+ * smp : target is visible in this address space
+ * mpi : target is on the other end of an MPI link
+ * ppe->spe : sending from Cell PPE to Cell SPE
+ * spe->ppe : sending from Cell SPE to Cell PPE
+ */
+class mb_msg_accepter {
+public:
+ mb_msg_accepter(){};
+ virtual ~mb_msg_accepter();
+
+ virtual void operator()(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority) = 0;
+};
+
+#endif /* INCLUDED_MB_MSG_ACCEPTER_H */
diff --git a/mblock/src/lib/mb_msg_accepter_smp.cc b/mblock/src/lib/mb_msg_accepter_smp.cc
new file mode 100644
index 0000000000..9e543979ef
--- /dev/null
+++ b/mblock/src/lib/mb_msg_accepter_smp.cc
@@ -0,0 +1,50 @@
+/* -*- 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_msg_accepter_smp.h>
+#include <mb_common.h>
+#include <mb_mblock.h>
+#include <mb_mblock_impl.h>
+#include <mb_message.h>
+
+mb_msg_accepter_smp::mb_msg_accepter_smp(mb_mblock_sptr mblock, pmt_t port_name)
+ : d_mb(mblock), d_port_name(port_name)
+{
+}
+
+mb_msg_accepter_smp::~mb_msg_accepter_smp()
+{
+ // nop
+}
+
+void
+mb_msg_accepter_smp::operator()(pmt_t signal, pmt_t data,
+ pmt_t metadata, mb_pri_t priority)
+{
+ mb_message_sptr msg = mb_make_message(signal, data, metadata, priority);
+ msg->set_port_id(d_port_name);
+ d_mb->impl()->msgq().insert(msg);
+
+ // FIXME tell runtime that we're ready to run
+}
diff --git a/mblock/src/lib/mb_msg_accepter_smp.h b/mblock/src/lib/mb_msg_accepter_smp.h
new file mode 100644
index 0000000000..bc17f46870
--- /dev/null
+++ b/mblock/src/lib/mb_msg_accepter_smp.h
@@ -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_MSG_ACCEPTER_SMP_H
+#define INCLUDED_MB_MSG_ACCEPTER_SMP_H
+
+#include <mb_msg_accepter.h>
+
+/*!
+ * \brief Concrete message acceptor that does an mb_msg_queue insertion
+ */
+class mb_msg_accepter_smp : public mb_msg_accepter
+{
+ mb_mblock_sptr d_mb;
+ pmt_t d_port_name;
+
+public:
+ mb_msg_accepter_smp(mb_mblock_sptr mblock, pmt_t port_name);
+ ~mb_msg_accepter_smp();
+
+ void operator()(pmt_t signal, pmt_t data, pmt_t metadata, mb_pri_t priority);
+};
+
+
+#endif /* INCLUDED_MB_MSG_ACCEPTER_SMP_H */
diff --git a/mblock/src/lib/mb_msg_queue.cc b/mblock/src/lib/mb_msg_queue.cc
new file mode 100644
index 0000000000..e626949259
--- /dev/null
+++ b/mblock/src/lib/mb_msg_queue.cc
@@ -0,0 +1,80 @@
+/* -*- 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_msg_queue.h>
+#include <mb_message.h>
+
+// FIXME turn this into a template so we can use it for the runq of mblocks too
+
+mb_msg_queue::mb_msg_queue()
+{
+}
+
+mb_msg_queue::~mb_msg_queue()
+{
+}
+
+void
+mb_msg_queue::insert(mb_message_sptr msg)
+{
+ // omni_mutex_lock l(d_mutex); FIXME
+
+ mb_pri_t q = mb_pri_clamp(msg->priority());
+
+ if (d_queue[q].empty_p()){
+ d_queue[q].tail = d_queue[q].head = msg;
+ msg->d_next.reset(); //msg->d_next = 0;
+ }
+ else {
+ d_queue[q].tail->d_next = msg;
+ d_queue[q].tail = msg;
+ msg->d_next.reset(); // msg->d_next = 0;
+ }
+ // FIXME set bit in bitmap
+}
+
+mb_message_sptr
+mb_msg_queue::get_highest_pri_msg()
+{
+ // omni_mutex_lock l(d_mutex); FIXME
+
+ // FIXME use bitmap and ffz to find best queue in O(1)
+
+ for (mb_pri_t q = 0; q <= MB_PRI_WORST; q++){
+
+ if (!d_queue[q].empty_p()){
+ mb_message_sptr msg = d_queue[q].head;
+ d_queue[q].head = msg->d_next;
+ if (d_queue[q].head == 0){
+ d_queue[q].tail.reset(); // d_queue[q].tail = 0;
+ // FIXME clear bit in bitmap
+ }
+
+ msg->d_next.reset(); // msg->d_next = 0;
+ return msg;
+ }
+ }
+
+ return mb_message_sptr(); // equivalent of a zero pointer
+}
diff --git a/mblock/src/lib/mb_msg_queue.h b/mblock/src/lib/mb_msg_queue.h
new file mode 100644
index 0000000000..2749e6a59f
--- /dev/null
+++ b/mblock/src/lib/mb_msg_queue.h
@@ -0,0 +1,59 @@
+/* -*- 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_MSG_QUEUE_H
+#define INCLUDED_MB_MSG_QUEUE_H
+
+#include <mb_common.h>
+//#include <omnithread.h> FIXME
+
+/*!
+ * \brief priority queue for mblock messages
+ */
+class mb_msg_queue : boost::noncopyable
+{
+ // When empty both head and tail are zero.
+ struct subq {
+ mb_message_sptr head;
+ mb_message_sptr tail;
+
+ bool empty_p() const { return head == 0; }
+ };
+
+ // omni_mutex d_mutex; FIXME
+
+ // FIXME add bitmap to indicate which queues are non-empty.
+ subq d_queue[MB_NPRI];
+
+public:
+ mb_msg_queue();
+ ~mb_msg_queue();
+
+ //! Insert \p msg into priority queue.
+ void insert(mb_message_sptr msg);
+
+ /*
+ * \brief Delete highest pri message from the queue and return it.
+ * Returns equivalent of zero pointer if queue is empty.
+ */
+ mb_message_sptr get_highest_pri_msg();
+};
+
+#endif /* INCLUDED_MB_MSG_QUEUE_H */
diff --git a/mblock/src/lib/mb_port.cc b/mblock/src/lib/mb_port.cc
index d7851126b0..5c9f544c4b 100644
--- a/mblock/src/lib/mb_port.cc
+++ b/mblock/src/lib/mb_port.cc
@@ -27,12 +27,13 @@
#include <mb_port_detail.h>
#include <mb_protocol_class.h>
-mb_port::mb_port(const std::string &port_name,
+mb_port::mb_port(mb_mblock *mblock,
+ const std::string &port_name,
const std::string &protocol_class_name,
bool conjugated,
mb_port::port_type_t port_type)
- : d_detail(mb_port_detail_sptr(new mb_port_detail())),
- d_port_name(port_name), d_conjugated(conjugated), d_port_type(port_type)
+ : d_port_name(port_name), d_conjugated(conjugated), d_port_type(port_type),
+ d_mblock(mblock)
{
pmt_t pc = mb_protocol_class_lookup(pmt_intern(protocol_class_name));
if (pmt_is_null(pc)){
diff --git a/mblock/src/lib/mb_port.h b/mblock/src/lib/mb_port.h
index 35ac34e2c6..59a508c92e 100644
--- a/mblock/src/lib/mb_port.h
+++ b/mblock/src/lib/mb_port.h
@@ -24,7 +24,7 @@
#include <mb_common.h>
/*!
- * \brief Public port characteristics
+ * \brief Abstract port characteristics
*/
class mb_port : boost::noncopyable
{
@@ -38,20 +38,21 @@ public:
};
private:
- friend class mb_mblock_impl;
- mb_port_detail_sptr d_detail;
std::string d_port_name;
pmt_t d_protocol_class;
bool d_conjugated;
port_type_t d_port_type;
- // private constructor
- mb_port(const std::string &port_name,
- const std::string &protocol_class_name,
- bool conjugated,
- mb_port::port_type_t port_type);
+protected:
+ mb_mblock *d_mblock; // mblock we're defined in
+ // protected constructor
+ mb_port(mb_mblock *mblock,
+ const std::string &port_name,
+ const std::string &protocol_class_name,
+ bool conjugated,
+ mb_port::port_type_t port_type);
public:
std::string port_name() const { return d_port_name; }
@@ -62,7 +63,7 @@ public:
pmt_t incoming_message_set() const;
pmt_t outgoing_message_set() const;
- ~mb_port();
+ virtual ~mb_port();
/*!
* \brief send a message
@@ -72,12 +73,11 @@ public:
* \param metadata optional metadata
* \param priority the urgency at which the message is sent
*/
- void
+ virtual void
send(pmt_t signal,
pmt_t data = PMT_NIL,
pmt_t metadata = PMT_NIL,
- mb_pri_t priority = MB_PRI_DEFAULT);
-
+ mb_pri_t priority = MB_PRI_DEFAULT) = 0;
};
#endif /* INCLUDED_MB_PORT_H */
diff --git a/mblock/src/lib/mb_port_simple.cc b/mblock/src/lib/mb_port_simple.cc
new file mode 100644
index 0000000000..4896df3a6c
--- /dev/null
+++ b/mblock/src/lib/mb_port_simple.cc
@@ -0,0 +1,59 @@
+/* -*- 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_port_simple.h>
+#include <mb_msg_accepter.h>
+
+mb_port_simple::mb_port_simple(mb_mblock *mblock,
+ const std::string &port_name,
+ const std::string &protocol_class_name,
+ bool conjugated,
+ mb_port::port_type_t port_type)
+ : mb_port(mblock, port_name, protocol_class_name, conjugated, port_type)
+{
+}
+
+mb_port_simple::~mb_port_simple()
+{
+ // nop
+}
+
+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 (accepter)
+ (*accepter)(signal, data, metadata, priority);
+}
+
+mb_msg_accepter_sptr
+mb_port_simple::find_accepter()
+{
+ mb_msg_accepter_sptr r;
+
+ // FIXME, actually do the work ;)
+
+ return r;
+}
diff --git a/mblock/src/lib/mb_port_simple.h b/mblock/src/lib/mb_port_simple.h
new file mode 100644
index 0000000000..3ce3e3cb1b
--- /dev/null
+++ b/mblock/src/lib/mb_port_simple.h
@@ -0,0 +1,59 @@
+/* -*- 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_PORT_SIMPLE_H
+#define INCLUDED_MB_PORT_SIMPLE_H
+
+#include <mb_port.h>
+
+/*!
+ * \brief Concrete port realization
+ */
+class mb_port_simple : public mb_port
+{
+protected:
+ mb_msg_accepter_sptr
+ find_accepter();
+
+public:
+ mb_port_simple(mb_mblock *mblock,
+ const std::string &port_name,
+ const std::string &protocol_class_name,
+ bool conjugated,
+ mb_port::port_type_t port_type);
+
+ ~mb_port_simple();
+
+ /*!
+ * \brief send a message
+ *
+ * \param signal the event name
+ * \param data optional data
+ * \param metadata optional metadata
+ * \param priority the urgency at which the message is sent
+ */
+ void
+ send(pmt_t signal,
+ pmt_t data = PMT_NIL,
+ pmt_t metadata = PMT_NIL,
+ mb_pri_t priority = MB_PRI_DEFAULT);
+};
+
+#endif /* INCLUDED_MB_PORT_SIMPLE_H */
diff --git a/mblock/src/lib/qa_mblock_prims.cc b/mblock/src/lib/qa_mblock_prims.cc
index 432e819aaa..fc3452f968 100644
--- a/mblock/src/lib/qa_mblock_prims.cc
+++ b/mblock/src/lib/qa_mblock_prims.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,6 +26,10 @@
#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_cs = pmt_intern("cs");
@@ -329,3 +333,87 @@ qa_mblock_prims::test_connect()
mb_runtime_sptr rt = mb_make_runtime();
mb_mblock_sptr mb0 = mb_mblock_sptr(new tc_0());
}
+
+////////////////////////////////////////////////////////////////
+
+void
+qa_mblock_prims::test_msg_queue()
+{
+ mb_msg_queue q;
+
+ // check initial state
+ CPPUNIT_ASSERT(q.get_highest_pri_msg() == 0);
+
+ CPPUNIT_ASSERT(MB_NPRI >= 5); // sanity check for this test
+
+ // insert three messages at the same pri and ensure that they come out in order
+ // signal data metadata pri
+ q.insert(mb_make_message(PMT_NIL, pmt_from_long(0), PMT_NIL, MB_PRI_BEST + 2));
+ q.insert(mb_make_message(PMT_NIL, pmt_from_long(1), PMT_NIL, MB_PRI_BEST + 2));
+ q.insert(mb_make_message(PMT_NIL, pmt_from_long(2), PMT_NIL, MB_PRI_BEST + 2));
+
+ CPPUNIT_ASSERT_EQUAL(0L, pmt_to_long(q.get_highest_pri_msg()->data()));
+ CPPUNIT_ASSERT_EQUAL(1L, pmt_to_long(q.get_highest_pri_msg()->data()));
+ CPPUNIT_ASSERT_EQUAL(2L, pmt_to_long(q.get_highest_pri_msg()->data()));
+
+ CPPUNIT_ASSERT(q.get_highest_pri_msg() == 0);
+
+
+ // insert messages of different priorities in pseudo-random order
+ // signal data metadata pri
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 3));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 2));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 4));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 0));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 1));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 3));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 2));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 4));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 0));
+ q.insert(mb_make_message(PMT_NIL, PMT_NIL, PMT_NIL, MB_PRI_BEST + 1));
+
+ // confirm that they come out in order
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 0, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 0, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 1, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 1, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 2, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 2, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 3, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 3, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 4, q.get_highest_pri_msg()->priority());
+ CPPUNIT_ASSERT_EQUAL(MB_PRI_BEST + 4, q.get_highest_pri_msg()->priority());
+
+ // check final state
+ CPPUNIT_ASSERT(q.get_highest_pri_msg() == 0);
+}
+
+////////////////////////////////////////////////////////////////
+
+void
+qa_mblock_prims::test_make_accepter()
+{
+ // create a block
+ mb_mblock_sptr mb = mb_mblock_sptr(new dp_2());
+
+ // use "internal use only" method...
+ mb_msg_accepter_sptr accepter = mb->impl()->make_accepter("cs");
+
+ // Now push a few messages into it...
+ // signal data metadata pri
+ (*accepter)(PMT_NIL, pmt_from_long(0), PMT_NIL, MB_PRI_BEST + 2);
+ (*accepter)(PMT_NIL, pmt_from_long(1), PMT_NIL, MB_PRI_BEST + 2);
+ (*accepter)(PMT_NIL, pmt_from_long(2), PMT_NIL, MB_PRI_BEST + 2);
+
+ // try to pull them out
+
+ pmt_t cs = pmt_intern("cs");
+
+ mb_message_sptr msg = mb->impl()->msgq().get_highest_pri_msg();
+ CPPUNIT_ASSERT(pmt_eq(cs, msg->port_id())); // confirm that port_id is set
+ CPPUNIT_ASSERT_EQUAL(0L, pmt_to_long(msg->data())); // and that data is correct
+
+ 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()));
+}
+
diff --git a/mblock/src/lib/qa_mblock_prims.h b/mblock/src/lib/qa_mblock_prims.h
index 36b35550f7..4eb6c4ea0e 100644
--- a/mblock/src/lib/qa_mblock_prims.h
+++ b/mblock/src/lib/qa_mblock_prims.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2007 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -31,12 +31,16 @@ class qa_mblock_prims : public CppUnit::TestCase {
CPPUNIT_TEST(test_define_ports);
CPPUNIT_TEST(test_define_components);
CPPUNIT_TEST(test_connect);
+ CPPUNIT_TEST(test_msg_queue);
+ CPPUNIT_TEST(test_make_accepter);
CPPUNIT_TEST_SUITE_END();
private:
void test_define_ports();
void test_define_components();
void test_connect();
+ void test_msg_queue();
+ void test_make_accepter();
};
#endif /* INCLUDED_QA_MBLOCK_PRIMS_H */