diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2016-09-09 11:19:18 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2016-09-09 11:19:18 -0700 |
commit | af4323d1e471476efa255e3df745397f7c8a1b71 (patch) | |
tree | 6f1b8e92d93d42a86fc640672378d2f924087eea | |
parent | 094e3f8b8497e3039b981856f2abfb0fe1ec3795 (diff) | |
parent | a287639e17272cb5763c3c596ecabf7d95f87c54 (diff) |
Merge remote-tracking branch 'github/remove-sts' into next
-rw-r--r-- | gnuradio-runtime/lib/CMakeLists.txt | 2 | ||||
-rw-r--r-- | gnuradio-runtime/lib/scheduler_sts.cc | 90 | ||||
-rw-r--r-- | gnuradio-runtime/lib/scheduler_sts.h | 66 | ||||
-rw-r--r-- | gnuradio-runtime/lib/single_threaded_scheduler.cc | 363 | ||||
-rw-r--r-- | gnuradio-runtime/lib/single_threaded_scheduler.h | 65 | ||||
-rw-r--r-- | gnuradio-runtime/lib/top_block_impl.cc | 4 | ||||
-rw-r--r-- | gnuradio-runtime/swig/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gnuradio-runtime/swig/single_threaded_scheduler.i | 54 |
8 files changed, 1 insertions, 644 deletions
diff --git a/gnuradio-runtime/lib/CMakeLists.txt b/gnuradio-runtime/lib/CMakeLists.txt index e0196b669a..c6e42876ce 100644 --- a/gnuradio-runtime/lib/CMakeLists.txt +++ b/gnuradio-runtime/lib/CMakeLists.txt @@ -106,9 +106,7 @@ list(APPEND gnuradio_runtime_sources realtime.cc realtime_impl.cc scheduler.cc - scheduler_sts.cc scheduler_tpb.cc - single_threaded_scheduler.cc sptr_magic.cc sync_block.cc sync_decimator.cc diff --git a/gnuradio-runtime/lib/scheduler_sts.cc b/gnuradio-runtime/lib/scheduler_sts.cc deleted file mode 100644 index 19d05b2316..0000000000 --- a/gnuradio-runtime/lib/scheduler_sts.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2013 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "scheduler_sts.h" -#include "single_threaded_scheduler.h" -#include <gnuradio/thread/thread_body_wrapper.h> - -namespace gr { - - class sts_container - { - block_vector_t d_blocks; - - public: - sts_container(block_vector_t blocks) - : d_blocks(blocks) {} - - void operator()() - { - make_single_threaded_scheduler(d_blocks)->run(); - } - }; - - scheduler_sptr - scheduler_sts::make(flat_flowgraph_sptr ffg, int max_noutput_items) - { - return scheduler_sptr(new scheduler_sts(ffg, max_noutput_items)); - } - - scheduler_sts::scheduler_sts(flat_flowgraph_sptr ffg, int max_noutput_items) - : scheduler(ffg, max_noutput_items) - { - // Split the flattened flow graph into discrete partitions, each - // of which is topologically sorted. - - std::vector<basic_block_vector_t> graphs = ffg->partition(); - - // For each partition, create a thread to evaluate it using - // an instance of the gr_single_threaded_scheduler - - for(std::vector<basic_block_vector_t>::iterator p = graphs.begin(); - p != graphs.end(); p++) { - - block_vector_t blocks = flat_flowgraph::make_block_vector(*p); - d_threads.create_thread( - gr::thread::thread_body_wrapper<sts_container>(sts_container(blocks), - "single-threaded-scheduler")); - } - } - - scheduler_sts::~scheduler_sts() - { - stop(); - } - - void - scheduler_sts::stop() - { - d_threads.interrupt_all(); - } - - void - scheduler_sts::wait() - { - d_threads.join_all(); - } - -} /* namespace gr */ diff --git a/gnuradio-runtime/lib/scheduler_sts.h b/gnuradio-runtime/lib/scheduler_sts.h deleted file mode 100644 index b4cddb4614..0000000000 --- a/gnuradio-runtime/lib/scheduler_sts.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2013 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 this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef INCLUDED_GR_SCHEDULER_STS_H -#define INCLUDED_GR_SCHEDULER_STS_H - -#include <gnuradio/api.h> -#include <gnuradio/thread/thread_group.h> -#include "scheduler.h" - -namespace gr { - - /*! - * \brief Concrete scheduler that uses the single_threaded_scheduler - */ - class GR_RUNTIME_API scheduler_sts : public scheduler - { - gr::thread::thread_group d_threads; - - protected: - /*! - * \brief Construct a scheduler and begin evaluating the graph. - * - * The scheduler will continue running until all blocks until they - * report that they are done or the stop method is called. - */ - scheduler_sts(flat_flowgraph_sptr ffg, int max_noutput_items); - - public: - static scheduler_sptr make(flat_flowgraph_sptr ffg, - int max_noutput_items); - - ~scheduler_sts(); - - /*! - * \brief Tell the scheduler to stop executing. - */ - void stop(); - - /*! - * \brief Block until the graph is done. - */ - void wait(); - }; - -} /* namespace gr */ - -#endif /* INCLUDED_GR_SCHEDULER_STS_H */ diff --git a/gnuradio-runtime/lib/single_threaded_scheduler.cc b/gnuradio-runtime/lib/single_threaded_scheduler.cc deleted file mode 100644 index c86d26ca3a..0000000000 --- a/gnuradio-runtime/lib/single_threaded_scheduler.cc +++ /dev/null @@ -1,363 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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 "single_threaded_scheduler.h" -#include <gnuradio/block.h> -#include <gnuradio/block_detail.h> -#include <gnuradio/buffer.h> -#include <boost/thread.hpp> -#include <boost/format.hpp> -#include <iostream> -#include <limits> -#include <assert.h> -#include <stdio.h> - -namespace gr { - - // must be defined to either 0 or 1 -#define ENABLE_LOGGING 0 - -#if (ENABLE_LOGGING) -#define LOG(x) do { x; } while(0) -#else -#define LOG(x) do {;} while(0) -#endif - - static int which_scheduler = 0; - - single_threaded_scheduler_sptr - make_single_threaded_scheduler(const std::vector<block_sptr> &blocks) - { - return single_threaded_scheduler_sptr - (new single_threaded_scheduler(blocks)); - } - - single_threaded_scheduler::single_threaded_scheduler(const std::vector<block_sptr> &blocks) - : d_blocks(blocks), d_enabled(true), d_log(0) - { - if(ENABLE_LOGGING) { - std::string name = str(boost::format("sst-%d.log") % which_scheduler++); - d_log = new std::ofstream(name.c_str()); - *d_log << "single_threaded_scheduler: " - << d_blocks.size () - << " blocks\n"; - } - } - - single_threaded_scheduler::~single_threaded_scheduler() - { - if(ENABLE_LOGGING) - delete d_log; - } - - void - single_threaded_scheduler::run() - { - // d_enabled = true; // KLUDGE - main_loop (); - } - - void - single_threaded_scheduler::stop() - { - if(0) - std::cout << "gr_singled_threaded_scheduler::stop() " - << this << std::endl; - d_enabled = false; - } - - inline static unsigned int - round_up(unsigned int n, unsigned int multiple) - { - return ((n + multiple - 1) / multiple) * multiple; - } - - inline static unsigned int - round_down(unsigned int n, unsigned int multiple) - { - return (n / multiple) * multiple; - } - - // - // Return minimum available write space in all our downstream - // buffers or -1 if we're output blocked and the output we're - // blocked on is done. - // - static int - min_available_space(block_detail *d, int output_multiple) - { - int min_space = std::numeric_limits<int>::max(); - - for(int i = 0; i < d->noutputs (); i++) { - int n = round_down (d->output(i)->space_available (), output_multiple); - if(n == 0) { // We're blocked on output. - if(d->output(i)->done()) { // Downstream is done, therefore we're done. - return -1; - } - return 0; - } - min_space = std::min (min_space, n); - } - return min_space; - } - - void - single_threaded_scheduler::main_loop() - { - static const int DEFAULT_CAPACITY = 16; - - int noutput_items; - gr_vector_int ninput_items_required(DEFAULT_CAPACITY); - gr_vector_int ninput_items(DEFAULT_CAPACITY); - gr_vector_const_void_star input_items(DEFAULT_CAPACITY); - gr_vector_void_star output_items(DEFAULT_CAPACITY); - unsigned int bi; - unsigned int nalive; - int max_items_avail; - bool made_progress_last_pass; - bool making_progress; - - for(unsigned i = 0; i < d_blocks.size (); i++) - d_blocks[i]->detail()->set_done (false); // reset any done flags - - for(unsigned i = 0; i < d_blocks.size (); i++) // enable any drivers, etc. - d_blocks[i]->start(); - - bi = 0; - made_progress_last_pass = true; - making_progress = false; - - // Loop while there are still blocks alive - - nalive = d_blocks.size (); - while(d_enabled && nalive > 0) { - if(boost::this_thread::interruption_requested()) - break; - - block *m = d_blocks[bi].get (); - block_detail *d = m->detail().get (); - - LOG(*d_log << std::endl << m); - - if(d->done ()) - goto next_block; - - if(d->source_p ()) { - // Invoke sources as a last resort. As long as the previous - // pass made progress, don't call a source. - if(made_progress_last_pass) { - LOG(*d_log << " Skipping source\n"); - goto next_block; - } - - ninput_items_required.resize (0); - ninput_items.resize (0); - input_items.resize (0); - output_items.resize (d->noutputs ()); - - // determine the minimum available output space - noutput_items = min_available_space (d, m->output_multiple ()); - LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl); - if(noutput_items == -1) // we're done - goto were_done; - - if(noutput_items == 0) { // we're output blocked - LOG(*d_log << " BLKD_OUT\n"); - goto next_block; - } - - goto setup_call_to_work; // jump to common code - } - - else if(d->sink_p ()) { - ninput_items_required.resize (d->ninputs ()); - ninput_items.resize (d->ninputs ()); - input_items.resize (d->ninputs ()); - output_items.resize (0); - LOG(*d_log << " sink\n"); - - max_items_avail = 0; - for(int i = 0; i < d->ninputs (); i++) { - ninput_items[i] = d->input(i)->items_available(); - //if (ninput_items[i] == 0 && d->input(i)->done()) - if(ninput_items[i] < m->output_multiple() && d->input(i)->done()) - goto were_done; - - max_items_avail = std::max (max_items_avail, ninput_items[i]); - } - - // take a swag at how much output we can sink - noutput_items = (int) (max_items_avail * m->relative_rate ()); - noutput_items = round_down (noutput_items, m->output_multiple ()); - LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl); - LOG(*d_log << " noutput_items = " << noutput_items << std::endl); - - if(noutput_items == 0) { // we're blocked on input - LOG(*d_log << " BLKD_IN\n"); - goto next_block; - } - - goto try_again; // Jump to code shared with regular case. - } - - else { - // do the regular thing - ninput_items_required.resize(d->ninputs ()); - ninput_items.resize(d->ninputs ()); - input_items.resize(d->ninputs ()); - output_items.resize(d->noutputs ()); - - max_items_avail = 0; - for(int i = 0; i < d->ninputs (); i++) { - ninput_items[i] = d->input(i)->items_available (); - max_items_avail = std::max(max_items_avail, ninput_items[i]); - } - - // determine the minimum available output space - noutput_items = min_available_space(d, m->output_multiple ()); - if(ENABLE_LOGGING){ - *d_log << " regular "; - if(m->relative_rate() >= 1.0) - *d_log << "1:" << m->relative_rate() << std::endl; - else - *d_log << 1.0/m->relative_rate() << ":1\n"; - *d_log << " max_items_avail = " << max_items_avail << std::endl; - *d_log << " noutput_items = " << noutput_items << std::endl; - } - if(noutput_items == -1) // we're done - goto were_done; - - if(noutput_items == 0) { // we're output blocked - LOG(*d_log << " BLKD_OUT\n"); - goto next_block; - } - -#if 0 - // Compute best estimate of noutput_items that we can really use. - noutput_items = - std::min((unsigned)noutput_items, - std::max((unsigned)m->output_multiple(), - round_up((unsigned)(max_items_avail * m->relative_rate()), - m->output_multiple()))); - - LOG(*d_log << " revised noutput_items = " << noutput_items << std::endl); -#endif - - try_again: - if(m->fixed_rate()) { - // try to work it forward starting with max_items_avail. - // We want to try to consume all the input we've got. - int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail); - reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple()); - if(reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items) - noutput_items = reqd_noutput_items; - } - - // ask the block how much input they need to produce noutput_items - m->forecast(noutput_items, ninput_items_required); - - // See if we've got sufficient input available - int i; - for(i = 0; i < d->ninputs (); i++) - if(ninput_items_required[i] > ninput_items[i]) // not enough - break; - - if(i < d->ninputs()) { // not enough input on input[i] - // if we can, try reducing the size of our output request - if(noutput_items > m->output_multiple ()){ - noutput_items /= 2; - noutput_items = round_up (noutput_items, m->output_multiple ()); - goto try_again; - } - - // We're blocked on input - LOG(*d_log << " BLKD_IN\n"); - if(d->input(i)->done()) // If the upstream block is done, we're done - goto were_done; - - // Is it possible to ever fulfill this request? - if(ninput_items_required[i] > d->input(i)->max_possible_items_available ()) { - // Nope, never going to happen... - std::cerr << "\nsched: <block " << m->name() - << " (" << m->unique_id() << ")>" - << " is requesting more input data\n" - << " than we can provide.\n" - << " ninput_items_required = " - << ninput_items_required[i] << "\n" - << " max_possible_items_available = " - << d->input(i)->max_possible_items_available() << "\n" - << " If this is a filter, consider reducing the number of taps.\n"; - goto were_done; - } - - goto next_block; - } - - // We've got enough data on each input to produce noutput_items. - // Finish setting up the call to work. - for(int i = 0; i < d->ninputs (); i++) - input_items[i] = d->input(i)->read_pointer(); - - setup_call_to_work: - - for(int i = 0; i < d->noutputs (); i++) - output_items[i] = d->output(i)->write_pointer(); - - // Do the actual work of the block - int n = m->general_work(noutput_items, ninput_items, - input_items, output_items); - LOG(*d_log << " general_work: noutput_items = " << noutput_items - << " result = " << n << std::endl); - - if(n == -1) // block is done - goto were_done; - - d->produce_each(n); // advance write pointers - if(n > 0) - making_progress = true; - - goto next_block; - } - assert(0); - - were_done: - LOG(*d_log << " were_done\n"); - d->set_done (true); - nalive--; - - next_block: - if(++bi >= d_blocks.size ()) { - bi = 0; - made_progress_last_pass = making_progress; - making_progress = false; - } - } - - for(unsigned i = 0; i < d_blocks.size(); i++) // disable any drivers, etc. - d_blocks[i]->stop(); - } - -} /* namespace gr */ diff --git a/gnuradio-runtime/lib/single_threaded_scheduler.h b/gnuradio-runtime/lib/single_threaded_scheduler.h deleted file mode 100644 index eccbf03b36..0000000000 --- a/gnuradio-runtime/lib/single_threaded_scheduler.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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_SINGLE_THREADED_SCHEDULER_H -#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H - -#include <gnuradio/api.h> -#include <gnuradio/runtime_types.h> -#include <fstream> - -namespace gr { - - class single_threaded_scheduler; - typedef boost::shared_ptr<single_threaded_scheduler> single_threaded_scheduler_sptr; - - /*! - * \brief Simple scheduler for stream computations. - * \ingroup internal - */ - class GR_RUNTIME_API single_threaded_scheduler - { - public: - ~single_threaded_scheduler(); - - void run(); - void stop(); - - private: - const std::vector<block_sptr> d_blocks; - volatile bool d_enabled; - std::ofstream *d_log; - - single_threaded_scheduler(const std::vector<block_sptr> &blocks); - - void main_loop(); - - friend GR_RUNTIME_API single_threaded_scheduler_sptr - make_single_threaded_scheduler(const std::vector<block_sptr> &blocks); - }; - - GR_RUNTIME_API single_threaded_scheduler_sptr - make_single_threaded_scheduler(const std::vector<block_sptr> &blocks); - -} /* namespace gr */ - -#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */ diff --git a/gnuradio-runtime/lib/top_block_impl.cc b/gnuradio-runtime/lib/top_block_impl.cc index 3f94867bc2..d2a07e89ef 100644 --- a/gnuradio-runtime/lib/top_block_impl.cc +++ b/gnuradio-runtime/lib/top_block_impl.cc @@ -26,7 +26,6 @@ #include "top_block_impl.h" #include "flat_flowgraph.h" -#include "scheduler_sts.h" #include "scheduler_tpb.h" #include <gnuradio/top_block.h> #include <gnuradio/prefs.h> @@ -48,8 +47,7 @@ namespace gr { const char *name; scheduler_maker f; } scheduler_table[] = { - { "TPB", scheduler_tpb::make }, // first entry is default - { "STS", scheduler_sts::make } + { "TPB", scheduler_tpb::make } // first entry is default }; static scheduler_sptr diff --git a/gnuradio-runtime/swig/CMakeLists.txt b/gnuradio-runtime/swig/CMakeLists.txt index 1b6921fb07..698283fe4d 100644 --- a/gnuradio-runtime/swig/CMakeLists.txt +++ b/gnuradio-runtime/swig/CMakeLists.txt @@ -106,7 +106,6 @@ install( pmt_swig.i prefs.i realtime.i - single_threaded_scheduler.i sync_block.i sync_decimator.i sync_interpolator.i diff --git a/gnuradio-runtime/swig/single_threaded_scheduler.i b/gnuradio-runtime/swig/single_threaded_scheduler.i deleted file mode 100644 index f4fbed075c..0000000000 --- a/gnuradio-runtime/swig/single_threaded_scheduler.i +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2013 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. - */ - -#include <gnuradio/runtime.h> - -class gr::single_threaded_scheduler; -typedef boost::shared_ptr<gr::single_threaded_scheduler> gr::single_threaded_scheduler_sptr; -%template(single_threaded_scheduler_sptr) boost::shared_ptr<gr::single_threaded_scheduler>; -%rename(single_threaded_scheduler) gr::make_single_threaded_scheduler; -%ignore gr::single_threaded_scheduler; - -gr::single_threaded_scheduler_sptr -gr::make_single_threaded_scheduler(const std::vector<gr::block_sptr> &modules); - -class gr::single_threaded_scheduler { - public: - ~single_threaded_scheduler (); - - // void run (); - void stop (); - - private: - single_threaded_scheduler (const std::vector<block_sptr> &modules); -}; - -#ifdef SWIGPYTHON -%inline %{ - void sts_pyrun (gr::single_threaded_scheduler_sptr s) { - Py_BEGIN_ALLOW_THREADS; // release global interpreter lock - s->run (); - Py_END_ALLOW_THREADS; // acquire global interpreter lock - } -%} -#endif - |