summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block.cc3
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl.cc114
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl.h38
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc130
-rw-r--r--gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h55
6 files changed, 225 insertions, 117 deletions
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
index d84128cbd..0463581c7 100644
--- a/gnuradio-core/src/lib/runtime/Makefile.am
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -55,6 +55,7 @@ libruntime_la_SOURCES = \
gr_sync_interpolator.cc \
gr_top_block.cc \
gr_top_block_impl.cc \
+ gr_top_block_impl_sts.cc \
gr_tmp_path.cc \
gr_vmcircbuf.cc \
gr_vmcircbuf_mmap_shm_open.cc \
@@ -102,6 +103,7 @@ grinclude_HEADERS = \
gr_sync_interpolator.h \
gr_top_block.h \
gr_top_block_impl.h \
+ gr_top_block_impl_sts.h \
gr_timer.h \
gr_tmp_path.h \
gr_types.h \
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc
index 5cb0ccdea..473ea5883 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <gr_top_block.h>
#include <gr_top_block_impl.h>
+#include <gr_top_block_impl_sts.h>
#include <gr_io_signature.h>
#include <iostream>
@@ -42,7 +43,7 @@ gr_top_block::gr_top_block(const std::string &name)
gr_make_io_signature(0,0,0))
{
- d_impl = new gr_top_block_impl(this);
+ d_impl = new gr_top_block_impl_sts(this);
}
gr_top_block::~gr_top_block()
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
index 359665a77..857e9fa2d 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -37,55 +37,16 @@
#define GR_TOP_BLOCK_IMPL_DEBUG 0
-static gr_top_block_impl *s_impl = 0;
-
-/*!
- * Make a vector of gr_block from a vector of gr_basic_block
- *
- * Pass-by-value to avoid problem with possible asynchronous modification
- */
-static gr_block_vector_t
-make_gr_block_vector(gr_basic_block_vector_t blocks)
-{
- gr_block_vector_t result;
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- result.push_back(make_gr_block_sptr(*p));
- }
-
- return result;
-}
-
-// FIXME: This prevents using more than one gr_top_block instance
-
-static void
-runtime_sigint_handler(int signum)
-{
- if (GR_TOP_BLOCK_IMPL_DEBUG){
- char *msg = "SIGINT received, calling stop()\n";
- ::write(1, msg, strlen(msg)); // write is OK to call from signal handler
- }
-
- if (s_impl)
- s_impl->stop();
-}
-
-// ----------------------------------------------------------------
-
gr_top_block_impl::gr_top_block_impl(gr_top_block *owner)
- : d_running(false),
+ : d_owner(owner),
+ d_running(false),
d_ffg(),
- d_owner(owner),
d_lock_count(0)
{
- if (s_impl)
- throw std::logic_error("gr_top_block_impl: multiple simultaneous gr_top_blocks not allowed");
-
- s_impl = this;
}
gr_top_block_impl::~gr_top_block_impl()
{
- s_impl = 0; // don't call delete we don't own these
d_owner = 0;
}
@@ -109,64 +70,6 @@ gr_top_block_impl::start()
start_threads();
}
-void
-gr_top_block_impl::start_threads()
-{
- if (GR_TOP_BLOCK_IMPL_DEBUG)
- std::cout << "start_threads: entered" << std::endl;
-
- d_graphs = d_ffg->partition();
- for (std::vector<gr_basic_block_vector_t>::iterator p = d_graphs.begin();
- p != d_graphs.end(); p++) {
- gr_scheduler_thread *thread = new gr_scheduler_thread(make_gr_block_vector(*p));
- d_threads.push_back(thread);
- if (GR_TOP_BLOCK_IMPL_DEBUG)
- std::cout << "start_threads: starting " << thread << std::endl;
- thread->start();
- }
-
- d_running = true;
-}
-
-/*
- * N.B. as currently implemented, it is possible that this may be
- * invoked by the SIGINT handler which is fragile as hell...
- */
-void
-gr_top_block_impl::stop()
-{
- if (GR_TOP_BLOCK_IMPL_DEBUG){
- char *msg = "stop: entered\n";
- ::write(1, msg, strlen(msg));
- }
-
- for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) {
- if (*p)
- (*p)->stop();
- }
-}
-
-void
-gr_top_block_impl::wait()
-{
- if (GR_TOP_BLOCK_IMPL_DEBUG)
- std::cout << "wait: entered" << std::endl;
-
- void *dummy_status; // don't ever dereference this
- gr_local_sighandler sigint(SIGINT, runtime_sigint_handler);
-
- for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) {
- if (GR_TOP_BLOCK_IMPL_DEBUG)
- std::cout << "wait: joining thread " << (*p) << std::endl;
- (*p)->join(&dummy_status); // pthreads will self-delete, so pointer is now dead
- (*p) = 0; // FIXME: switch to stl::list and actually remove from container
- if (GR_TOP_BLOCK_IMPL_DEBUG)
- std::cout << "wait: join returned" << std::endl;
- }
-
- d_threads.clear();
- d_running = false;
-}
// N.B. lock() and unlock() cannot be called from a flow graph thread or
// deadlock will occur when reconfiguration happens
@@ -238,3 +141,14 @@ gr_top_block_impl::dump()
if (d_ffg)
d_ffg->dump();
}
+
+gr_block_vector_t
+gr_top_block_impl::make_gr_block_vector(gr_basic_block_vector_t blocks)
+{
+ gr_block_vector_t result;
+ for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ result.push_back(make_gr_block_sptr(*p));
+ }
+
+ return result;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h
index abdfa9964..003afec93 100644
--- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2007 Free Software Foundation, Inc.
+ * Copyright 2007,2008 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -26,9 +26,9 @@
#include <gr_scheduler_thread.h>
/*!
- *\brief Implementation details of gr_top_block
- *
+ *\brief Abstract implementation details of gr_top_block
* \ingroup internal
+ *
* The actual implementation of gr_top_block. Separate class allows
* decoupling of changes from dependent classes.
*
@@ -37,22 +37,22 @@ class gr_top_block_impl
{
public:
gr_top_block_impl(gr_top_block *owner);
- ~gr_top_block_impl();
+ virtual ~gr_top_block_impl();
// Create and start scheduler threads
- void start();
+ virtual void start();
// Signal scheduler threads to stop
- void stop();
+ virtual void stop() = 0;
// Wait for scheduler threads to exit
- void wait();
+ virtual void wait() = 0;
// Lock the top block to allow reconfiguration
- void lock();
+ virtual void lock();
// Unlock the top block at end of reconfiguration
- void unlock();
+ virtual void unlock();
// Dump the flowgraph to stdout
void dump();
@@ -60,19 +60,25 @@ public:
// Return true if flowgraph is running
bool is_running() const { return d_running; }
-private:
+protected:
+ gr_top_block *d_owner;
bool d_running;
gr_flat_flowgraph_sptr d_ffg;
- gr_scheduler_thread_vector_t d_threads;
- gr_top_block *d_owner;
+
+ omni_mutex d_reconf; // protects d_lock_count
int d_lock_count;
- omni_mutex d_reconf;
- std::vector<gr_basic_block_vector_t> d_graphs;
+ virtual void start_threads() = 0;
+ virtual void restart();
+
+/*!
+ * Make a vector of gr_block from a vector of gr_basic_block
+ *
+ * Pass-by-value to avoid problem with possible asynchronous modification
+ */
+ static gr_block_vector_t make_gr_block_vector(gr_basic_block_vector_t blocks);
- void start_threads();
- void restart();
};
#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc
new file mode 100644
index 000000000..39289ce5b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2008 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 3, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_top_block.h>
+#include <gr_top_block_impl_sts.h>
+#include <gr_flat_flowgraph.h>
+#include <gr_scheduler_thread.h>
+#include <gr_local_sighandler.h>
+
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+#include <unistd.h>
+
+#define GR_TOP_BLOCK_IMPL_STS_DEBUG 0
+
+static gr_top_block_impl *s_impl = 0;
+
+
+// FIXME: This prevents using more than one gr_top_block instance
+
+static void
+runtime_sigint_handler(int signum)
+{
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG){
+ char *msg = "SIGINT received, calling stop()\n";
+ ::write(1, msg, strlen(msg)); // write is OK to call from signal handler
+ }
+
+ if (s_impl)
+ s_impl->stop();
+}
+
+// ----------------------------------------------------------------
+
+gr_top_block_impl_sts::gr_top_block_impl_sts(gr_top_block *owner)
+ : gr_top_block_impl(owner)
+{
+ if (s_impl)
+ throw std::logic_error("gr_top_block_impl_sts: multiple simultaneous gr_top_blocks not allowed");
+
+ s_impl = this;
+}
+
+gr_top_block_impl_sts::~gr_top_block_impl_sts()
+{
+ s_impl = 0; // don't call delete we don't own these
+}
+
+void
+gr_top_block_impl_sts::start_threads()
+{
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG)
+ std::cout << "start_threads: entered" << std::endl;
+
+ d_graphs = d_ffg->partition();
+ for (std::vector<gr_basic_block_vector_t>::iterator p = d_graphs.begin();
+ p != d_graphs.end(); p++) {
+ gr_scheduler_thread *thread = new gr_scheduler_thread(make_gr_block_vector(*p));
+ d_threads.push_back(thread);
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG)
+ std::cout << "start_threads: starting " << thread << std::endl;
+ thread->start();
+ }
+
+ d_running = true;
+}
+
+/*
+ * N.B. as currently implemented, it is possible that this may be
+ * invoked by the SIGINT handler which is fragile as hell...
+ */
+void
+gr_top_block_impl_sts::stop()
+{
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG){
+ char *msg = "stop: entered\n";
+ ::write(1, msg, strlen(msg));
+ }
+
+ for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) {
+ if (*p)
+ (*p)->stop();
+ }
+}
+
+void
+gr_top_block_impl_sts::wait()
+{
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG)
+ std::cout << "wait: entered" << std::endl;
+
+ void *dummy_status; // don't ever dereference this
+ gr_local_sighandler sigint(SIGINT, runtime_sigint_handler);
+
+ for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) {
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG)
+ std::cout << "wait: joining thread " << (*p) << std::endl;
+ (*p)->join(&dummy_status); // omnithreads will self-delete, so pointer is now dead
+ (*p) = 0; // FIXME: switch to stl::list and actually remove from container
+ if (GR_TOP_BLOCK_IMPL_STS_DEBUG)
+ std::cout << "wait: join returned" << std::endl;
+ }
+
+ d_threads.clear();
+ d_running = false;
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h
new file mode 100644
index 000000000..ec2e51cf2
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h
@@ -0,0 +1,55 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 3, 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_TOP_BLOCK_IMPL_STS_H
+#define INCLUDED_GR_TOP_BLOCK_IMPL_STS_H
+
+#include <gr_top_block_impl.h>
+#include <gr_scheduler_thread.h>
+
+/*!
+ *\brief Implementation details of gr_top_block
+ * \ingroup internal
+ *
+ * Concrete implementation of gr_top_block using gr_single_threaded_scheduler.
+ */
+class gr_top_block_impl_sts : public gr_top_block_impl
+{
+public:
+ gr_top_block_impl_sts(gr_top_block *owner);
+ ~gr_top_block_impl_sts();
+
+ // Signal scheduler threads to stop
+ void stop();
+
+ // Wait for scheduler threads to exit
+ void wait();
+
+private:
+
+ gr_scheduler_thread_vector_t d_threads;
+ std::vector<gr_basic_block_vector_t> d_graphs;
+
+ void start_threads();
+};
+
+#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_STS_H */