GNU Radio 3.7.1 C++ API
|
00001 /* -*- c++ -*- */ 00002 /* 00003 * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc. 00004 * 00005 * This file is part of GNU Radio 00006 * 00007 * GNU Radio is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3, or (at your option) 00010 * any later version. 00011 * 00012 * GNU Radio is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with GNU Radio; see the file COPYING. If not, write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, 00020 * Boston, MA 02110-1301, USA. 00021 */ 00022 00023 #ifndef INCLUDED_GR_RUNTIME_BLOCK_H 00024 #define INCLUDED_GR_RUNTIME_BLOCK_H 00025 00026 #include <gnuradio/api.h> 00027 #include <gnuradio/basic_block.h> 00028 #include <gnuradio/tags.h> 00029 #include <gnuradio/logger.h> 00030 00031 namespace gr { 00032 00033 /*! 00034 * \brief The abstract base class for all 'terminal' processing blocks. 00035 * \ingroup base_blk 00036 * 00037 * A signal processing flow is constructed by creating a tree of 00038 * hierarchical blocks, which at any level may also contain terminal 00039 * nodes that actually implement signal processing functions. This 00040 * is the base class for all such leaf nodes. 00041 * 00042 * Blocks have a set of input streams and output streams. The 00043 * input_signature and output_signature define the number of input 00044 * streams and output streams respectively, and the type of the data 00045 * items in each stream. 00046 * 00047 * Although blocks may consume data on each input stream at a 00048 * different rate, all outputs streams must produce data at the same 00049 * rate. That rate may be different from any of the input rates. 00050 * 00051 * User derived blocks override two methods, forecast and 00052 * general_work, to implement their signal processing 00053 * behavior. forecast is called by the system scheduler to determine 00054 * how many items are required on each input stream in order to 00055 * produce a given number of output items. 00056 * 00057 * general_work is called to perform the signal processing in the 00058 * block. It reads the input items and writes the output items. 00059 */ 00060 class GR_RUNTIME_API block : public basic_block 00061 { 00062 public: 00063 00064 //! Magic return values from general_work 00065 enum { 00066 WORK_CALLED_PRODUCE = -2, 00067 WORK_DONE = -1 00068 }; 00069 00070 enum tag_propagation_policy_t { 00071 TPP_DONT = 0, 00072 TPP_ALL_TO_ALL = 1, 00073 TPP_ONE_TO_ONE = 2 00074 }; 00075 00076 virtual ~block(); 00077 00078 /*! 00079 * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...) 00080 * History is the number of x_i's that are examined to produce one y_i. 00081 * This comes in handy for FIR filters, where we use history to 00082 * ensure that our input contains the appropriate "history" for the 00083 * filter. History should be equal to the number of filter taps. 00084 */ 00085 unsigned history() const { return d_history; } 00086 void set_history(unsigned history) { d_history = history; } 00087 00088 /*! 00089 * \brief Return true if this block has a fixed input to output rate. 00090 * 00091 * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called. 00092 */ 00093 bool fixed_rate() const { return d_fixed_rate; } 00094 00095 // ---------------------------------------------------------------- 00096 // override these to define your behavior 00097 // ---------------------------------------------------------------- 00098 00099 /*! 00100 * \brief Estimate input requirements given output request 00101 * 00102 * \param noutput_items number of output items to produce 00103 * \param ninput_items_required number of input items required on each input stream 00104 * 00105 * Given a request to product \p noutput_items, estimate the 00106 * number of data items required on each input stream. The 00107 * estimate doesn't have to be exact, but should be close. 00108 */ 00109 virtual void forecast(int noutput_items, 00110 gr_vector_int &ninput_items_required); 00111 00112 /*! 00113 * \brief compute output items from input items 00114 * 00115 * \param noutput_items number of output items to write on each output stream 00116 * \param ninput_items number of input items available on each input stream 00117 * \param input_items vector of pointers to the input items, one entry per input stream 00118 * \param output_items vector of pointers to the output items, one entry per output stream 00119 * 00120 * \returns number of items actually written to each output stream, or -1 on EOF. 00121 * It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items 00122 * 00123 * general_work must call consume or consume_each to indicate how 00124 * many items were consumed on each input stream. 00125 */ 00126 virtual int general_work(int noutput_items, 00127 gr_vector_int &ninput_items, 00128 gr_vector_const_void_star &input_items, 00129 gr_vector_void_star &output_items); 00130 00131 /*! 00132 * \brief Called to enable drivers, etc for i/o devices. 00133 * 00134 * This allows a block to enable an associated driver to begin 00135 * transfering data just before we start to execute the scheduler. 00136 * The end result is that this reduces latency in the pipeline 00137 * when dealing with audio devices, usrps, etc. 00138 */ 00139 virtual bool start(); 00140 00141 /*! 00142 * \brief Called to disable drivers, etc for i/o devices. 00143 */ 00144 virtual bool stop(); 00145 00146 // ---------------------------------------------------------------- 00147 00148 /*! 00149 * \brief Constrain the noutput_items argument passed to forecast and general_work 00150 * 00151 * set_output_multiple causes the scheduler to ensure that the 00152 * noutput_items argument passed to forecast and general_work will 00153 * be an integer multiple of \param multiple The default value of 00154 * output multiple is 1. 00155 */ 00156 void set_output_multiple(int multiple); 00157 int output_multiple() const { return d_output_multiple; } 00158 bool output_multiple_set() const { return d_output_multiple_set; } 00159 00160 /*! 00161 * \brief Constrains buffers to work on a set item alignment (for SIMD) 00162 * 00163 * set_alignment_multiple causes the scheduler to ensure that the 00164 * noutput_items argument passed to forecast and general_work will 00165 * be an integer multiple of \param multiple The default value is 00166 * 1. 00167 * 00168 * This control is similar to the output_multiple setting, except 00169 * that if the number of items passed to the block is less than 00170 * the output_multiple, this value is ignored and the block can 00171 * produce like normal. The d_unaligned value is set to the number 00172 * of items the block is off by. In the next call to general_work, 00173 * the noutput_items is set to d_unaligned or less until 00174 * d_unaligned==0. The buffers are now aligned again and the 00175 * aligned calls can be performed again. 00176 */ 00177 void set_alignment(int multiple); 00178 int alignment() const { return d_output_multiple; } 00179 00180 void set_unaligned(int na); 00181 int unaligned() const { return d_unaligned; } 00182 void set_is_unaligned(bool u); 00183 bool is_unaligned() const { return d_is_unaligned; } 00184 00185 /*! 00186 * \brief Tell the scheduler \p how_many_items of input stream \p 00187 * which_input were consumed. 00188 */ 00189 void consume(int which_input, int how_many_items); 00190 00191 /*! 00192 * \brief Tell the scheduler \p how_many_items were consumed on 00193 * each input stream. 00194 */ 00195 void consume_each(int how_many_items); 00196 00197 /*! 00198 * \brief Tell the scheduler \p how_many_items were produced on 00199 * output stream \p which_output. 00200 * 00201 * If the block's general_work method calls produce, \p 00202 * general_work must return WORK_CALLED_PRODUCE. 00203 */ 00204 void produce(int which_output, int how_many_items); 00205 00206 /*! 00207 * \brief Set the approximate output rate / input rate 00208 * 00209 * Provide a hint to the buffer allocator and scheduler. 00210 * The default relative_rate is 1.0 00211 * 00212 * decimators have relative_rates < 1.0 00213 * interpolators have relative_rates > 1.0 00214 */ 00215 void set_relative_rate(double relative_rate); 00216 00217 /*! 00218 * \brief return the approximate output rate / input rate 00219 */ 00220 double relative_rate() const { return d_relative_rate; } 00221 00222 /* 00223 * The following two methods provide special case info to the 00224 * scheduler in the event that a block has a fixed input to output 00225 * ratio. sync_block, sync_decimator and 00226 * sync_interpolator override these. If you're fixed rate, 00227 * subclass one of those. 00228 */ 00229 /*! 00230 * \brief Given ninput samples, return number of output samples that will be produced. 00231 * N.B. this is only defined if fixed_rate returns true. 00232 * Generally speaking, you don't need to override this. 00233 */ 00234 virtual int fixed_rate_ninput_to_noutput(int ninput); 00235 00236 /*! 00237 * \brief Given noutput samples, return number of input samples required to produce noutput. 00238 * N.B. this is only defined if fixed_rate returns true. 00239 * Generally speaking, you don't need to override this. 00240 */ 00241 virtual int fixed_rate_noutput_to_ninput(int noutput); 00242 00243 /*! 00244 * \brief Return the number of items read on input stream which_input 00245 */ 00246 uint64_t nitems_read(unsigned int which_input); 00247 00248 /*! 00249 * \brief Return the number of items written on output stream which_output 00250 */ 00251 uint64_t nitems_written(unsigned int which_output); 00252 00253 /*! 00254 * \brief Asks for the policy used by the scheduler to moved tags downstream. 00255 */ 00256 tag_propagation_policy_t tag_propagation_policy(); 00257 00258 /*! 00259 * \brief Set the policy by the scheduler to determine how tags are moved downstream. 00260 */ 00261 void set_tag_propagation_policy(tag_propagation_policy_t p); 00262 00263 /*! 00264 * \brief Return the minimum number of output items this block can 00265 * produce during a call to work. 00266 * 00267 * Should be 0 for most blocks. Useful if we're dealing with 00268 * packets and the block produces one packet per call to work. 00269 */ 00270 int min_noutput_items() const { return d_min_noutput_items; } 00271 00272 /*! 00273 * \brief Set the minimum number of output items this block can 00274 * produce during a call to work. 00275 * 00276 * \param m the minimum noutput_items this block can produce. 00277 */ 00278 void set_min_noutput_items(int m) { d_min_noutput_items = m; } 00279 00280 /*! 00281 * \brief Return the maximum number of output items this block will 00282 * handle during a call to work. 00283 */ 00284 int max_noutput_items(); 00285 00286 /*! 00287 * \brief Set the maximum number of output items this block will 00288 * handle during a call to work. 00289 * 00290 * \param m the maximum noutput_items this block will handle. 00291 */ 00292 void set_max_noutput_items(int m); 00293 00294 /*! 00295 * \brief Clear the switch for using the max_noutput_items value of this block. 00296 * 00297 * When is_set_max_noutput_items() returns 'true', the scheduler 00298 * will use the value returned by max_noutput_items() to limit the 00299 * size of the number of items possible for this block's work 00300 * function. If is_set_max_notput_items() returns 'false', then 00301 * the scheduler ignores the internal value and uses the value set 00302 * globally in the top_block. 00303 * 00304 * Use this value to clear the 'is_set' flag so the scheduler will 00305 * ignore this. Use the set_max_noutput_items(m) call to both set 00306 * a new value for max_noutput_items and to reenable its use in 00307 * the scheduler. 00308 */ 00309 void unset_max_noutput_items(); 00310 00311 /*! 00312 * \brief Ask the block if the flag is or is not set to use the 00313 * internal value of max_noutput_items during a call to work. 00314 */ 00315 bool is_set_max_noutput_items(); 00316 00317 /* 00318 * Used to expand the vectors that hold the min/max buffer sizes. 00319 * 00320 * Specifically, when -1 is used, the vectors are just initialized 00321 * with 1 value; this is used by the flat_flowgraph to expand when 00322 * required to add a new value for new ports on these blocks. 00323 */ 00324 void expand_minmax_buffer(int port); 00325 00326 /*! 00327 * \brief Returns max buffer size on output port \p i. 00328 */ 00329 long max_output_buffer(size_t i); 00330 00331 /*! 00332 * \brief Sets max buffer size on all output ports. 00333 */ 00334 void set_max_output_buffer(long max_output_buffer); 00335 00336 /*! 00337 * \brief Sets max buffer size on output port \p port. 00338 */ 00339 void set_max_output_buffer(int port, long max_output_buffer); 00340 00341 /*! 00342 * \brief Returns min buffer size on output port \p i. 00343 */ 00344 long min_output_buffer(size_t i); 00345 00346 /*! 00347 * \brief Sets min buffer size on all output ports. 00348 */ 00349 void set_min_output_buffer(long min_output_buffer); 00350 00351 /*! 00352 * \brief Sets min buffer size on output port \p port. 00353 */ 00354 void set_min_output_buffer(int port, long min_output_buffer); 00355 00356 // --------------- Performance counter functions ------------- 00357 00358 /*! 00359 * \brief Gets instantaneous noutput_items performance counter. 00360 */ 00361 float pc_noutput_items(); 00362 00363 /*! 00364 * \brief Gets average noutput_items performance counter. 00365 */ 00366 float pc_noutput_items_avg(); 00367 00368 /*! 00369 * \brief Gets variance of noutput_items performance counter. 00370 */ 00371 float pc_noutput_items_var(); 00372 00373 /*! 00374 * \brief Gets instantaneous num items produced performance counter. 00375 */ 00376 float pc_nproduced(); 00377 00378 /*! 00379 * \brief Gets average num items produced performance counter. 00380 */ 00381 float pc_nproduced_avg(); 00382 00383 /*! 00384 * \brief Gets variance of num items produced performance counter. 00385 */ 00386 float pc_nproduced_var(); 00387 00388 /*! 00389 * \brief Gets instantaneous fullness of \p which input buffer. 00390 */ 00391 float pc_input_buffers_full(int which); 00392 00393 /*! 00394 * \brief Gets average fullness of \p which input buffer. 00395 */ 00396 float pc_input_buffers_full_avg(int which); 00397 00398 /*! 00399 * \brief Gets variance of fullness of \p which input buffer. 00400 */ 00401 float pc_input_buffers_full_var(int which); 00402 00403 /*! 00404 * \brief Gets instantaneous fullness of all input buffers. 00405 */ 00406 std::vector<float> pc_input_buffers_full(); 00407 00408 /*! 00409 * \brief Gets average fullness of all input buffers. 00410 */ 00411 std::vector<float> pc_input_buffers_full_avg(); 00412 00413 /*! 00414 * \brief Gets variance of fullness of all input buffers. 00415 */ 00416 std::vector<float> pc_input_buffers_full_var(); 00417 00418 /*! 00419 * \brief Gets instantaneous fullness of \p which input buffer. 00420 */ 00421 float pc_output_buffers_full(int which); 00422 00423 /*! 00424 * \brief Gets average fullness of \p which input buffer. 00425 */ 00426 float pc_output_buffers_full_avg(int which); 00427 00428 /*! 00429 * \brief Gets variance of fullness of \p which input buffer. 00430 */ 00431 float pc_output_buffers_full_var(int which); 00432 00433 /*! 00434 * \brief Gets instantaneous fullness of all output buffers. 00435 */ 00436 std::vector<float> pc_output_buffers_full(); 00437 00438 /*! 00439 * \brief Gets average fullness of all output buffers. 00440 */ 00441 std::vector<float> pc_output_buffers_full_avg(); 00442 00443 /*! 00444 * \brief Gets variance of fullness of all output buffers. 00445 */ 00446 std::vector<float> pc_output_buffers_full_var(); 00447 00448 /*! 00449 * \brief Gets instantaneous clock cycles spent in work. 00450 */ 00451 float pc_work_time(); 00452 00453 /*! 00454 * \brief Gets average clock cycles spent in work. 00455 */ 00456 float pc_work_time_avg(); 00457 00458 /*! 00459 * \brief Gets average clock cycles spent in work. 00460 */ 00461 float pc_work_time_var(); 00462 00463 /*! 00464 * \brief Resets the performance counters 00465 */ 00466 void reset_perf_counters(); 00467 00468 /*! 00469 * \brief Sets up export of perf. counters to ControlPort. Only 00470 * called by the scheduler. 00471 */ 00472 void setup_pc_rpc(); 00473 00474 /*! 00475 * \brief Checks if this block is already exporting perf. counters 00476 * to ControlPort. 00477 */ 00478 bool is_pc_rpc_set() { return d_pc_rpc_set; } 00479 00480 /*! 00481 * \brief If the block calls this in its constructor, it's 00482 * perf. counters will not be exported. 00483 */ 00484 void no_pc_rpc() { d_pc_rpc_set = true; } 00485 00486 00487 // ---------------------------------------------------------------------------- 00488 // Functions to handle thread affinity 00489 00490 /*! 00491 * \brief Set the thread's affinity to processor core \p n. 00492 * 00493 * \param mask a vector of ints of the core numbers available to this block. 00494 */ 00495 void set_processor_affinity(const std::vector<int> &mask); 00496 00497 /*! 00498 * \brief Remove processor affinity to a specific core. 00499 */ 00500 void unset_processor_affinity(); 00501 00502 /*! 00503 * \brief Get the current processor affinity. 00504 */ 00505 std::vector<int> processor_affinity() { return d_affinity; } 00506 00507 /*! 00508 * \brief Get the current thread priority in use 00509 */ 00510 int active_thread_priority(); 00511 00512 /*! 00513 * \brief Get the current thread priority stored 00514 */ 00515 int thread_priority(); 00516 00517 /*! 00518 * \brief Set the current thread priority 00519 */ 00520 int set_thread_priority(int priority); 00521 00522 // ---------------------------------------------------------------------------- 00523 00524 private: 00525 int d_output_multiple; 00526 bool d_output_multiple_set; 00527 int d_unaligned; 00528 bool d_is_unaligned; 00529 double d_relative_rate; // approx output_rate / input_rate 00530 block_detail_sptr d_detail; // implementation details 00531 unsigned d_history; 00532 bool d_fixed_rate; 00533 bool d_max_noutput_items_set; // if d_max_noutput_items is valid 00534 int d_max_noutput_items; // value of max_noutput_items for this block 00535 int d_min_noutput_items; 00536 tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream 00537 std::vector<int> d_affinity; // thread affinity proc. mask 00538 int d_priority; // thread priority level 00539 bool d_pc_rpc_set; 00540 00541 protected: 00542 block(void) {} // allows pure virtual interface sub-classes 00543 block(const std::string &name, 00544 gr::io_signature::sptr input_signature, 00545 gr::io_signature::sptr output_signature); 00546 00547 void set_fixed_rate(bool fixed_rate) { d_fixed_rate = fixed_rate; } 00548 00549 /*! 00550 * \brief Adds a new tag onto the given output buffer. 00551 * 00552 * \param which_output an integer of which output stream to attach the tag 00553 * \param abs_offset a uint64 number of the absolute item number 00554 * assicated with the tag. Can get from nitems_written. 00555 * \param key the tag key as a PMT symbol 00556 * \param value any PMT holding any value for the given key 00557 * \param srcid optional source ID specifier; defaults to PMT_F 00558 */ 00559 inline void add_item_tag(unsigned int which_output, 00560 uint64_t abs_offset, 00561 const pmt::pmt_t &key, 00562 const pmt::pmt_t &value, 00563 const pmt::pmt_t &srcid=pmt::PMT_F) 00564 { 00565 tag_t tag; 00566 tag.offset = abs_offset; 00567 tag.key = key; 00568 tag.value = value; 00569 tag.srcid = srcid; 00570 this->add_item_tag(which_output, tag); 00571 } 00572 00573 /*! 00574 * \brief Adds a new tag onto the given output buffer. 00575 * 00576 * \param which_output an integer of which output stream to attach the tag 00577 * \param tag the tag object to add 00578 */ 00579 void add_item_tag(unsigned int which_output, const tag_t &tag); 00580 00581 /*! 00582 * \brief Removes a tag from the given input buffer. 00583 * 00584 * \param which_input an integer of which input stream to remove the tag from 00585 * \param abs_offset a uint64 number of the absolute item number 00586 * assicated with the tag. Can get from nitems_written. 00587 * \param key the tag key as a PMT symbol 00588 * \param value any PMT holding any value for the given key 00589 * \param srcid optional source ID specifier; defaults to PMT_F 00590 * 00591 * If no such tag is found, does nothing. 00592 */ 00593 inline void remove_item_tag(unsigned int which_input, 00594 uint64_t abs_offset, 00595 const pmt::pmt_t &key, 00596 const pmt::pmt_t &value, 00597 const pmt::pmt_t &srcid=pmt::PMT_F) 00598 { 00599 tag_t tag; 00600 tag.offset = abs_offset; 00601 tag.key = key; 00602 tag.value = value; 00603 tag.srcid = srcid; 00604 this->remove_item_tag(which_input, tag); 00605 } 00606 00607 /*! 00608 * \brief Removes a tag from the given input buffer. 00609 * 00610 * If no such tag is found, does nothing. 00611 * 00612 * \param which_input an integer of which input stream to remove the tag from 00613 * \param tag the tag object to remove 00614 */ 00615 void remove_item_tag(unsigned int which_input, const tag_t &tag); 00616 00617 /*! 00618 * \brief Given a [start,end), returns a vector of all tags in the range. 00619 * 00620 * Range of counts is from start to end-1. 00621 * 00622 * Tags are tuples of: 00623 * (item count, source id, key, value) 00624 * 00625 * \param v a vector reference to return tags into 00626 * \param which_input an integer of which input stream to pull from 00627 * \param abs_start a uint64 count of the start of the range of interest 00628 * \param abs_end a uint64 count of the end of the range of interest 00629 */ 00630 void get_tags_in_range(std::vector<tag_t> &v, 00631 unsigned int which_input, 00632 uint64_t abs_start, 00633 uint64_t abs_end); 00634 00635 /*! 00636 * \brief Given a [start,end), returns a vector of all tags in the 00637 * range with a given key. 00638 * 00639 * Range of counts is from start to end-1. 00640 * 00641 * Tags are tuples of: 00642 * (item count, source id, key, value) 00643 * 00644 * \param v a vector reference to return tags into 00645 * \param which_input an integer of which input stream to pull from 00646 * \param abs_start a uint64 count of the start of the range of interest 00647 * \param abs_end a uint64 count of the end of the range of interest 00648 * \param key a PMT symbol key to filter only tags of this key 00649 */ 00650 void get_tags_in_range(std::vector<tag_t> &v, 00651 unsigned int which_input, 00652 uint64_t abs_start, 00653 uint64_t abs_end, 00654 const pmt::pmt_t &key); 00655 00656 std::vector<long> d_max_output_buffer; 00657 std::vector<long> d_min_output_buffer; 00658 00659 /*! Used by block's setters and work functions to make 00660 * setting/resetting of parameters thread-safe. 00661 * 00662 * Used by calling gr::thread::scoped_lock l(d_setlock); 00663 */ 00664 gr::thread::mutex d_setlock; 00665 00666 /*! Used by blocks to access the logger system. 00667 */ 00668 gr::logger_ptr d_logger; 00669 gr::logger_ptr d_debug_logger; 00670 00671 // These are really only for internal use, but leaving them public avoids 00672 // having to work up an ever-varying list of friend GR_RUNTIME_APIs 00673 00674 public: 00675 block_detail_sptr detail() const { return d_detail; } 00676 void set_detail(block_detail_sptr detail) { d_detail = detail; } 00677 }; 00678 00679 typedef std::vector<block_sptr> block_vector_t; 00680 typedef std::vector<block_sptr>::iterator block_viter_t; 00681 00682 inline block_sptr cast_to_block_sptr(basic_block_sptr p) 00683 { 00684 return boost::dynamic_pointer_cast<block, basic_block>(p); 00685 } 00686 00687 std::ostream& 00688 operator << (std::ostream& os, const block *m); 00689 00690 } /* namespace gr */ 00691 00692 #endif /* INCLUDED_GR_RUNTIME_BLOCK_H */