3 * Copyright 2007,2008 Free Software Foundation, Inc.
5 * This file is part of GNU Radio
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
27 #include <gr_top_block.h>
28 #include <gr_top_block_impl.h>
29 #include <gr_flat_flowgraph.h>
30 #include <gr_scheduler_thread.h>
31 #include <gr_local_sighandler.h>
38 #define GR_TOP_BLOCK_IMPL_DEBUG 0
40 gr_top_block_impl::gr_top_block_impl(gr_top_block *owner)
48 gr_top_block_impl::~gr_top_block_impl()
54 gr_top_block_impl::start()
56 if (GR_TOP_BLOCK_IMPL_DEBUG)
57 std::cout << "start: entered " << this << std::endl;
60 throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
63 throw std::runtime_error("top_block::start: can't call start with flow graph locked");
65 // Create new flat flow graph by flattening hierarchy
66 d_ffg = d_owner->flatten();
68 // Validate new simple flow graph and wire it up
70 d_ffg->setup_connections();
72 // Execute scheduler threads
78 // N.B. lock() and unlock() cannot be called from a flow graph thread or
79 // deadlock will occur when reconfiguration happens
81 gr_top_block_impl::lock()
83 omni_mutex_lock lock(d_reconf);
85 if (GR_TOP_BLOCK_IMPL_DEBUG)
86 std::cout << "runtime: locked, count = " << d_lock_count << std::endl;
90 gr_top_block_impl::unlock()
92 omni_mutex_lock lock(d_reconf);
93 if (d_lock_count <= 0){
94 d_lock_count = 0; // fix it, then complain
95 throw std::runtime_error("unpaired unlock() call");
99 if (GR_TOP_BLOCK_IMPL_DEBUG)
100 std::cout << "unlock: unlocked, count = " << d_lock_count << std::endl;
102 if (d_lock_count == 0) {
103 if (GR_TOP_BLOCK_IMPL_DEBUG)
104 std::cout << "unlock: restarting flowgraph" << std::endl;
110 gr_top_block_impl::restart()
112 if (GR_TOP_BLOCK_IMPL_DEBUG)
113 std::cout << "restart: entered" << std::endl;
116 return; // nothing to do
118 // Stop scheduler threads and wait for completion
121 if (GR_TOP_BLOCK_IMPL_DEBUG)
122 std::cout << "restart: threads stopped" << std::endl;
124 // Create new simple flow graph
125 gr_flat_flowgraph_sptr new_ffg = d_owner->flatten();
126 new_ffg->validate(); // check consistency, sanity, etc
128 if (GR_TOP_BLOCK_IMPL_DEBUG) {
129 std::cout << std::endl << "*** Existing flat flowgraph @" << d_ffg << ":" << std::endl;
132 new_ffg->merge_connections(d_ffg); // reuse buffers, etc
134 if (GR_TOP_BLOCK_IMPL_DEBUG) {
135 std::cout << std::endl << "*** New flat flowgraph after merge @" << new_ffg << ":" << std::endl;
146 gr_top_block_impl::dump()
153 gr_top_block_impl::make_gr_block_vector(gr_basic_block_vector_t blocks)
155 gr_block_vector_t result;
156 for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
157 result.push_back(make_gr_block_sptr(*p));