diff options
author | jcorgan | 2007-05-05 18:26:33 +0000 |
---|---|---|
committer | jcorgan | 2007-05-05 18:26:33 +0000 |
commit | b37d879f6b46225fab22862f193f10d1908400e1 (patch) | |
tree | 2e5816d582b4e19806cce8652dc298d7ede823ce | |
parent | 6b1e25d6c62d82369548ecad4b86a0795be23025 (diff) | |
download | gnuradio-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.cc | 22 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_hier_block2.h | 7 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_hier_block2.i | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc | 61 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h | 7 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_runtime.cc | 15 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_runtime.h | 20 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_runtime_impl.cc | 37 | ||||
-rw-r--r-- | gnuradio-core/src/lib/runtime/gr_runtime_impl.h | 9 |
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(); |