summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjcorgan2007-05-05 18:26:33 +0000
committerjcorgan2007-05-05 18:26:33 +0000
commitb37d879f6b46225fab22862f193f10d1908400e1 (patch)
tree2e5816d582b4e19806cce8652dc298d7ede823ce
parent6b1e25d6c62d82369548ecad4b86a0795be23025 (diff)
downloadgnuradio-b37d879f6b46225fab22862f193f10d1908400e1.tar.gz
gnuradio-b37d879f6b46225fab22862f193f10d1908400e1.tar.bz2
gnuradio-b37d879f6b46225fab22862f193f10d1908400e1.zip
Merged r5241:5242 from jcorgan/reconf into trunk. Trunk passes distcheck.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@5243 221aa14e-8319-0410-a670-987f0aec2ac5
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc22
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.h7
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.i2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc61
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h7
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.cc15
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.h20
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.cc37
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.h9
9 files changed, 170 insertions, 10 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
index d5ed4ccc9..9811b9def 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -29,6 +29,8 @@
#include <gr_hier_block2_detail.h>
#include <iostream>
+#define GR_HIER_BLOCK2_DEBUG 1
+
gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
gr_io_signature_sptr input_signature,
gr_io_signature_sptr output_signature)
@@ -62,3 +64,23 @@ gr_hier_block2::disconnect(gr_basic_block_sptr src, int src_port,
{
d_detail->disconnect(src, src_port, dst, dst_port);
}
+
+void
+gr_hier_block2::set_runtime(gr_runtime *runtime)
+{
+ if (GR_HIER_BLOCK2_DEBUG)
+ std::cout << "Setting runtime on " << this << " to " << runtime << std::endl;
+ d_detail->set_runtime(runtime);
+}
+
+void
+gr_hier_block2::lock()
+{
+ d_detail->lock();
+}
+
+void
+gr_hier_block2::unlock()
+{
+ d_detail->unlock();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
index 53a23bb47..da483098e 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.h
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
@@ -50,7 +50,10 @@ private:
* \brief Private implementation details of gr_hier_block2
*/
gr_hier_block2_detail *d_detail;
-
+
+ /* Internal use only */
+ void set_runtime(gr_runtime *runtime);
+
protected:
gr_hier_block2(const std::string &name,
gr_io_signature_sptr input_signature,
@@ -63,6 +66,8 @@ public:
gr_basic_block_sptr dst, int dst_port);
void disconnect(gr_basic_block_sptr src, int src_port,
gr_basic_block_sptr dst, int dst_port);
+ void lock();
+ void unlock();
};
#endif /* INCLUDED_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
index f9a126fe2..f899b6894 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.i
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
@@ -50,4 +50,6 @@ public:
void disconnect(gr_basic_block_sptr src, int src_port,
gr_basic_block_sptr dst, int dst_port)
throw (std::invalid_argument);
+ void lock();
+ void unlock();
};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
index 4e9380689..307cbabeb 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -26,6 +26,7 @@
#include <gr_hier_block2_detail.h>
#include <gr_simple_flowgraph.h>
#include <gr_io_signature.h>
+#include <gr_runtime.h>
#include <stdexcept>
#include <iostream>
@@ -33,9 +34,11 @@
gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
d_owner(owner),
+ d_parent_detail(0),
d_fg(gr_make_simple_flowgraph()),
d_inputs(owner->input_signature()->max_streams()),
- d_outputs(owner->output_signature()->max_streams())
+ d_outputs(owner->output_signature()->max_streams()),
+ d_runtime()
{
}
@@ -55,6 +58,21 @@ gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port,
if (src.get() == dst.get())
throw std::invalid_argument("src and destination blocks cannot be the same");
+ gr_hier_block2_sptr src_block(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(src));
+ gr_hier_block2_sptr dst_block(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(dst));
+
+ if (src_block && src.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
+ src_block->d_detail->d_parent_detail = this;
+ }
+
+ if (dst_block && dst.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
+ dst_block->d_detail->d_parent_detail = this;
+ }
+
// Connections to block inputs or outputs
int max_port;
if (src.get() == d_owner) {
@@ -88,6 +106,21 @@ gr_hier_block2_detail::disconnect(gr_basic_block_sptr src, int src_port,
if (src.get() == dst.get())
throw std::invalid_argument("src and destination blocks cannot be the same");
+ gr_hier_block2_sptr src_block(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(src));
+ gr_hier_block2_sptr dst_block(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(dst));
+
+ if (src_block && src.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, clearing parent" << std::endl;
+ src_block->d_detail->d_parent_detail = 0;
+ }
+
+ if (dst_block && dst.get() != d_owner) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, clearing parent" << std::endl;
+ dst_block->d_detail->d_parent_detail = 0;
+ }
+
if (src.get() == d_owner)
return disconnect_input(src_port, dst_port, dst);
@@ -219,3 +252,29 @@ gr_hier_block2_detail::flatten(gr_simple_flowgraph_sptr sfg)
hier_block2->d_detail->flatten(sfg);
}
}
+
+void
+gr_hier_block2_detail::lock()
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "lock: entered in " << this << std::endl;
+
+ if (d_parent_detail)
+ d_parent_detail->lock();
+ else
+ if (d_runtime)
+ d_runtime->lock();
+}
+
+void
+gr_hier_block2_detail::unlock()
+{
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "unlock: entered in " << this << std::endl;
+
+ if (d_parent_detail)
+ d_parent_detail->unlock();
+ else
+ if (d_runtime)
+ d_runtime->unlock();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
index 15c8548c6..254709ffb 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
@@ -36,10 +36,12 @@ private:
// Private implementation data
gr_hier_block2 *d_owner;
+ gr_hier_block2_detail *d_parent_detail;
gr_simple_flowgraph_sptr d_fg;
gr_endpoint_vector_t d_inputs;
gr_endpoint_vector_t d_outputs;
-
+ gr_runtime *d_runtime;
+
// Private implementation methods
void connect(gr_basic_block_sptr src, int src_port,
gr_basic_block_sptr dst, int dst_port);
@@ -52,6 +54,9 @@ private:
void flatten(gr_simple_flowgraph_sptr sfg);
gr_endpoint resolve_port(int port, bool is_input);
gr_endpoint resolve_endpoint(const gr_endpoint &endp, bool is_input);
+ void set_runtime(gr_runtime *runtime) { d_runtime = runtime; }
+ void lock();
+ void unlock();
public:
~gr_hier_block2_detail();
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.cc b/gnuradio-core/src/lib/runtime/gr_runtime.cc
index 3a992f689..a77aac432 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime.cc
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.cc
@@ -36,7 +36,7 @@ gr_make_runtime(gr_hier_block2_sptr top_block)
gr_runtime::gr_runtime(gr_hier_block2_sptr top_block)
{
- d_impl = new gr_runtime_impl(top_block);
+ d_impl = new gr_runtime_impl(top_block, this);
}
gr_runtime::~gr_runtime()
@@ -74,3 +74,16 @@ gr_runtime::restart()
{
d_impl->restart();
}
+
+void
+gr_runtime::lock()
+{
+ d_impl->lock();
+}
+
+void
+gr_runtime::unlock()
+{
+ d_impl->unlock();
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
index 5aec6dcf0..23bdfaa78 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime.h
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.h
@@ -80,6 +80,26 @@ public:
* recreates new threads (possibly a different number from before.)
*/
void restart();
+
+ /*!
+ * Lock a flow graph in preparation for reconfiguration. When an equal
+ * number of calls to lock() and unlock() have occurred, the flow graph
+ * will be restarted automatically.
+ *
+ * N.B. lock() and unlock() cannot be called from a flow graph thread or
+ * deadlock will occur when reconfiguration happens.
+ */
+ void lock();
+
+ /*!
+ * Lock a flow graph in preparation for reconfiguration. When an equal
+ * number of calls to lock() and unlock() have occurred, the flow graph
+ * will be restarted automatically.
+ *
+ * N.B. lock() and unlock() cannot be called from a flow graph thread or
+ * deadlock will occur when reconfiguration happens.
+ */
+ void unlock();
};
#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
index 64fbca9c9..54fc7d19a 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
@@ -53,17 +53,20 @@ runtime_sigint_handler(int signum)
s_runtime->stop();
}
-gr_runtime_impl::gr_runtime_impl(gr_hier_block2_sptr top_block)
+gr_runtime_impl::gr_runtime_impl(gr_hier_block2_sptr top_block, gr_runtime *owner)
: d_running(false),
d_top_block(top_block),
- d_sfg(gr_make_simple_flowgraph())
+ d_sfg(gr_make_simple_flowgraph()),
+ d_owner(owner)
{
s_runtime = this;
+ top_block->set_runtime(d_owner);
}
gr_runtime_impl::~gr_runtime_impl()
{
- s_runtime = 0; // we don't own this
+ s_runtime = 0; // don't call delete we don't own these
+ d_owner = 0;
}
void
@@ -142,6 +145,33 @@ gr_runtime_impl::wait()
d_threads.clear();
}
+
+// N.B. lock() and unlock() cannot be called from a flow graph thread or
+// deadlock will occur when reconfiguration happens
+void
+gr_runtime_impl::lock()
+{
+ omni_mutex_lock lock(d_reconf);
+ d_lock_count++;
+ if (GR_RUNTIME_IMPL_DEBUG)
+ std::cout << "runtime: locked, count = " << d_lock_count << std::endl;
+}
+
+void
+gr_runtime_impl::unlock()
+{
+ omni_mutex_lock lock(d_reconf);
+ if (d_lock_count == 0)
+ throw std::runtime_error("unpaired unlock() call");
+
+ d_lock_count--;
+ if (GR_RUNTIME_IMPL_DEBUG)
+ std::cout << "runtime: unlocked, count = " << d_lock_count << std::endl;
+
+ if (d_lock_count == 0)
+ restart();
+}
+
void
gr_runtime_impl::restart()
{
@@ -208,4 +238,3 @@ gr_scheduler_thread::stop()
{
d_sts->stop();
}
-
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.h b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
index 0fb6e1f0d..5dc2311cb 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
@@ -66,7 +66,7 @@ public:
class gr_runtime_impl
{
private:
- gr_runtime_impl(gr_hier_block2_sptr top_block);
+ gr_runtime_impl(gr_hier_block2_sptr top_block, gr_runtime *owner);
friend void runtime_sigint_handler(int signum);
friend class gr_runtime;
@@ -75,12 +75,17 @@ private:
gr_simple_flowgraph_sptr d_sfg;
std::vector<gr_block_vector_t> d_graphs;
gr_scheduler_thread_vector_t d_threads;
-
+ gr_runtime *d_owner;
+ int d_lock_count;
+ omni_mutex d_reconf;
+
void start();
void start_threads();
void stop();
void wait();
void restart();
+ void lock();
+ void unlock();
public:
~gr_runtime_impl();