summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-runtime/lib/top_block_impl.cc23
-rw-r--r--gnuradio-runtime/lib/top_block_impl.h2
-rw-r--r--gnuradio-runtime/python/gnuradio/gr/top_block.py8
-rw-r--r--gnuradio-runtime/swig/top_block.i8
-rwxr-xr-xgr-blocks/python/blocks/qa_hier_block2.py16
-rwxr-xr-xgr-digital/examples/ofdm/tunnel.py11
6 files changed, 60 insertions, 8 deletions
diff --git a/gnuradio-runtime/lib/top_block_impl.cc b/gnuradio-runtime/lib/top_block_impl.cc
index b7322c8e2a..48404a6832 100644
--- a/gnuradio-runtime/lib/top_block_impl.cc
+++ b/gnuradio-runtime/lib/top_block_impl.cc
@@ -86,6 +86,9 @@ namespace gr {
top_block_impl::~top_block_impl()
{
+ if (d_lock_count) {
+ std::cerr << "error: destroying locked block." << std::endl;
+ }
d_owner = 0;
}
@@ -129,6 +132,21 @@ namespace gr {
void
top_block_impl::wait()
{
+ do {
+ wait_for_jobs();
+ {
+ gr::thread::scoped_lock lock(d_mutex);
+ if (!d_lock_count) {
+ break;
+ }
+ d_lock_cond.wait(lock);
+ }
+ } while(true);
+ }
+
+ void
+ top_block_impl::wait_for_jobs()
+ {
if(d_scheduler)
d_scheduler->wait();
@@ -141,6 +159,7 @@ namespace gr {
top_block_impl::lock()
{
gr::thread::scoped_lock lock(d_mutex);
+ stop();
d_lock_count++;
}
@@ -158,6 +177,7 @@ namespace gr {
if(d_lock_count > 0 || d_state == IDLE) // nothing to do
return;
+ d_lock_cond.notify_all();
restart();
}
@@ -167,8 +187,7 @@ namespace gr {
void
top_block_impl::restart()
{
- stop(); // Stop scheduler and wait for completion
- wait();
+ wait_for_jobs();
// Create new simple flow graph
flat_flowgraph_sptr new_ffg = d_owner->flatten();
diff --git a/gnuradio-runtime/lib/top_block_impl.h b/gnuradio-runtime/lib/top_block_impl.h
index 67395e0c35..1ac5136ddf 100644
--- a/gnuradio-runtime/lib/top_block_impl.h
+++ b/gnuradio-runtime/lib/top_block_impl.h
@@ -82,10 +82,12 @@ namespace gr {
gr::thread::mutex d_mutex; // protects d_state and d_lock_count
tb_state d_state;
int d_lock_count;
+ boost::condition_variable d_lock_cond;
int d_max_noutput_items;
private:
void restart();
+ void wait_for_jobs();
};
} /* namespace gr */
diff --git a/gnuradio-runtime/python/gnuradio/gr/top_block.py b/gnuradio-runtime/python/gnuradio/gr/top_block.py
index f9872fc114..f449d98489 100644
--- a/gnuradio-runtime/python/gnuradio/gr/top_block.py
+++ b/gnuradio-runtime/python/gnuradio/gr/top_block.py
@@ -22,7 +22,7 @@
from runtime_swig import top_block_swig, \
top_block_wait_unlocked, top_block_run_unlocked, \
top_block_start_unlocked, top_block_stop_unlocked, \
- dot_graph_tb
+ top_block_unlock_unlocked, dot_graph_tb
#import gnuradio.gr.gr_threading as _threading
import gr_threading as _threading
@@ -118,6 +118,12 @@ class top_block(hier_block2):
self.start(max_noutput_items)
self.wait()
+ def unlock(self):
+ """
+ Release lock and continue execution of flow-graph.
+ """
+ top_block_unlock_unlocked(self._impl)
+
def wait(self):
"""
Wait for the flowgraph to finish running
diff --git a/gnuradio-runtime/swig/top_block.i b/gnuradio-runtime/swig/top_block.i
index 60c9e1a232..c7ee0af941 100644
--- a/gnuradio-runtime/swig/top_block.i
+++ b/gnuradio-runtime/swig/top_block.i
@@ -89,6 +89,14 @@ void top_block_stop_unlocked(gr::top_block_sptr r) throw (std::runtime_error)
)
}
+void top_block_unlock_unlocked(gr::top_block_sptr r) throw (std::runtime_error)
+{
+ GR_PYTHON_BLOCKING_CODE
+ (
+ r->unlock();
+ )
+}
+
std::string
dot_graph_tb(gr::top_block_sptr r)
{
diff --git a/gr-blocks/python/blocks/qa_hier_block2.py b/gr-blocks/python/blocks/qa_hier_block2.py
index 5a351f2b37..97206a248d 100755
--- a/gr-blocks/python/blocks/qa_hier_block2.py
+++ b/gr-blocks/python/blocks/qa_hier_block2.py
@@ -2,6 +2,7 @@
from gnuradio import gr, gr_unittest, blocks
import numpy
+import time
class add_ff(gr.sync_block):
def __init__(self):
@@ -426,5 +427,20 @@ class test_hier_block2(gr_unittest.TestCase):
procs = hblock.processor_affinity()
self.assertEquals((0,), procs)
+ def test_lock_unlock(self):
+ hblock = gr.top_block("test_block")
+ src = blocks.null_source(gr.sizeof_float)
+ throttle = blocks.throttle(gr.sizeof_float, 32000)
+ hier = multiply_const_ff(0.5)
+ sink = blocks.null_sink(gr.sizeof_float)
+ hblock.connect(src, throttle, hier, sink)
+ hblock.set_processor_affinity([0,])
+ hblock.start()
+ time.sleep(1)
+ hblock.lock()
+ hblock.unlock()
+ hblock.stop()
+ hblock.wait()
+
if __name__ == "__main__":
gr_unittest.run(test_hier_block2, "test_hier_block2.xml")
diff --git a/gr-digital/examples/ofdm/tunnel.py b/gr-digital/examples/ofdm/tunnel.py
index f407aef8d6..17b31db9af 100755
--- a/gr-digital/examples/ofdm/tunnel.py
+++ b/gr-digital/examples/ofdm/tunnel.py
@@ -89,15 +89,16 @@ class my_top_block(gr.top_block):
self.source = uhd_receiver(options.args,
options.bandwidth,
- options.rx_freq, options.rx_gain,
+ options.rx_freq,
+ options.lo_offset, options.rx_gain,
options.spec, options.antenna,
- options.verbose)
+ options.clock_source, options.verbose)
self.sink = uhd_transmitter(options.args,
- options.bandwidth,
- options.tx_freq, options.tx_gain,
+ options.bandwidth, options.tx_freq,
+ options.lo_offset, options.tx_gain,
options.spec, options.antenna,
- options.verbose)
+ options.clock_source, options.verbose)
self.txpath = transmit_path(options)
self.rxpath = receive_path(callback, options)