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_sts.h>
31 #include <gr_scheduler_tpb.h>
39 #define GR_TOP_BLOCK_IMPL_DEBUG 0
42 typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg);
44 static struct scheduler_table {
47 } scheduler_table[] = {
48 { "TPB", gr_scheduler_tpb::make }, // first entry is default
49 { "STS", gr_scheduler_sts::make }
52 static gr_scheduler_sptr
53 make_scheduler(gr_flat_flowgraph_sptr ffg)
55 static scheduler_maker factory = 0;
58 char *v = getenv("GR_SCHEDULER");
60 factory = scheduler_table[0].f; // use default
62 for (size_t i = 0; i < sizeof(scheduler_table)/sizeof(scheduler_table[0]); i++){
63 if (strcmp(v, scheduler_table[i].name) == 0){
64 factory = scheduler_table[i].f;
69 std::cerr << "warning: Invalid GR_SCHEDULER environment variable value \""
70 << v << "\". Using \"" << scheduler_table[0].name << "\"\n";
71 factory = scheduler_table[0].f;
79 gr_top_block_impl::gr_top_block_impl(gr_top_block *owner)
80 : d_owner(owner), d_ffg(),
81 d_state(IDLE), d_lock_count(0)
85 gr_top_block_impl::~gr_top_block_impl()
91 gr_top_block_impl::start()
93 gr_lock_guard l(d_mutex);
96 throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
99 throw std::runtime_error("top_block::start: can't start with flow graph locked");
101 // Create new flat flow graph by flattening hierarchy
102 d_ffg = d_owner->flatten();
104 // Validate new simple flow graph and wire it up
106 d_ffg->setup_connections();
108 d_scheduler = make_scheduler(d_ffg);
113 gr_top_block_impl::stop()
121 gr_top_block_impl::wait()
129 // N.B. lock() and unlock() cannot be called from a flow graph thread or
130 // deadlock will occur when reconfiguration happens
132 gr_top_block_impl::lock()
134 gr_lock_guard lock(d_mutex);
139 gr_top_block_impl::unlock()
141 gr_lock_guard lock(d_mutex);
143 if (d_lock_count <= 0){
144 d_lock_count = 0; // fix it, then complain
145 throw std::runtime_error("unpaired unlock() call");
149 if (d_lock_count > 0 || d_state == IDLE) // nothing to do
156 * restart is called with d_mutex held
159 gr_top_block_impl::restart()
161 stop(); // Stop scheduler and wait for completion
164 // Create new simple flow graph
165 gr_flat_flowgraph_sptr new_ffg = d_owner->flatten();
166 new_ffg->validate(); // check consistency, sanity, etc
167 new_ffg->merge_connections(d_ffg); // reuse buffers, etc
170 // Create a new scheduler to execute it
171 d_scheduler = make_scheduler(d_ffg);
176 gr_top_block_impl::dump()