[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r3806 - in gnuradio/branches/developers/jcorgan/cppwra
From: |
jcorgan |
Subject: |
[Commit-gnuradio] r3806 - in gnuradio/branches/developers/jcorgan/cppwrap: gnuradio-core/src/lib/runtime gnuradio-examples/c++ |
Date: |
Tue, 17 Oct 2006 12:45:01 -0600 (MDT) |
Author: jcorgan
Date: 2006-10-17 12:45:01 -0600 (Tue, 17 Oct 2006)
New Revision: 3806
Added:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.h
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.h
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.h
Removed:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.h
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.h
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.cc
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.h
Modified:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/Makefile.am
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/Makefile.am
Log:
Moved C++ wrapper code into runtime.
Modified:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/Makefile.am
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/Makefile.am
2006-10-17 18:25:13 UTC (rev 3805)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/Makefile.am
2006-10-17 18:45:01 UTC (rev 3806)
@@ -50,7 +50,10 @@
gr_vmcircbuf_mmap_tmpfile.cc \
gr_vmcircbuf_createfilemapping.cc \
gr_vmcircbuf_sysv_shm.cc \
- gr_select_handler.cc
+ gr_select_handler.cc \
+ gr_basic_flowgraph.cc \
+ gr_flow_graph.cc \
+ gr_scheduler.cc
libruntime_qa_la_SOURCES = \
qa_gr_block.cc \
@@ -80,7 +83,10 @@
gr_timer.h \
gr_tmp_path.h \
gr_types.h \
- gr_vmcircbuf.h
+ gr_vmcircbuf.h \
+ gr_basic_flowgraph.h \
+ gr_flow_graph.h \
+ gr_scheduler.h
noinst_HEADERS = \
gr_vmcircbuf_mmap_shm_open.h \
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.cc
(from rev 3805,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.cc)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.cc
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.cc
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,431 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_basic_flowgraph.h>
+#include <gr_block_detail.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+
+#include <algorithm>
+
+#if GR_FLOWGRAPH_DEBUG
+#include <iostream>
+#endif
+
+using namespace std;
+
+/********** BEGIN PUBLIC METHODS **********/
+
+// Create an instance of a shared pointer to a gr_basic_flowgraph
+// allocated on the heap. No further memory management is needed.
+gr_basic_flowgraph_sptr gr_make_basic_flowgraph()
+{
+ return gr_basic_flowgraph_sptr(new gr_basic_flowgraph());
+}
+
+// Destructor, nothing to do.
+gr_basic_flowgraph::~gr_basic_flowgraph()
+{
+ // NOP
+}
+
+// Establishes a connection between supplied blocks and ports
+void gr_basic_flowgraph::connect(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port)
+{
+ // TODO: check shared pointer validity
+ connect_prim(gr_endpoint_t(src_block, src_port),
+ gr_endpoint_t(dst_block, dst_port));
+}
+
+// Removes an individual connection between supplied blocks and ports
+void gr_basic_flowgraph::disconnect(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port)
+{
+ disconnect_prim(gr_endpoint_t(src_block, src_port),
+ gr_endpoint_t(dst_block, dst_port));
+}
+
+// Removes all connections between blocks in graph
+void gr_basic_flowgraph::disconnect_all()
+{
+ d_edges.clear();
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Disconnected all blocks." << endl;
+#endif
+}
+
+// Returns list of lists of blocks comprising unique islands
+// of connectivity in flow graph.
+gr_block_vector_vector_t gr_basic_flowgraph::calc_partitions()
+{
+ gr_block_vector_vector_t result;
+ gr_block_vector_t nodes = d_blocks; // Working copy
+ gr_block_vector_t graph;
+
+ while (nodes.size() > 0) {
+ graph = calc_reachable_blocks(nodes[0], nodes);
+
+ // Partition should be at least one block
+ assert(graph.size());
+
+ result.push_back(topological_sort(graph));
+
+ // Remove all nodes in graph from node list
+ gr_block_vector_iterator_t block_iter;
+ for(block_iter = graph.begin(); block_iter != graph.end(); block_iter++)
+ nodes.erase(find(nodes.begin(), nodes.end(), *block_iter));
+ }
+
+ return result;
+}
+
+/********** BEGIN PRIVATE METHODS **********/
+
+#if GR_FLOWGRAPH_DEBUG
+static ostream &operator << (ostream &os, const gr_block_sptr block)
+{
+ os << block->name() << "(" << block->unique_id() << ")";
+ return os;
+}
+#endif
+
+// Constructor, nothing to do.
+gr_basic_flowgraph::gr_basic_flowgraph()
+{
+ // NOP
+}
+
+// Establishes a connection between supplied blocks and ports, exceptions
+// passed upwards on error conditions. All overloaded versions of 'connect'
+// should resolve to calls here.
+void gr_basic_flowgraph::connect_prim(gr_endpoint_t src, gr_endpoint_t dst)
+{
+ // Correctness checks. Port numbers must be in range, the destination must
+ // not be already used, and they must have the same stream data type.
+ check_valid_port(src.first->output_signature(), src.second);
+ check_valid_port(dst.first->input_signature(), dst.second);
+ check_dst_not_used(dst);
+ check_type_match(src, dst);
+
+ // Create edge instance and add to edge list
+ d_edges.push_back(gr_edge_t(src, dst));
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Connected " << src.first << ":" << src.second << " to "
+ << dst.second << ":" << dst.first << endl;
+#endif
+}
+
+// Removes an edge from the list of edges. All overloaded version sof
'disconnect'
+// shoudl resolve to calls here.
+void gr_basic_flowgraph::disconnect_prim(gr_endpoint_t src, gr_endpoint_t dst)
+{
+ gr_edge_vector_iterator_t edge_iter;
+ edge_iter = find(d_edges.begin(), d_edges.end(), gr_edge_t(src, dst));
+ if (edge_iter != d_edges.end())
+ d_edges.erase(edge_iter);
+ else
+ throw invalid_argument("gr_basic_flowgraph::disconnect_prim: not
connected");
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Disconnected " << src.first << ":" << src.second << " from "
+ << dst.second << ":" << dst.first << endl;
+#endif
+}
+
+// Ports must not be negative and must be less than max streams for block
+void gr_basic_flowgraph::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ if (port < 0)
+ throw out_of_range("gr_basic_flowgraph::check_valid_port: negative port
number");
+
+ if (sig->max_streams() >= 0 && port >= sig->max_streams())
+ throw out_of_range("gr_basic_flowgraph::check_valid_port: port exceeds
max_streams");
+}
+
+// Destination ports must not already be in use
+void gr_basic_flowgraph::check_dst_not_used(gr_endpoint_t dst)
+{
+ gr_edge_vector_iterator_t edge_iter;
+ for(edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++) {
+ gr_endpoint_t endp = edge_iter->second;
+ if (endp == dst)
+ throw invalid_argument("gr_basic_flowgraph::check_dst_not_used: dst
already used");
+ }
+}
+
+// Connected ports must have the same data size
+void gr_basic_flowgraph::check_type_match(gr_endpoint_t src, gr_endpoint_t dst)
+{
+ gr_io_signature_sptr src_sig = src.first->output_signature();
+ gr_io_signature_sptr dst_sig = dst.first->input_signature();
+ int src_size = src_sig->sizeof_stream_item(src.second);
+ int dst_size = dst_sig->sizeof_stream_item(dst.second);
+
+ if (src_size != dst_size)
+ throw invalid_argument("gr_basic_flowgraph::check_type_match");
+}
+
+// Scans edge list and assembles list of unique blocks used
+void gr_basic_flowgraph::create_block_list()
+{
+ gr_block_vector_iterator_t block_iter;
+ gr_edge_vector_iterator_t edge_iter;
+
+ // TODO: use sort() and unique() instead
+ for(edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++) {
+ gr_block_sptr src_block = edge_iter->first.first;
+ gr_block_sptr dst_block = edge_iter->second.first;
+
+ block_iter = find(d_blocks.begin(), d_blocks.end(), src_block);
+ if (block_iter == d_blocks.end())
+ d_blocks.push_back(src_block);
+
+ block_iter = find(d_blocks.begin(), d_blocks.end(), dst_block);
+ if (block_iter == d_blocks.end())
+ d_blocks.push_back(dst_block);
+ }
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Flow graph has " << d_blocks.size() << " unique blocks." << endl;
+#endif
+}
+
+// Based on connectivity, create block details, buffers, and assign to block
outputs
+// and downstream inputs.
+void gr_basic_flowgraph::connect_blocks()
+{
+ gr_block_vector_iterator_t block_iter;
+ for(block_iter = d_blocks.begin(); block_iter != d_blocks.end();
block_iter++) {
+ vector<int> used_inputs = calc_used_ports(*block_iter, false);
+ vector<int> used_outputs = calc_used_ports(*block_iter, true);
+
+ // Blocks must have inputs sequentially assigned with no gaps
+ check_contiguity(*block_iter, (*block_iter)->input_signature(),
used_inputs);
+ check_contiguity(*block_iter, (*block_iter)->output_signature(),
used_outputs);
+
+ int ninputs = used_inputs.size();
+ int noutputs = used_outputs.size();
+
+ // Ask blocks if their input/ouput connectivity makes sense
+ if (!(*block_iter)->check_topology(ninputs, noutputs))
+ throw invalid_argument("gr_basic_flowgraph::connect_blocks:
topology check failed");
+
+ // Allocate block detail and output buffer and assign
+ 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_iter, i));
+ (*block_iter)->set_detail(detail);
+ }
+
+ // Connect inputs to outputs for each block
+ for(block_iter = d_blocks.begin(); block_iter != d_blocks.end();
block_iter++) {
+ // Get its detail and edges that feed into it
+ gr_block_detail_sptr detail = (*block_iter)->detail();
+ gr_edge_vector_t in_edges = calc_input_edges(*block_iter);
+
+ // For each edge that feeds into it
+ gr_edge_vector_iterator_t edge_iter;
+ for(edge_iter = in_edges.begin(); edge_iter != in_edges.end();
edge_iter++) {
+ // Set the input buffer on the destination port to the output
+ // buffer on the source port
+ int dst_port = edge_iter->second.second;
+ int src_port = edge_iter->first.second;
+ gr_block_sptr src_block = edge_iter->first.first;
+ gr_buffer_sptr src_buffer = src_block->detail()->output(src_port);
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Setting input buffer on " << dst_port << ":"
+ << edge_iter->second.first << endl;
+#endif
+ detail->set_input(dst_port, gr_buffer_add_reader(src_buffer,
(*block_iter)->history()-1));
+ }
+ }
+}
+
+// Allocate and return shared pointer to gr_buffer appropriate to given block
and port
+gr_buffer_sptr gr_basic_flowgraph::allocate_buffer(gr_block_sptr block, int
port)
+{
+ // Start by allocating at least number of items in fixed block size
+ 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*block->output_multiple()) // Note: this means
output_multiple()
+ nitems = 2*block->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_block_vector_t blocks = calc_downstream_blocks(gr_endpoint_t(block,
port));
+ gr_block_vector_iterator_t block_iter;
+ for(block_iter = blocks.begin(); block_iter != blocks.end(); block_iter++)
{
+ int decimation = (int)(1.0/(*block_iter)->relative_rate());
+ int multiple = (*block_iter)->output_multiple();
+ int history = (*block_iter)->history();
+ nitems = max(nitems, 2*(decimation*multiple+history));
+ }
+#if GR_FLOWGRAPH_DEBUG
+ cout << "Block " << block << " has output buffer of " << nitems
+ << " items, each of size " << item_size << endl;
+#endif
+ return gr_make_buffer(nitems, item_size);
+}
+
+// Return list of blocks sorted in topological order
+gr_block_vector_t gr_basic_flowgraph::topological_sort(gr_block_vector_t
blocks)
+{
+ gr_block_vector_t result;
+
+ // Not yet implemented, just return identity
+ result = blocks;
+
+ return result;
+}
+
+// Return a list of ports already used in block.
+// direction == false, check inputs
+// direction == true, check outputs
+vector<int> gr_basic_flowgraph::calc_used_ports(gr_block_sptr block, bool
direction)
+{
+ gr_edge_vector_iterator_t edge_iter;
+ vector<int> result;
+ gr_block_sptr cmp_block;
+
+ for(edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++) {
+ if (!direction) { // inputs
+ cmp_block = edge_iter->second.first;
+ if (cmp_block == block)
+ result.push_back(edge_iter->second.second);
+ }
+ else { // outputs
+ cmp_block = edge_iter->first.first;
+ if (cmp_block == block)
+ result.push_back(edge_iter->first.second);
+ }
+ }
+
+ // Remove duplicates
+ sort(result.begin(), result.end());
+ unique(result.begin(), result.end());
+ return result;
+}
+
+// Check that block inputs are fully assigned
+void gr_basic_flowgraph::check_contiguity(gr_block_sptr block,
gr_io_signature_sptr sig,
+ vector<int> &used_ports)
+{
+ int min_s = sig->min_streams();
+ int l = used_ports.size();
+
+ if (l == 0) {
+ if (min_s == 0)
+ return;
+ else
+ throw invalid_argument("gr_basic_flowgraph::check_contiguity: too
many inputs");
+ }
+
+ if (used_ports[l-1]+1 < min_s)
+ throw invalid_argument("gr_basic_flowgraph::check_contiguity:
insufficient inputs");
+
+ if (used_ports[l-1]+1 != l) {
+ for (int i = 0; i < l; i++)
+ if (used_ports[i] != i)
+ throw invalid_argument("gr_basic_flowgraph::check_contiguity:
missing input");
+ }
+}
+
+// Return list of blocks downstream of a given endpoint
+gr_block_vector_t gr_basic_flowgraph::calc_downstream_blocks(gr_endpoint_t src)
+{
+ gr_block_vector_t result;
+ gr_edge_vector_iterator_t edge_iter;
+
+ for(edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++)
+ if (edge_iter->first == src)
+ result.push_back(edge_iter->second.first);
+
+ // Remove duplicates
+ sort(result.begin(), result.end());
+ unique(result.begin(), result.end());
+ return result;
+}
+
+// Return list of edges that flow into a given block
+gr_edge_vector_t gr_basic_flowgraph::calc_input_edges(gr_block_sptr block)
+{
+ gr_edge_vector_t result;
+ gr_edge_vector_iterator_t edge_iter;
+ for(edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++)
+ if (edge_iter->second.first == block)
+ result.push_back(*edge_iter);
+
+ return result;
+}
+
+// Return a list of blocks reachable from a given block via any port
+gr_block_vector_t gr_basic_flowgraph::calc_reachable_blocks(gr_block_sptr
block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // Mark all blocks as unvisited
+ gr_block_vector_iterator_t block_iter;
+ for(block_iter = blocks.begin(); block_iter != blocks.end(); block_iter++)
+ (*block_iter)->detail()->set_color(gr_block_detail::WHITE);
+
+ // Recursively mark all reachable vertices from 'block'
+ reachable_dfs_visit(block, blocks);
+
+ // Collect all the blocks that have been visited
+ for (block_iter = blocks.begin(); block_iter != blocks.end(); block_iter++)
+ if ((*block_iter)->detail()->color() == gr_block_detail::BLACK)
+ result.push_back(*block_iter);
+
+ return result;
+}
+
+// Recursively mark all reachable blocks from given block and block list
+void gr_basic_flowgraph::reachable_dfs_visit(gr_block_sptr block,
gr_block_vector_t &blocks)
+{
+ // Mark the current one as visited
+ block->detail()->set_color(gr_block_detail::BLACK);
+
+ // Recurse into adjacent vertices
+ gr_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+ gr_block_vector_iterator_t block_iter;
+ for (block_iter = adjacent.begin(); block_iter != adjacent.end();
block_iter++)
+ if ((*block_iter)->detail()->color() == gr_block_detail::WHITE)
+ reachable_dfs_visit(*block_iter, blocks);
+}
+
+// Return a list of block adjacent to a given block along any edge
+gr_block_vector_t gr_basic_flowgraph::calc_adjacent_blocks(gr_block_sptr
block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // Find any blocks that are inputs or outputs
+ gr_edge_vector_iterator_t edge_iter;
+ for (edge_iter = d_edges.begin(); edge_iter != d_edges.end(); edge_iter++)
{
+ if (edge_iter->first.first == block)
+ result.push_back(edge_iter->second.first);
+ if (edge_iter->second.first == block)
+ result.push_back(edge_iter->first.first);
+ }
+
+ return result;
+}
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.h
(from rev 3803,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.h)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.h
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_basic_flowgraph.h
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_BASIC_FLOWGRAPH_H
+#define INCLUDED_GR_BASIC_FLOWGRAPH_H
+
+// NOTE: This is not the underlying code for Python object gr.basic_flowgraph;
that
+// is written in pure Python.
+//
+// Rather, this code is a native C++ implementation of the same functionality
+// and is not exported via SWIG. This is only used when writing pure C++
programs.
+
+// Define to 0 to eliminate flowgraph debugging
+#define GR_FLOWGRAPH_DEBUG 1
+
+#include <gr_block.h>
+#include <boost/enable_shared_from_this.hpp>
+
+class gr_basic_flowgraph;
+typedef boost::shared_ptr<gr_basic_flowgraph> gr_basic_flowgraph_sptr;
+gr_basic_flowgraph_sptr gr_make_basic_flowgraph();
+
+// Oh, for the love of Python, of which the STL is but the faintest
approximation,
+// that those poor souls who toil in C++ land might know some glimmer of the
+// beauty and majesty of lists and list comprehensions. At least one may take
some
+// small solace that one is not mired in the dreaded environs of pure C,
though such
+// consolation is no recompense for the agony of templates, pairs, and
iterators!
+
+// Container for list of gr_blocks, and list of lists
+typedef std::vector<gr_block_sptr> gr_block_vector_t;
+typedef std::vector<gr_block_sptr>::iterator gr_block_vector_iterator_t;
+typedef std::vector<gr_block_vector_t> gr_block_vector_vector_t;
+typedef std::vector<gr_block_vector_t>::iterator
gr_block_vector_vector_iterator_t; // :-)
+
+// Flow graph endpoints, edges
+typedef std::pair<gr_block_sptr, int> gr_endpoint_t;
+typedef std::pair<gr_endpoint_t, gr_endpoint_t> gr_edge_t;
+typedef std::vector<gr_edge_t> gr_edge_vector_t;
+typedef std::vector<gr_edge_t>::iterator gr_edge_vector_iterator_t;
+
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+// Implements container primitives
+class gr_basic_flowgraph : public
boost::enable_shared_from_this<gr_basic_flowgraph>
+{
+protected:
+ // Private constructor ensures use of shared pointers
+ gr_basic_flowgraph();
+ friend gr_basic_flowgraph_sptr gr_make_basic_flowgraph();
+
+ // Add or remove graph edges
+ void connect_prim(gr_endpoint_t src, gr_endpoint_t dst);
+ void disconnect_prim(gr_endpoint_t src, gr_endpoint_t dst);
+
+ // Validation methods, throws exceptions on errors
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_dst_not_used(gr_endpoint_t dst);
+ void check_type_match(gr_endpoint_t src, gr_endpoint_t dst);
+ void check_contiguity(gr_block_sptr block, gr_io_signature_sptr sig,
+ std::vector<int> &used_ports);
+
+ // Utility functions
+ void create_block_list();
+ void connect_blocks();
+ gr_buffer_sptr allocate_buffer(gr_block_sptr block, int port);
+ gr_block_vector_t topological_sort(gr_block_vector_t blocks);
+ std::vector<int> calc_used_ports(gr_block_sptr block, bool direction);
+ gr_block_vector_t calc_downstream_blocks(gr_endpoint_t src);
+ gr_edge_vector_t calc_input_edges(gr_block_sptr block);
+ gr_block_vector_t calc_reachable_blocks(gr_block_sptr block,
gr_block_vector_t &blocks);
+ void reachable_dfs_visit(gr_block_sptr block, gr_block_vector_t &blocks);
+ gr_block_vector_t calc_adjacent_blocks(gr_block_sptr block,
gr_block_vector_t &blocks);
+
+ // Private data
+ static const int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+ gr_edge_vector_t d_edges; // Block:port to port:block connections
+ gr_block_vector_t d_blocks; // List of unique blocks in
graph
+
+public:
+ // Destructor
+ ~gr_basic_flowgraph();
+
+ // Add or remove graph edges
+ void connect(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port);
+ void disconnect(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port);
+ void disconnect_all();
+
+ // Returns a list of lists of blocks that represent distinct
+ // islands of connectivity in the graph
+ gr_block_vector_vector_t calc_partitions();
+};
+
+#endif /* INCLUDED_GR_BASIC_FLOWGRAPH */
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.cc
(from rev 3800,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.cc)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.cc
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.cc
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_flow_graph.h>
+#include <gr_scheduler.h>
+#include <stdexcept>
+
+using namespace std;
+
+gr_flow_graph_sptr gr_make_flow_graph()
+{
+ return gr_flow_graph_sptr(new gr_flow_graph());
+}
+
+gr_flow_graph::gr_flow_graph()
+{
+ // NOP
+}
+
+gr_flow_graph::~gr_flow_graph()
+{
+ // NOP
+}
+
+void gr_flow_graph::start()
+{
+ if (d_scheduler)
+ throw runtime_error("Scheduler already running!");
+
+ create_block_list();
+ connect_blocks();
+
+ d_scheduler = gr_make_scheduler(shared_from_this());
+ d_scheduler->start();
+}
+
+void gr_flow_graph::stop()
+{
+ if (!d_scheduler)
+ throw runtime_error("Scheduler not running!");
+
+ d_scheduler->stop();
+ d_scheduler.reset();
+}
+
+void gr_flow_graph::wait()
+{
+ if (!d_scheduler)
+ throw runtime_error("Scheduler not running!");
+ d_scheduler->wait();
+ d_scheduler.reset();
+}
+
+void gr_flow_graph::run()
+{
+ start();
+ wait();
+}
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.h
(from rev 3800,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.h)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.h
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_flow_graph.h
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_FLOW_GRAPH_H
+#define INCLUDED_GR_FLOW_GRAPH_H
+
+// NOTE: This is not the underlying code for Python object gr.flow_graph; that
+// is written in pure Python.
+//
+// Rather, this code is a native C++ implementation of the same functionality
+// and is not exported via SWIG. This is only used when writing pure C++
programs.
+
+#include <gr_basic_flowgraph.h>
+
+class gr_flow_graph;
+typedef boost::shared_ptr<gr_flow_graph> gr_flow_graph_sptr;
+gr_flow_graph_sptr gr_make_flow_graph();
+
+// Dupe to gr_scheduler.h, but we can't include it here
+class gr_scheduler;
+typedef boost::shared_ptr<gr_scheduler> gr_scheduler_sptr;
+
+class gr_flow_graph : public gr_basic_flowgraph
+{
+private:
+ gr_flow_graph();
+ friend gr_flow_graph_sptr gr_make_flow_graph();
+
+ gr_scheduler_sptr d_scheduler;
+
+public:
+ ~gr_flow_graph();
+
+ void start();
+ void stop();
+ void wait();
+ void run();
+};
+
+#endif
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.cc
(from rev 3803,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.cc)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.cc
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.cc
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_scheduler.h>
+#include <gr_flow_graph.h>
+#include <iostream>
+
+using namespace std;
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph)
+{
+ return gr_scheduler_thread_sptr(new gr_scheduler_thread(graph));
+}
+
+gr_scheduler_thread::gr_scheduler_thread(gr_block_vector_t graph) :
+ omni_thread(NULL, PRIORITY_NORMAL),
+ d_sts(gr_make_single_threaded_scheduler(graph))
+{
+ // NOP
+}
+
+gr_scheduler_thread::~gr_scheduler_thread()
+{
+ // NOP
+}
+
+void gr_scheduler_thread::start()
+{
+ start_undetached();
+}
+
+void *gr_scheduler_thread::run_undetached(void *arg)
+{
+#if GR_SCHEDULER_DEBUG
+ cout << "Running thread..." << endl;
+#endif
+ d_sts->run();
+}
+
+void gr_scheduler_thread::stop()
+{
+ d_sts->stop();
+}
+
+gr_scheduler_sptr gr_make_scheduler(gr_basic_flowgraph_sptr fg)
+{
+ return gr_scheduler_sptr(new gr_scheduler(fg));
+}
+
+gr_scheduler::gr_scheduler(gr_basic_flowgraph_sptr fg)
+{
+ gr_block_vector_vector_t graphs = fg->calc_partitions();
+#if GR_SCHEDULER_DEBUG
+ cout << "Flowgraph has " << graphs.size() << " sub-graphs." << endl;
+#endif
+ gr_block_vector_vector_iterator_t graph_iter;
+ for (graph_iter = graphs.begin(); graph_iter != graphs.end(); graph_iter++)
+ d_threads.push_back(gr_make_scheduler_thread(*graph_iter));
+}
+
+gr_scheduler::~gr_scheduler()
+{
+ // NOP
+}
+
+void gr_scheduler::start()
+{
+#if GR_SCHEDULER_DEBUG
+ cout << "There are " << d_threads.size() << " threads to run." << endl;
+#endif
+ gr_scheduler_thread_vector_iterator_t thread_iter;
+ for (thread_iter = d_threads.begin(); thread_iter != d_threads.end();
thread_iter++)
+ (*thread_iter)->start();
+}
+
+void gr_scheduler::stop()
+{
+}
+
+void gr_scheduler::wait()
+{
+ gr_scheduler_thread_vector_iterator_t thread_iter;
+ for (thread_iter = d_threads.begin(); thread_iter != d_threads.end();
thread_iter++) {
+ while(1) {
+#if GR_SCHEDULER_DEBUG
+ cout << "Thread state is " << (*thread_iter)->state() << endl;
+#endif
+ (*thread_iter)->join(NULL);
+ if (!(*thread_iter)->state() == omni_thread::STATE_TERMINATED)
+ break;
+ }
+ }
+}
Copied:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.h
(from rev 3803,
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.h)
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.h
(rev 0)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-core/src/lib/runtime/gr_scheduler.h
2006-10-17 18:45:01 UTC (rev 3806)
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_GR_SCHEDULER_H
+#define INCLUDED_GR_SCHEDULER_H
+
+// NOTE: This is not the underlying code for Python object gr.scheduler; that
+// is written in pure Python.
+//
+// Rather, this code is a native C++ implementation of the same functionality
+// and is not exported via SWIG. This is only used when writing pure C++
programs.
+
+#define GR_SCHEDULER_DEBUG 1
+
+#include <gr_flow_graph.h>
+#include <omnithread.h>
+#include <gr_single_threaded_scheduler.h>
+#include <boost/shared_ptr.hpp>
+
+class gr_scheduler_thread;
+typedef boost::shared_ptr<gr_scheduler_thread> gr_scheduler_thread_sptr;
+typedef std::vector<gr_scheduler_thread_sptr> gr_scheduler_thread_vector_t;
+typedef std::vector<gr_scheduler_thread_sptr>::iterator
gr_scheduler_thread_vector_iterator_t;
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph);
+
+class gr_scheduler_thread : public omni_thread
+{
+private:
+ gr_scheduler_thread(gr_block_vector_t graph);
+ friend gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t
graph);
+
+ gr_single_threaded_scheduler_sptr d_sts;
+
+public:
+ ~gr_scheduler_thread();
+ virtual void *run_undetached(void *arg);
+ void start();
+ void stop();
+};
+
+class gr_scheduler;
+typedef boost::shared_ptr<gr_scheduler> gr_scheduler_sptr;
+gr_scheduler_sptr gr_make_scheduler(gr_basic_flowgraph_sptr fg);
+
+class gr_scheduler
+{
+private:
+ gr_scheduler_thread_vector_t d_threads;
+
+ gr_scheduler(gr_basic_flowgraph_sptr fg);
+ friend gr_scheduler_sptr gr_make_scheduler(gr_basic_flowgraph_sptr fg);
+
+public:
+ ~gr_scheduler();
+
+ void start();
+ void stop();
+ void wait();
+};
+
+#endif /* INCLUDED_GR_SCHEDULER_H */
Modified:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/Makefile.am
===================================================================
---
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/Makefile.am
2006-10-17 18:25:13 UTC (rev 3805)
+++
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/Makefile.am
2006-10-17 18:45:01 UTC (rev 3806)
@@ -23,14 +23,9 @@
INCLUDES=$(STD_DEFINES_AND_INCLUDES)
-noinst_PROGRAMS = \
- dialtone
+noinst_PROGRAMS = dialtone
-dialtone_SOURCES = \
- dialtone.cc \
- gr_basic_flowgraph.cc \
- gr_flow_graph.cc \
- gr_scheduler.cc
+dialtone_SOURCES = dialtone.cc
dialtone_LDADD = $(GNURADIO_CORE_LIBS) \
$(top_builddir)/gr-audio-alsa/src/libgr_audio_alsa.la
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.cc
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_basic_flowgraph.h
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.cc
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_flow_graph.h
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.cc
Deleted:
gnuradio/branches/developers/jcorgan/cppwrap/gnuradio-examples/c++/gr_scheduler.h
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r3806 - in gnuradio/branches/developers/jcorgan/cppwrap: gnuradio-core/src/lib/runtime gnuradio-examples/c++,
jcorgan <=