aboutsummaryrefslogtreecommitdiffstats
path: root/src/Flowgraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Flowgraph.cpp')
-rw-r--r--src/Flowgraph.cpp226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/Flowgraph.cpp b/src/Flowgraph.cpp
new file mode 100644
index 0000000..2212485
--- /dev/null
+++ b/src/Flowgraph.cpp
@@ -0,0 +1,226 @@
+/*
+ Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Her Majesty
+ the Queen in Right of Canada (Communications Research Center Canada)
+ */
+/*
+ This file is part of CRC-DADMOD.
+
+ CRC-DADMOD 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 3 of the
+ License, or (at your option) any later version.
+
+ CRC-DADMOD 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 CRC-DADMOD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Flowgraph.h"
+#include "PcDebug.h"
+
+
+#ifdef __ppc__
+# define memalign(a, b) malloc(b)
+#else // !__ppc__
+# include <mm_malloc.h>
+#endif
+#include <sys/types.h>
+#include <stdexcept>
+#include <assert.h>
+#if defined(_WIN32) and !defined(__MINGW32__)
+//#include <sys/timeb.h>
+//#include <sys/types.h>
+#else
+#include <sys/time.h>
+#endif
+
+
+typedef std::vector<Node*>::iterator NodeIterator;
+typedef std::vector<Edge*>::iterator EdgeIterator;
+
+
+Node::Node(ModPlugin* plugin) :
+ myPlugin(plugin),
+ myProcessTime(0)
+{
+ PDEBUG("Node::Node(plugin(%s): %p) @ %p\n", plugin->name(), plugin, this);
+
+}
+
+
+Node::~Node()
+{
+ PDEBUG("Node::~Node() @ %p\n", this);
+
+ if (myPlugin != NULL) {
+ delete myPlugin;
+ }
+ assert(myInputBuffers.size() == 0);
+ assert(myOutputBuffers.size() == 0);
+}
+
+
+Edge::Edge(Node* srcNode, Node* dstNode) :
+ mySrcNode(srcNode),
+ myDstNode(dstNode)
+{
+ PDEBUG("Edge::Edge(srcNode(%s): %p, dstNode(%s): %p) @ %p\n",
+ srcNode->plugin()->name(), srcNode,
+ dstNode->plugin()->name(), dstNode,
+ this);
+
+ myBuffer = new Buffer();
+ srcNode->myOutputBuffers.push_back(myBuffer);
+ dstNode->myInputBuffers.push_back(myBuffer);
+}
+
+
+Edge::~Edge()
+{
+ PDEBUG("Edge::~Edge() @ %p\n", this);
+
+ std::vector<Buffer*>::iterator buffer;
+ if (myBuffer != NULL) {
+ for (buffer = mySrcNode->myOutputBuffers.begin();
+ buffer != mySrcNode->myOutputBuffers.end();
+ ++buffer) {
+ if (*buffer == myBuffer) {
+ mySrcNode->myOutputBuffers.erase(buffer);
+ break;
+ }
+ }
+
+ for (buffer = myDstNode->myInputBuffers.begin();
+ buffer != myDstNode->myInputBuffers.end();
+ ++buffer) {
+ if (*buffer == myBuffer) {
+ myDstNode->myInputBuffers.erase(buffer);
+ break;
+ }
+ }
+ delete myBuffer;
+ }
+}
+
+
+int Node::process()
+{
+ PDEBUG("Edge::process()\n");
+ PDEBUG(" Plugin name: %s (%p)\n", myPlugin->name(), myPlugin);
+
+ return myPlugin->process(myInputBuffers, myOutputBuffers);
+}
+
+
+Flowgraph::Flowgraph() :
+ myProcessTime(0)
+{
+ PDEBUG("Flowgraph::Flowgraph() @ %p\n", this);
+
+}
+
+
+Flowgraph::~Flowgraph()
+{
+ PDEBUG("Flowgraph::~Flowgraph() @ %p\n", this);
+
+ std::vector<Edge*>::const_iterator edge;
+ for (edge = edges.begin(); edge != edges.end(); ++edge) {
+ delete *edge;
+ }
+
+ if (myProcessTime) {
+ fprintf(stderr, "Process time:\n");
+ }
+ std::vector<Node*>::const_iterator node;
+ for (node = nodes.begin(); node != nodes.end(); ++node) {
+ if (myProcessTime) {
+ fprintf(stderr, " %30s: %10u us (%2.2f %%)\n",
+ (*node)->plugin()->name(),
+ (unsigned)(*node)->processTime(),
+ (*node)->processTime() * 100.0 / myProcessTime);
+ }
+ delete *node;
+ }
+ if (myProcessTime) {
+ fprintf(stderr, " %30s: %10u us (100.00 %%)\n", "total",
+ (unsigned)myProcessTime);
+ }
+}
+
+
+void Flowgraph::connect(ModPlugin* input, ModPlugin* output)
+{
+ PDEBUG("Flowgraph::connect(input(%s): %p, output(%s): %p)\n",
+ input->name(), input, output->name(), output);
+
+ NodeIterator inputNode;
+ NodeIterator outputNode;
+
+ for (inputNode = nodes.begin(); inputNode != nodes.end(); ++inputNode) {
+ if ((*inputNode)->plugin() == input) {
+ break;
+ }
+ }
+ if (inputNode == nodes.end()) {
+ inputNode = nodes.insert(nodes.end(), new Node(input));
+ }
+
+ for (outputNode = nodes.begin(); outputNode != nodes.end(); ++outputNode) {
+ if ((*outputNode)->plugin() == output) {
+ break;
+ }
+ }
+ if (outputNode == nodes.end()) {
+ outputNode = nodes.insert(nodes.end(), new Node(output));
+ for (inputNode = nodes.begin(); inputNode != nodes.end(); ++inputNode) {
+ if ((*inputNode)->plugin() == input) {
+ break;
+ }
+ }
+ } else if (inputNode > outputNode) {
+ Node* node = *outputNode;
+ nodes.erase(outputNode);
+ outputNode = nodes.insert(nodes.end(), node);
+ for (inputNode = nodes.begin(); inputNode != nodes.end(); ++inputNode) {
+ if ((*inputNode)->plugin() == input) {
+ break;
+ }
+ }
+ }
+
+ assert((*inputNode)->plugin() == input);
+ assert((*outputNode)->plugin() == output);
+
+ edges.push_back(new Edge(*inputNode, *outputNode));
+}
+
+
+bool Flowgraph::run()
+{
+ PDEBUG("Flowgraph::run()\n");
+
+ std::vector<Node*>::const_iterator node;
+ timeval start, stop;
+ time_t diff;
+
+ gettimeofday(&start, NULL);
+ for (node = nodes.begin(); node != nodes.end(); ++node) {
+ int ret = (*node)->process();
+ PDEBUG(" ret: %i\n", ret);
+ gettimeofday(&stop, NULL);
+ diff = (stop.tv_sec - start.tv_sec) * 1000000 +
+ stop.tv_usec - start.tv_usec;
+ myProcessTime += diff;
+ (*node)->addProcessTime(diff);
+ start = stop;
+ if (!ret) {
+ return false;
+ }
+ }
+ return true;
+}