diff options
Diffstat (limited to 'gnuradio-core/src/lib')
36 files changed, 202 insertions, 50 deletions
diff --git a/gnuradio-core/src/lib/filter/CMakeLists.txt b/gnuradio-core/src/lib/filter/CMakeLists.txt index ce7e387c2..d26e55fb8 100644 --- a/gnuradio-core/src/lib/filter/CMakeLists.txt +++ b/gnuradio-core/src/lib/filter/CMakeLists.txt @@ -28,7 +28,7 @@ foreach(gr_core_filter_asm ${gr_core_filter_asms}) endforeach(gr_core_filter_asm) #detect 32 or 64 bit compiler -if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x86_64)$") +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86|x86_64|amd64)$") include(CheckTypeSize) check_type_size("void*" SIZEOF_VOID_P BUILTIN_TYPES_ONLY) if (${SIZEOF_VOID_P} EQUAL 8) diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc index 02bfaf105..9fa98cc69 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.cc @@ -62,6 +62,7 @@ gr_fft_filter_ccc::gr_fft_filter_ccc (int decimation, const std::vector<gr_compl #else d_filter = new gri_fft_filter_ccc_sse(decimation, taps); #endif + d_new_taps = taps; d_nsamples = d_filter->set_taps(taps); set_output_multiple(d_nsamples); } @@ -78,6 +79,12 @@ gr_fft_filter_ccc::set_taps (const std::vector<gr_complex> &taps) d_updated = true; } +std::vector<gr_complex> +gr_fft_filter_ccc::taps () const +{ + return d_new_taps; +} + int gr_fft_filter_ccc::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h index 721a44a83..1b72a1c00 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.h @@ -62,6 +62,7 @@ class GR_CORE_API gr_fft_filter_ccc : public gr_sync_decimator ~gr_fft_filter_ccc (); void set_taps (const std::vector<gr_complex> &taps); + std::vector<gr_complex> taps () const; int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i index aa7564f54..812920d8b 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_ccc.i @@ -36,4 +36,5 @@ class gr_fft_filter_ccc : public gr_sync_decimator ~gr_fft_filter_ccc (); void set_taps (const std::vector<gr_complex> &taps); + std::vector<gr_complex> taps () const; }; diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc index e5b218f20..c0a9b3483 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.cc @@ -55,7 +55,7 @@ gr_fft_filter_fff::gr_fft_filter_fff (int decimation, const std::vector<float> & #else d_filter = new gri_fft_filter_fff_sse(decimation, taps); #endif - + d_new_taps = taps; d_nsamples = d_filter->set_taps(taps); set_output_multiple(d_nsamples); } @@ -72,6 +72,12 @@ gr_fft_filter_fff::set_taps (const std::vector<float> &taps) d_updated = true; } +std::vector<float> +gr_fft_filter_fff::taps () const +{ + return d_new_taps; +} + int gr_fft_filter_fff::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h index b0dc74883..ddd8dcac2 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.h @@ -62,6 +62,7 @@ class GR_CORE_API gr_fft_filter_fff : public gr_sync_decimator ~gr_fft_filter_fff (); void set_taps (const std::vector<float> &taps); + std::vector<float> taps () const; int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i index bbe84f99f..7e2cde977 100644 --- a/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i +++ b/gnuradio-core/src/lib/filter/gr_fft_filter_fff.i @@ -36,4 +36,5 @@ class gr_fft_filter_fff : public gr_sync_decimator ~gr_fft_filter_fff (); void set_taps (const std::vector<float> &taps); + std::vector<float> taps () const; }; diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t index 29e351925..f7458e743 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t +++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.cc.t @@ -63,6 +63,12 @@ void d_updated = true; } +std::vector<@TAP_TYPE@> +@NAME@::taps () const +{ + return d_new_taps; +} + int @NAME@::work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t index db0625504..f638e7bb5 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t +++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.h.t @@ -59,6 +59,7 @@ class GR_CORE_API @NAME@ : public gr_sync_decimator ~@NAME@ (); void set_taps (const std::vector<@TAP_TYPE@> &taps); + std::vector<@TAP_TYPE@> taps () const; int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t index 0cbe8cbcc..fb4ff95af 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t +++ b/gnuradio-core/src/lib/filter/gr_fir_filter_XXX.i.t @@ -38,4 +38,5 @@ class @NAME@ : public gr_sync_decimator ~@NAME@ (); void set_taps (const std::vector<@TAP_TYPE@> &taps); + std::vector<@TAP_TYPE@> taps () const; }; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index 398956ddd..9297b6587 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -60,7 +60,7 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float loop_bw, gr_make_io_signaturev (1, 4, iosig)), d_updated (false), d_nfilters(filter_size), d_max_dev(max_rate_deviation), - d_osps(osps), d_error(0) + d_osps(osps), d_error(0), d_out_idx(0) { d_nfilters = filter_size; d_sps = floor(sps); @@ -380,7 +380,7 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, // produce output as long as we can and there are enough input samples while((i < noutput_items) && (count < nrequired)) { - for(int k = 0; k < d_osps; k++) { + while(d_out_idx < d_osps) { d_filtnum = (int)floor(d_k); // Keep the current filter number in [0, d_nfilters] @@ -397,16 +397,27 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, count -= 1; } - out[i+k] = d_filters[d_filtnum]->filter(&in[count+k]); + out[i+d_out_idx] = d_filters[d_filtnum]->filter(&in[count+d_out_idx]); d_k = d_k + d_rate_i + d_rate_f; // update phase - + d_out_idx++; + if(output_items.size() == 4) { err[i] = d_error; outrate[i] = d_rate_f; outk[i] = d_k; } + + // We've run out of output items we can create; return now. + if(i+d_out_idx >= noutput_items) { + consume_each(count); + return i; + } } + // reset here; if we didn't complete a full osps samples last time, + // the early return would take care of it. + d_out_idx = 0; + // Update the phase and rate estimates for this symbol gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]); error_r = out[i].real() * diff.real(); @@ -424,7 +435,7 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, i+=d_osps; count += (int)floor(d_sps); } - consume_each(count); + consume_each(count); return i; } diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index f4f589cd9..1e1bbca10 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h @@ -197,7 +197,8 @@ class GR_CORE_API gr_pfb_clock_sync_ccf : public gr_block int d_filtnum; int d_osps; float d_error; - + int d_out_idx; + /*! * Build the polyphase filterbank timing synchronizer. */ diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc index 2fc97a78a..d0ed04238 100644 --- a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc +++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc @@ -31,6 +31,7 @@ #include <stdio.h> #include <cmath> #include <stdexcept> +#include <unistd.h> #define NELEM(x) (sizeof (x) / sizeof (x[0])) diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc index 3293e3ab8..c66015c11 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vcc_fftw.cc @@ -67,8 +67,17 @@ gr_fft_vcc_fftw::work (int noutput_items, if (d_window.size()){ gr_complex *dst = d_fft->get_inbuf(); - for (unsigned int i = 0; i < d_fft_size; i++) // apply window - dst[i] = in[i] * d_window[i]; + if(!d_forward && d_shift){ + int offset = (!d_forward && d_shift)?floor(d_fft_size/2):0; + int fft_m_offset = d_fft_size - offset; + for (unsigned int i = 0; i < offset; i++) // apply window + dst[i+fft_m_offset] = in[i] * d_window[i]; + for (unsigned int i = offset; i < d_fft_size; i++) // apply window + dst[i-offset] = in[i] * d_window[i]; + } else { + for (unsigned int i = 0; i < d_fft_size; i++) // apply window + dst[i] = in[i] * d_window[i]; + } } else { if(!d_forward && d_shift) { // apply an ifft shift on the data diff --git a/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t b/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t index 9dd92c8f5..ab5992257 100644 --- a/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t +++ b/gnuradio-core/src/lib/gengen/gr_noise_source_X.h.t @@ -55,6 +55,9 @@ class GR_CORE_API @NAME@ : public gr_sync_block { void set_type (gr_noise_type_t type) { d_type = type; } void set_amplitude (float ampl) { d_ampl = ampl; } + gr_noise_type_t type () const { return d_type; } + float amplitude () const { return d_ampl; } + virtual int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t b/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t index 27261502d..179dc0343 100644 --- a/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t +++ b/gnuradio-core/src/lib/gengen/gr_noise_source_X.i.t @@ -34,4 +34,7 @@ class @NAME@ : public gr_block { public: void set_type (gr_noise_type_t type) { d_type = type; } void set_amplitude (float ampl) { d_ampl = ampl; } + + gr_noise_type_t type () const { return d_type; } + float amplitude () const { return d_ampl; } }; diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.cc b/gnuradio-core/src/lib/hier/gr_channel_model.cc index fb57e808a..5f190e972 100644 --- a/gnuradio-core/src/lib/hier/gr_channel_model.cc +++ b/gnuradio-core/src/lib/hier/gr_channel_model.cc @@ -99,3 +99,28 @@ gr_channel_model::set_timing_offset(double epsilon) { d_timing_offset->set_interp_ratio(epsilon); } + + +double +gr_channel_model::noise_voltage() const +{ + return d_noise->amplitude(); +} + +double +gr_channel_model::frequency_offset() const +{ + return d_freq_offset->frequency(); +} + +std::vector<gr_complex> +gr_channel_model::taps() const +{ + return d_multipath->taps(); +} + +double +gr_channel_model::timing_offset() const +{ + return d_timing_offset->interp_ratio(); +} diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.h b/gnuradio-core/src/lib/hier/gr_channel_model.h index 07c0c76b6..c5d06ce11 100644 --- a/gnuradio-core/src/lib/hier/gr_channel_model.h +++ b/gnuradio-core/src/lib/hier/gr_channel_model.h @@ -71,4 +71,9 @@ class GR_CORE_API gr_channel_model : public gr_hier_block2 void set_frequency_offset(double frequency_offset); void set_taps(const std::vector<gr_complex> &taps); void set_timing_offset(double epsilon); + + double noise_voltage() const; + double frequency_offset() const; + std::vector<gr_complex> taps() const; + double timing_offset() const; }; diff --git a/gnuradio-core/src/lib/hier/gr_channel_model.i b/gnuradio-core/src/lib/hier/gr_channel_model.i index ff9ab466d..2e0cb7bdf 100644 --- a/gnuradio-core/src/lib/hier/gr_channel_model.i +++ b/gnuradio-core/src/lib/hier/gr_channel_model.i @@ -42,4 +42,9 @@ class gr_channel_model : public gr_hier_block2 void set_frequency_offset(double frequency_offset); void set_taps(const std::vector<gr_complex> &taps); void set_timing_offset(double epsilon); + + double noise_voltage() const; + double frequency_offset() const; + std::vector<gr_complex> taps() const; + double timing_offset() const; }; diff --git a/gnuradio-core/src/lib/io/gr_oscope_guts.cc b/gnuradio-core/src/lib/io/gr_oscope_guts.cc index ce7feca13..f1bdeb9c1 100644 --- a/gnuradio-core/src/lib/io/gr_oscope_guts.cc +++ b/gnuradio-core/src/lib/io/gr_oscope_guts.cc @@ -31,8 +31,7 @@ #include <math.h> #include <assert.h> -static const int OUTPUT_RECORD_SIZE = 2048; // must be power of 2 - +static const int OUTPUT_RECORD_SIZE = 16384; // Must be power of 2 static inline int wrap_bi (int buffer_index) // wrap buffer index { @@ -139,7 +138,7 @@ gr_oscope_guts::process_sample (const float *channel_data) { for (int i = 0; i < d_nchannels; i++) { - for (int j = OUTPUT_RECORD_SIZE-1; j >= 0; j--) + for (int j = OUTPUT_RECORD_SIZE-1; j > 0; j--) { d_buffer[i][j] = d_buffer[i][j-1]; } diff --git a/gnuradio-core/src/lib/io/gr_udp_sink.cc b/gnuradio-core/src/lib/io/gr_udp_sink.cc index 36b4cbe36..9fc4da0ae 100644 --- a/gnuradio-core/src/lib/io/gr_udp_sink.cc +++ b/gnuradio-core/src/lib/io/gr_udp_sink.cc @@ -20,6 +20,8 @@ * Boston, MA 02110-1301, USA. */ +#include <boost/asio.hpp> + #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc index 737b26f67..ef53baf78 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -155,8 +155,8 @@ propagate_tags(gr_block::tag_propagation_policy_t policy, gr_block_detail *d, return true; } -gr_block_executor::gr_block_executor (gr_block_sptr block) - : d_block(block), d_log(0) +gr_block_executor::gr_block_executor (gr_block_sptr block, int max_noutput_items) + : d_block(block), d_log(0), d_max_noutput_items(max_noutput_items) { if (ENABLE_LOGGING){ std::string name = str(boost::format("sst-%03d.log") % which_scheduler++); @@ -182,6 +182,7 @@ gr_block_executor::run_one_iteration() { int noutput_items; int max_items_avail; + int max_noutput_items = d_max_noutput_items; gr_block *m = d_block.get(); gr_block_detail *d = m->detail().get(); @@ -203,6 +204,7 @@ gr_block_executor::run_one_iteration() // determine the minimum available output space noutput_items = min_available_space (d, m->output_multiple ()); + noutput_items = std::min(noutput_items, d_max_noutput_items); LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl); if (noutput_items == -1) // we're done goto were_done; @@ -247,6 +249,7 @@ gr_block_executor::run_one_iteration() // 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 ()); + noutput_items = std::min(noutput_items, d_max_noutput_items); LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl); LOG(*d_log << " noutput_items = " << noutput_items << std::endl); @@ -307,7 +310,11 @@ gr_block_executor::run_one_iteration() 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; + + // if we need this many outputs, overrule the max_noutput_items setting + max_noutput_items = std::max(m->output_multiple(), max_noutput_items); } + noutput_items = std::min(noutput_items, max_noutput_items); // ask the block how much input they need to produce noutput_items m->forecast (noutput_items, d_ninput_items_required); diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.h b/gnuradio-core/src/lib/runtime/gr_block_executor.h index 15279f273..e022d8273 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.h +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.h @@ -51,9 +51,10 @@ protected: gr_vector_void_star d_output_items; std::vector<uint64_t> d_start_nitems_read; //stores where tag counts are before work std::vector<gr_tag_t> d_returned_tags; + int d_max_noutput_items; public: - gr_block_executor(gr_block_sptr block); + gr_block_executor(gr_block_sptr block, int max_noutput_items=100000); ~gr_block_executor (); enum state { diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_scheduler.cc index e4d8b3dd9..3ae08a7a3 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler.cc +++ b/gnuradio-core/src/lib/runtime/gr_scheduler.cc @@ -24,7 +24,7 @@ #endif #include <gr_scheduler.h> -gr_scheduler::gr_scheduler(gr_flat_flowgraph_sptr ffg) +gr_scheduler::gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items) { } diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.h b/gnuradio-core/src/lib/runtime/gr_scheduler.h index 4e97b5881..92af8d1cb 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler.h +++ b/gnuradio-core/src/lib/runtime/gr_scheduler.h @@ -47,7 +47,7 @@ public: * The scheduler will continue running until all blocks until they * report that they are done or the stop method is called. */ - gr_scheduler(gr_flat_flowgraph_sptr ffg); + gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items); virtual ~gr_scheduler(); diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc index fefc0dc70..3cc1d4d45 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc @@ -43,13 +43,13 @@ public: gr_scheduler_sptr -gr_scheduler_sts::make(gr_flat_flowgraph_sptr ffg) +gr_scheduler_sts::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items) { - return gr_scheduler_sptr(new gr_scheduler_sts(ffg)); + return gr_scheduler_sptr(new gr_scheduler_sts(ffg, max_noutput_items)); } -gr_scheduler_sts::gr_scheduler_sts(gr_flat_flowgraph_sptr ffg) - : gr_scheduler(ffg) +gr_scheduler_sts::gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items) + : gr_scheduler(ffg, max_noutput_items) { // Split the flattened flow graph into discrete partitions, each // of which is topologically sorted. diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h index 9b73b68c1..08c68d88a 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h @@ -39,10 +39,10 @@ protected: * The scheduler will continue running until all blocks until they * report that they are done or the stop method is called. */ - gr_scheduler_sts(gr_flat_flowgraph_sptr ffg); + gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items); public: - static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg); + static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items); ~gr_scheduler_sts(); diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc index af0338570..0a7ff4556 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc @@ -33,25 +33,27 @@ class tpb_container { gr_block_sptr d_block; + int d_max_noutput_items; public: - tpb_container(gr_block_sptr block) : d_block(block) {} + tpb_container(gr_block_sptr block, int max_noutput_items) + : d_block(block), d_max_noutput_items(max_noutput_items) {} void operator()() { - gr_tpb_thread_body body(d_block); + gr_tpb_thread_body body(d_block, d_max_noutput_items); } }; gr_scheduler_sptr -gr_scheduler_tpb::make(gr_flat_flowgraph_sptr ffg) +gr_scheduler_tpb::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items) { - return gr_scheduler_sptr(new gr_scheduler_tpb(ffg)); + return gr_scheduler_sptr(new gr_scheduler_tpb(ffg, max_noutput_items)); } -gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg) - : gr_scheduler(ffg) +gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items) + : gr_scheduler(ffg, max_noutput_items) { // Get a topologically sorted vector of all the blocks in use. // Being topologically sorted probably isn't going to matter, but @@ -73,7 +75,8 @@ gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg) std::stringstream name; name << "thread-per-block[" << i << "]: " << blocks[i]; d_threads.create_thread( - gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i]), name.str())); + gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i], max_noutput_items), + name.str())); } } diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h index f97ab2e7f..ab74fa84d 100644 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h @@ -39,10 +39,10 @@ protected: * The scheduler will continue running until all blocks until they * report that they are done or the stop method is called. */ - gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg); + gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items); public: - static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg); + static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items=100000); ~gr_scheduler_tpb(); diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc index f341525c0..56d1352cd 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc @@ -54,9 +54,9 @@ gr_top_block::~gr_top_block() } void -gr_top_block::start() +gr_top_block::start(int max_noutput_items) { - d_impl->start(); + d_impl->start(max_noutput_items); } void @@ -72,9 +72,9 @@ gr_top_block::wait() } void -gr_top_block::run() +gr_top_block::run(int max_noutput_items) { - start(); + start(max_noutput_items); wait(); } @@ -96,6 +96,18 @@ gr_top_block::dump() d_impl->dump(); } +int +gr_top_block::max_noutput_items() +{ + return d_impl->max_noutput_items(); +} + +void +gr_top_block::set_max_noutput_items(int nmax) +{ + d_impl->set_max_noutput_items(nmax); +} + gr_top_block_sptr gr_top_block::to_top_block() { diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.h b/gnuradio-core/src/lib/runtime/gr_top_block.h index fca68ae71..9d01ba3ef 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block.h @@ -53,16 +53,25 @@ public: * * Calls start() then wait(). Used to run a flowgraph that will stop * on its own, or when another thread will call stop(). + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph. This passes through to + * the start function; see that function for more details. */ - void run(); + void run(int max_noutput_items=100000); /*! * Start the contained flowgraph. Creates one or more threads to * execute the flow graph. Returns to the caller once the threads * are created. Calling start() on a top_block that is already * started IS an error. + * + * \param max_noutput_items the maximum number of output items + * allowed for any block in the flowgraph; the noutput_items can + * always be less than this, but this will cap it as a maximum. Use + * this to adjust the maximum latency a flowgraph can exhibit. */ - void start(); + void start(int max_noutput_items=100000); /*! * Stop the running flowgraph. Notifies each thread created by the @@ -107,6 +116,12 @@ public: */ void dump(); + //! Get the number of max noutput_items in the flowgraph + int max_noutput_items(); + + //! Set the maximum number of noutput_items in the flowgraph + void set_max_noutput_items(int nmax); + gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion }; diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i index 90fa18b94..70c627ffd 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.i +++ b/gnuradio-core/src/lib/runtime/gr_top_block.i @@ -40,7 +40,7 @@ private: public: ~gr_top_block(); - void start() throw (std::runtime_error); + void start(int max_noutput_items=100000) throw (std::runtime_error); void stop(); //void wait(); //void run() throw (std::runtime_error); @@ -48,6 +48,9 @@ public: void unlock() throw (std::runtime_error); void dump(); + int max_noutput_items(); + void set_max_noutput_items(int nmax); + gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion }; 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 9cad687fb..0227d789c 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc @@ -39,7 +39,8 @@ #define GR_TOP_BLOCK_IMPL_DEBUG 0 -typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg); +typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg, + int max_noutput_items); static struct scheduler_table { const char *name; @@ -50,7 +51,7 @@ static struct scheduler_table { }; static gr_scheduler_sptr -make_scheduler(gr_flat_flowgraph_sptr ffg) +make_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items) { static scheduler_maker factory = 0; @@ -72,7 +73,7 @@ make_scheduler(gr_flat_flowgraph_sptr ffg) } } } - return factory(ffg); + return factory(ffg, max_noutput_items); } @@ -88,10 +89,12 @@ gr_top_block_impl::~gr_top_block_impl() } void -gr_top_block_impl::start() +gr_top_block_impl::start(int max_noutput_items) { gruel::scoped_lock l(d_mutex); + d_max_noutput_items = max_noutput_items; + if (d_state != IDLE) throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()"); @@ -105,7 +108,7 @@ gr_top_block_impl::start() d_ffg->validate(); d_ffg->setup_connections(); - d_scheduler = make_scheduler(d_ffg); + d_scheduler = make_scheduler(d_ffg, d_max_noutput_items); d_state = RUNNING; } @@ -168,7 +171,7 @@ gr_top_block_impl::restart() d_ffg = new_ffg; // Create a new scheduler to execute it - d_scheduler = make_scheduler(d_ffg); + d_scheduler = make_scheduler(d_ffg, d_max_noutput_items); d_state = RUNNING; } @@ -178,3 +181,15 @@ gr_top_block_impl::dump() if (d_ffg) d_ffg->dump(); } + +int +gr_top_block_impl::max_noutput_items() +{ + return d_max_noutput_items; +} + +void +gr_top_block_impl::set_max_noutput_items(int nmax) +{ + d_max_noutput_items = nmax; +} 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 904443be5..d804e3f30 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h @@ -42,7 +42,7 @@ public: ~gr_top_block_impl(); // Create and start scheduler threads - void start(); + void start(int max_noutput_items=100000); // Signal scheduler threads to stop void stop(); @@ -58,6 +58,12 @@ public: // Dump the flowgraph to stdout void dump(); + + // Get the number of max noutput_items in the flowgraph + int max_noutput_items(); + + // Set the maximum number of noutput_items in the flowgraph + void set_max_noutput_items(int nmax); protected: @@ -70,6 +76,7 @@ protected: gruel::mutex d_mutex; // protects d_state and d_lock_count tb_state d_state; int d_lock_count; + int d_max_noutput_items; private: void restart(); diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc index faa888697..d44c09aa6 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc @@ -28,8 +28,8 @@ using namespace pmt; -gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) - : d_exec(block) +gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items) + : d_exec(block, max_noutput_items) { // std::cerr << "gr_tpb_thread_body: " << block << std::endl; diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h index 548cfedfb..3170b402e 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h @@ -38,7 +38,7 @@ class GR_CORE_API gr_tpb_thread_body { gr_block_executor d_exec; public: - gr_tpb_thread_body(gr_block_sptr block); + gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items=100000); ~gr_tpb_thread_body(); }; |