commit-gnuradio
[Top][All Lists]
Advanced

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

[Commit-gnuradio] r5237 - gnuradio/branches/developers/jcorgan/disc2/gnu


From: jcorgan
Subject: [Commit-gnuradio] r5237 - gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime
Date: Fri, 4 May 2007 15:23:57 -0600 (MDT)

Author: jcorgan
Date: 2007-05-04 15:23:57 -0600 (Fri, 04 May 2007)
New Revision: 5237

Modified:
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
   
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
Log:
Update to handle changes in number of inputs or outputs when reconfigured.

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
 2007-05-04 01:02:30 UTC (rev 5236)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
 2007-05-04 21:23:57 UTC (rev 5237)
@@ -46,6 +46,9 @@
 void 
 runtime_sigint_handler(int signum)
 {
+  if (GR_RUNTIME_IMPL_DEBUG)
+    std::cout << "SIGINT received, calling stop() on all threads" << std::endl;
+
   if (s_runtime)
     s_runtime->stop();
 }
@@ -132,6 +135,8 @@
       std::cout << "wait: joining thread " << (*p) << std::endl;
     (*p)->join(&dummy_status); // pthreads will self-delete, so pointer is now 
dead
     (*p) = 0; // FIXME: switch to stl::list and actually remove from container
+    if (GR_RUNTIME_IMPL_DEBUG)
+      std::cout << "wait: join returned" << std::endl;
   }
 
   d_threads.clear();
@@ -157,6 +162,9 @@
   d_top_block->d_detail->flatten(new_sfg);
   new_sfg->validate();
   new_sfg->d_detail->merge_connections(d_sfg);
+
+  if (GR_RUNTIME_IMPL_DEBUG)
+    std::cout << "restart: replacing old flow graph with new" << std::endl;
   d_sfg = new_sfg;
 
   start_threads();

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
      2007-05-04 01:02:30 UTC (rev 5236)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
      2007-05-04 21:23:57 UTC (rev 5237)
@@ -31,6 +31,7 @@
 #include <gr_buffer.h>
 #include <iostream>
 #include <stdexcept>
+#include <map>
 
 #define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 1
 
@@ -117,6 +118,9 @@
     std::vector<int> used_ports;
     int ninputs, noutputs;
 
+    if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+      std::cout << "Validating block: " << (*p) << std::endl;
+
     used_ports = calc_used_ports(*p, true); // inputs
     ninputs = used_ports.size();
     check_contiguity(*p, used_ports, true); // inputs
@@ -194,86 +198,6 @@
   }
 }
 
-gr_block_detail_sptr
-gr_simple_flowgraph_detail::allocate_block_detail(gr_basic_block_sptr block)
-{
-  int ninputs = calc_used_ports(block, true).size();
-  int noutputs = calc_used_ports(block, false).size();
-  gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
-  for (int i = 0; i < noutputs; i++)
-    detail->set_output(i, allocate_buffer(block, i));
-
-  return detail;
-}
-
-void
-gr_simple_flowgraph_detail::connect_block_inputs(gr_basic_block_sptr block)
-{
-  gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(block));
-  if (!grblock)
-    throw std::runtime_error("found non-gr_block");
-  
-  // Get its detail and edges that feed into it
-  gr_block_detail_sptr detail = grblock->detail();
-  gr_edge_vector_t in_edges = calc_upstream_edges(block);
-  
-  // For each edge that feeds into it
-  for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
-    // Set the buffer reader on the destination port to the output
-    // buffer on the source port
-    int dst_port = (*e)->dst().port();
-    int src_port = (*e)->src().port();
-    gr_basic_block_sptr src_block = (*e)->src().block();
-    gr_block_sptr src_grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(src_block));
-    if (!grblock)
-      throw std::runtime_error("found non-gr_block");
-    gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
-    
-    detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, 
grblock->history()-1));
-  }
-}
-
-void
-gr_simple_flowgraph_detail::setup_connections()
-{
-  // Assign block details to blocks
-  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
-    boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p)->set_detail(allocate_block_detail(*p));
-
-  // Connect inputs to outputs for each block
-  for(gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
-    connect_block_inputs(*p);
-}
-
-gr_buffer_sptr
-gr_simple_flowgraph_detail::allocate_buffer(gr_basic_block_sptr block, int 
port)
-{
-  gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(block));
-  if (!grblock)
-    throw std::runtime_error("allocate_buffer found non-gr_block");
-  int item_size = block->output_signature()->sizeof_stream_item(port);
-  int nitems = s_fixed_buffer_size/item_size;
-
-  // Make sure there are at least twice the output_multiple no. of items
-  if (nitems < 2*grblock->output_multiple())   // Note: this means 
output_multiple()
-    nitems = 2*grblock->output_multiple();     // can't be changed by block 
dynamically
-
-  // If any downstream blocks are decimators and/or have a large 
output_multiple,
-  // ensure we have a buffer at least twice their decimation 
factor*output_multiple
-  gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
-  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
-    gr_block_sptr dgrblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
-      if (!dgrblock)
-       throw std::runtime_error("allocate_buffer found non-gr_block");
-    int decimation = (int)(1.0/dgrblock->relative_rate());
-    int multiple   = dgrblock->output_multiple();
-    int history    = dgrblock->history();
-    nitems = std::max(nitems, 2*(decimation*multiple+history));
-  }
-
-  return gr_make_buffer(nitems, item_size);
-}
-
 gr_basic_block_vector_t
 gr_simple_flowgraph_detail::calc_downstream_blocks(gr_basic_block_sptr block, 
int port)
 {
@@ -511,73 +435,175 @@
   return result;
 }
 
+gr_block_detail_sptr
+gr_simple_flowgraph_detail::allocate_block_detail(gr_basic_block_sptr block, 
gr_block_detail_sptr old_detail)
+{
+  int ninputs = calc_used_ports(block, true).size();
+  int noutputs = calc_used_ports(block, false).size();
+  gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+
+  if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+    std::cout << "Creating block detail for " << block << std::endl;
+
+  // Re-use or allocate output buffers
+  for (int i = 0; i < noutputs; i++) {
+    gr_buffer_sptr buffer;
+
+    if (!old_detail || i >= old_detail->noutputs()) {
+      if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+       std::cout << "Allocating new buffer for output " << i << std::endl;
+      buffer = allocate_buffer(block, i);
+    }
+    else {
+      if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+       std::cout << "Reusing old buffer for output " << i << std::endl;
+      buffer = old_detail->output(i);
+    }
+
+    detail->set_output(i, buffer);
+  }
+
+  return detail;
+}
+
 void
+gr_simple_flowgraph_detail::connect_block_inputs(gr_basic_block_sptr block)
+{
+  gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(block));
+  if (!grblock)
+    throw std::runtime_error("found non-gr_block");
+  
+  // Get its detail and edges that feed into it
+  gr_block_detail_sptr detail = grblock->detail();
+  gr_edge_vector_t in_edges = calc_upstream_edges(block);
+  
+  // For each edge that feeds into it
+  for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+    // Set the buffer reader on the destination port to the output
+    // buffer on the source port
+    int dst_port = (*e)->dst().port();
+    int src_port = (*e)->src().port();
+    gr_basic_block_sptr src_block = (*e)->src().block();
+    gr_block_sptr src_grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(src_block));
+    if (!grblock)
+      throw std::runtime_error("found non-gr_block");
+    gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
+    
+    if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+      std::cout << "Setting input " << dst_port << " from edge " << (*e) << 
std::endl;
+
+    detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, 
grblock->history()-1));
+  }
+}
+
+gr_buffer_sptr
+gr_simple_flowgraph_detail::allocate_buffer(gr_basic_block_sptr block, int 
port)
+{
+  gr_block_sptr grblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(block));
+  if (!grblock)
+    throw std::runtime_error("allocate_buffer found non-gr_block");
+  int item_size = block->output_signature()->sizeof_stream_item(port);
+  int nitems = s_fixed_buffer_size/item_size;
+
+  // Make sure there are at least twice the output_multiple no. of items
+  if (nitems < 2*grblock->output_multiple())   // Note: this means 
output_multiple()
+    nitems = 2*grblock->output_multiple();     // can't be changed by block 
dynamically
+
+  // If any downstream blocks are decimators and/or have a large 
output_multiple,
+  // ensure we have a buffer at least twice their decimation 
factor*output_multiple
+  gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+    gr_block_sptr dgrblock(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
+      if (!dgrblock)
+       throw std::runtime_error("allocate_buffer found non-gr_block");
+    int decimation = (int)(1.0/dgrblock->relative_rate());
+    int multiple   = dgrblock->output_multiple();
+    int history    = dgrblock->history();
+    nitems = std::max(nitems, 2*(decimation*multiple+history));
+  }
+
+  return gr_make_buffer(nitems, item_size);
+}
+
+void
+gr_simple_flowgraph_detail::setup_connections()
+{
+  // Assign block details to blocks
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
+    boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p)->set_detail(allocate_block_detail(*p));
+
+  // Connect inputs to outputs for each block
+  for(gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++)
+    connect_block_inputs(*p);
+}
+
+void
 gr_simple_flowgraph_detail::merge_connections(gr_simple_flowgraph_sptr old_sfg)
 {
-  // If a block is new, allocate detail and output buffers
+  std::map<gr_block_sptr, gr_block_detail_sptr> old_details;
+
+  // Allocate or reuse output buffers
   for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
     gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
 
-    if (!block->detail())
-      block->set_detail(allocate_block_detail(*p));
+    gr_block_detail_sptr old_detail = block->detail();
+    block->set_detail(allocate_block_detail(block, old_detail));
+
+    // Save old detail for use in next step
+    old_details[block] = old_detail;
   }
 
-  // For each block used in new flow graph, see if it exists in old flow graph
   for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+    gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
+
     if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
       std::cout << "merge: testing " << (*p) << "...";
     
     if (old_sfg->d_detail->has_block_p(*p)) {
-
       // Block exists in old flow graph
       if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
-       std::cout << "already exists" << std::endl;
+       std::cout << "used in old flow graph" << std::endl;
+      gr_block_detail_sptr detail = block->detail();
 
-      // Fish out the number of inputs on existing block detail
-      gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(*p));
-      int ninputs = block->detail()->ninputs();
-
       // Iterate through the inputs and see what needs to be done
-      for (int i = 0; i < ninputs; i++) {
+      for (int i = 0; i < detail->ninputs(); i++) {
        if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
          std::cout << "Checking input " << i << "...";
 
        gr_edge_sptr edge = calc_upstream_edge(*p, i);
-       // The input edge went away
-       if (!edge) {
-         if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
-           std::cout << "not assigned, removing old reader if any" << 
std::endl;
-         block->detail()->clear_input(i);
-         continue;
-       }
+       if (!edge)
+         throw std::runtime_error("merge: missing input edge");
 
-       // Fish out existing buffer reader and see if it matches correct buffer 
from edge list
+       // Fish out old buffer reader and see if it matches correct buffer from 
edge list
        gr_block_sptr src_block(boost::dynamic_pointer_cast<gr_block, 
gr_basic_block>(edge->src().block()));
        gr_block_detail_sptr src_detail = src_block->detail();
-       gr_buffer_sptr buffer = src_detail->output(edge->src().port());
-       gr_buffer_reader_sptr reader = block->detail()->input(i);
+       gr_buffer_sptr src_buffer = src_detail->output(edge->src().port());
+       gr_buffer_reader_sptr old_reader;
+       gr_block_detail_sptr old_detail = old_details[block];
+       if (old_detail && i < old_detail->ninputs())
+         old_reader = old_detail->input(i);
        
-       // If there's a match, skip to next input
-       if (buffer == reader->buffer()) {
+       // If there's a match, use it
+       if (old_reader && (src_buffer == old_reader->buffer())) {
          if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
            std::cout << "matched" << std::endl;
-         continue;
+         detail->set_input(i, old_reader);
+
        }
        else {
          if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
-           std::cout << "no longer valid" << std::endl;
+           std::cout << "needs a new reader" << std::endl;
 
          // Create new buffer reader and assign
-         block->detail()->set_input(i, gr_buffer_add_reader(buffer, 
block->history()-1));
+         detail->set_input(i, gr_buffer_add_reader(src_buffer, 
block->history()-1));
        }
       }
     }
     else {
+      // Block is new, it just needs buffer readers at this point
       if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
        std::cout << "new block" << std::endl;
-
-      // This block just needs buffer readers at this point
-      connect_block_inputs(*p);
+      connect_block_inputs(block);
     }
-  }
+  }  
 }

Modified: 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
===================================================================
--- 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
       2007-05-04 01:02:30 UTC (rev 5236)
+++ 
gnuradio/branches/developers/jcorgan/disc2/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
       2007-05-04 21:23:57 UTC (rev 5237)
@@ -80,7 +80,8 @@
   void merge_connections(gr_simple_flowgraph_sptr sfg);
 
   void connect_block_inputs(gr_basic_block_sptr block);
-  gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block);
+  gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block, 
+                                            gr_block_detail_sptr 
old_detail=gr_block_detail_sptr());
   gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port);
   gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, 
int port);
   gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block);
@@ -104,7 +105,7 @@
 inline std::ostream&
 operator <<(std::ostream &os, const gr_endpoint endp)
 {
-  os << endp.block()->name() << ":" << endp.port();
+  os << endp.block() << ":" << endp.port();
   return os;
 }
 





reply via email to

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