Changeset 8271

Show
Ignore:
Timestamp:
04/24/08 14:32:58
Author:
jcorgan
Message:

Merged changeset r8231:8270 from jcorgan/merge-fix into trunk. Fixes flowgraph reconfiguration bug reported by Tim O'Shea and Mark Schneider.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc

    r6207 r8271  
    6363 
    6464gr_block_detail_sptr 
    65 gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block, gr_block_detail_sptr old_detail
     65gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block
    6666{ 
    6767  int ninputs = calc_used_ports(block, true).size(); 
     
    7272    std::cout << "Creating block detail for " << block << std::endl; 
    7373 
    74   // Re-use or allocate output buffers 
    7574  for (int i = 0; i < noutputs; i++) { 
    76     gr_buffer_sptr buffer; 
    77  
    78     if (!old_detail || i >= old_detail->noutputs()) { 
    79       if (GR_FLAT_FLOWGRAPH_DEBUG) 
    80         std::cout << "Allocating new buffer for output " << i << std::endl; 
    81       buffer = allocate_buffer(block, i); 
    82     } 
    83     else { 
    84       if (GR_FLAT_FLOWGRAPH_DEBUG) 
    85         std::cout << "Reusing old buffer for output " << i << std::endl; 
    86       buffer = old_detail->output(i); 
    87     } 
    88  
     75    gr_buffer_sptr buffer = allocate_buffer(block, i); 
     76    if (GR_FLAT_FLOWGRAPH_DEBUG) 
     77      std::cout << "Allocated buffer for output " << block << ":" << i << std::endl; 
    8978    detail->set_output(i, buffer); 
    9079  } 
     
    157146gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) 
    158147{ 
    159   std::map<gr_block_sptr, gr_block_detail_sptr> old_details; 
    160  
    161   // Allocate or reuse output buffers 
     148  // Allocate block details if needed.  Only new blocks that aren't pruned out 
     149  // by flattening will need one; existing blocks still in the new flowgraph will 
     150  // already have one. 
    162151  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { 
    163152    gr_block_sptr block = make_gr_block_sptr(*p); 
    164  
    165     gr_block_detail_sptr old_detail = block->detail(); 
    166     block->set_detail(allocate_block_detail(block, old_detail)); 
    167  
    168     // Save old detail for use in next step 
    169     old_details[block] = old_detail; 
    170   } 
    171  
     153     
     154    if (!block->detail()) { 
     155      if (GR_FLAT_FLOWGRAPH_DEBUG) 
     156        std::cout << "merge: allocating new detail for block " << (*p) << std::endl; 
     157        block->set_detail(allocate_block_detail(block)); 
     158    } 
     159    else 
     160      if (GR_FLAT_FLOWGRAPH_DEBUG) 
     161        std::cout << "merge: reusing original detail for block " << (*p) << std::endl; 
     162  } 
     163 
     164  // Calculate the old edges that will be going away, and clear the buffer readers 
     165  // on the RHS. 
     166  for (gr_edge_viter_t old_edge = old_ffg->d_edges.begin(); old_edge != old_ffg->d_edges.end(); old_edge++) { 
     167    if (GR_FLAT_FLOWGRAPH_DEBUG) 
     168      std::cout << "merge: testing old edge " << (*old_edge) << "..."; 
     169       
     170    gr_edge_viter_t new_edge; 
     171    for (new_edge = d_edges.begin(); new_edge != d_edges.end(); new_edge++) 
     172      if (new_edge->src() == old_edge->src() && 
     173          new_edge->dst() == old_edge->dst()) 
     174        break; 
     175 
     176    if (new_edge == d_edges.end()) { // not found in new edge list 
     177      if (GR_FLAT_FLOWGRAPH_DEBUG) 
     178        std::cout << "not in new edge list" << std::endl; 
     179      // zero the buffer reader on RHS of old edge 
     180      gr_block_sptr block(make_gr_block_sptr(old_edge->dst().block())); 
     181      int port = old_edge->dst().port(); 
     182      block->detail()->set_input(port, gr_buffer_reader_sptr()); 
     183    } 
     184    else { 
     185      if (GR_FLAT_FLOWGRAPH_DEBUG) 
     186        std::cout << "found in new edge list" << std::endl; 
     187    } 
     188  }   
     189 
     190  // Now connect inputs to outputs, reusing old buffer readers if they exist 
    172191  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { 
    173192    gr_block_sptr block = make_gr_block_sptr(*p); 
    174193 
    175194    if (GR_FLAT_FLOWGRAPH_DEBUG) 
    176       std::cout << "merge: testing " << (*p) << "..."; 
     195      std::cout << "merge: merging " << (*p) << "..."; 
    177196     
    178197    if (old_ffg->has_block_p(*p)) { 
     
    181200        std::cout << "used in old flow graph" << std::endl; 
    182201      gr_block_detail_sptr detail = block->detail(); 
    183  
     202         
    184203      // Iterate through the inputs and see what needs to be done 
    185       for (int i = 0; i < detail->ninputs(); i++) { 
     204      int ninputs = calc_used_ports(block, true).size(); // Might be different now 
     205      for (int i = 0; i < ninputs; i++) { 
    186206        if (GR_FLAT_FLOWGRAPH_DEBUG) 
    187           std::cout << "Checking input " << i << "..."; 
     207          std::cout << "Checking input " << block << ":" << i << "..."; 
    188208        gr_edge edge = calc_upstream_edge(*p, i); 
    189209 
     
    193213        gr_buffer_sptr src_buffer = src_detail->output(edge.src().port()); 
    194214        gr_buffer_reader_sptr old_reader; 
    195         gr_block_detail_sptr old_detail = old_details[block]; 
    196         if (old_detail && i < old_detail->ninputs()) 
    197           old_reader = old_detail->input(i); 
     215        if (i < detail->ninputs()) // Don't exceed what the original detail has  
     216          old_reader = detail->input(i); 
    198217         
    199218        // If there's a match, use it 
    200219        if (old_reader && (src_buffer == old_reader->buffer())) { 
    201220          if (GR_FLAT_FLOWGRAPH_DEBUG) 
    202             std::cout << "matched" << std::endl; 
    203           detail->set_input(i, old_reader); 
    204  
     221            std::cout << "matched, reusing" << std::endl; 
    205222        } 
    206223        else { 
     
    219236      connect_block_inputs(block); 
    220237    } 
     238 
     239    // Now deal with the fact that the block details might have changed numbers of  
     240    // inputs and outputs vs. in the old flowgraph. 
    221241  }   
    222242} 
    223243 
     244void gr_flat_flowgraph::dump() 
     245{ 
     246  for (gr_edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++) 
     247     std::cout << " edge: " << (*e) << std::endl; 
     248 
     249  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { 
     250    std::cout << " block: " << (*p) << std::endl; 
     251    gr_block_detail_sptr detail = make_gr_block_sptr(*p)->detail(); 
     252    std::cout << "  detail @" << detail << ":" << std::endl; 
     253      
     254    int ni = detail->ninputs(); 
     255    int no = detail->noutputs(); 
     256    for (int i = 0; i < no; i++) { 
     257      gr_buffer_sptr buffer = detail->output(i); 
     258      std::cout << "   output " << i << ": " << buffer  
     259                << " space=" << buffer->space_available() << std::endl; 
     260    } 
     261 
     262    for (int i = 0; i < ni; i++) { 
     263      gr_buffer_reader_sptr reader = detail->input(i); 
     264      std::cout << "   reader " <<  i << ": " << reader 
     265                << " reading from buffer=" << reader->buffer() 
     266                << " avail=" << reader->items_available() << " items" 
     267                << std::endl; 
     268    } 
     269  } 
     270 
     271} 
  • gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h

    r7504 r8271  
    5454  void merge_connections(gr_flat_flowgraph_sptr sfg); 
    5555 
     56  void dump(); 
     57 
    5658private: 
    5759  gr_flat_flowgraph(); 
    5860 
    5961  static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE; 
    60   gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block,  
    61                                              gr_block_detail_sptr old_detail=gr_block_detail_sptr()); 
     62  gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block); 
    6263  gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port); 
    6364  void connect_block_inputs(gr_basic_block_sptr block); 
  • gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc

    r8050 r8271  
    216216  gr_flat_flowgraph_sptr new_ffg = d_owner->flatten();         
    217217  new_ffg->validate();                 // check consistency, sanity, etc 
     218 
     219  if (GR_TOP_BLOCK_IMPL_DEBUG) { 
     220      std::cout << std::endl << "*** Existing flat flowgraph @" << d_ffg << ":" << std::endl; 
     221      d_ffg->dump(); 
     222  } 
    218223  new_ffg->merge_connections(d_ffg);   // reuse buffers, etc 
    219224 
    220   if (GR_TOP_BLOCK_IMPL_DEBUG) 
    221     std::cout << "restart: replacing old flow graph with new" << std::endl; 
     225  if (GR_TOP_BLOCK_IMPL_DEBUG) { 
     226    std::cout << std::endl << "*** New flat flowgraph after merge @" << new_ffg << ":" << std::endl; 
     227    new_ffg->dump(); 
     228  } 
     229   
    222230  d_ffg = new_ffg; 
    223231