1 /* -*- c++ -*- */
2 /*
3 * Copyright 2004,2007,2009,2010,2013,2017 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU Radio
6 *
7 * GNU Radio is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
11 *
12 * GNU Radio is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Radio; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #ifndef INCLUDED_GR_RUNTIME_BLOCK_H
24 #define INCLUDED_GR_RUNTIME_BLOCK_H
25
26 #include <gnuradio/api.h>
27 #include <gnuradio/basic_block.h>
28 #include <gnuradio/config.h>
29 #include <gnuradio/logger.h>
30 #include <gnuradio/tags.h>
31 #ifdef GR_MPLIB_MPIR
32 #include <mpirxx.h>
33 #else
34 #include <gmpxx.h>
35 #endif
36
37 namespace gr {
38
39 /*!
40 * \brief The abstract base class for all 'terminal' processing blocks.
41 * \ingroup base_blk
42 *
43 * A signal processing flow is constructed by creating a tree of
44 * hierarchical blocks, which at any level may also contain terminal
45 * nodes that actually implement signal processing functions. This
46 * is the base class for all such leaf nodes.
47 *
48 * Blocks have a set of input streams and output streams. The
49 * input_signature and output_signature define the number of input
50 * streams and output streams respectively, and the type of the data
51 * items in each stream.
52 *
53 * Blocks report the number of items consumed on each input in
54 * general_work(), using consume() or consume_each().
55 *
56 * If the same number of items is produced on each output, the block
57 * returns that number from general_work(). Otherwise, the block
58 * calls produce() for each output, then returns
59 * WORK_CALLED_PRODUCE. The input and output rates are not required
60 * to be related.
61 *
62 * User derived blocks override two methods, forecast and
63 * general_work, to implement their signal processing
64 * behavior. forecast is called by the system scheduler to determine
65 * how many items are required on each input stream in order to
66 * produce a given number of output items.
67 *
68 * general_work is called to perform the signal processing in the
69 * block. It reads the input items and writes the output items.
70 */
71 class GR_RUNTIME_API block : public basic_block
72 {
73 public:
74 //! Magic return values from general_work
75 enum { WORK_CALLED_PRODUCE = -2, WORK_DONE = -1 };
76
77 /*!
78 * \brief enum to represent different tag propagation policies.
79 */
80 enum tag_propagation_policy_t {
81 TPP_DONT = 0, /*!< Scheduler doesn't propagate tags from in- to output. The block
82 itself is free to insert tags as it wants. */
83 TPP_ALL_TO_ALL = 1, /*!< Propagate tags from all in- to all outputs. The scheduler
84 takes care of that. */
85 TPP_ONE_TO_ONE = 2, /*!< Propagate tags from n. input to n. output. Requires same
86 number of in- and outputs */
87 TPP_CUSTOM = 3 /*!< Like TPP_DONT, but signals the block it should implement
88 application-specific forwarding behaviour. */
89 };
90
91 virtual ~block();
92
93 /*!
94 * Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
95 * History is the number of x_i's that are examined to produce one y_i.
96 * This comes in handy for FIR filters, where we use history to
97 * ensure that our input contains the appropriate "history" for the
98 * filter. History should be equal to the number of filter taps. First
99 * history samples (when there are no previous samples) are
100 * initialized with zeroes.
101 */
102 unsigned history() const;
103 void set_history(unsigned history);
104
105 /*!
106 * Declares the block's delay in samples. Since the delay of
107 * blocks like filters is derived from the taps and not the block
108 * itself, we cannot automatically calculate this value and so
109 * leave it as a user-defined property. It defaults to 0 is not
110 * set.
111 *
112 * This does not actively set the delay; it just tells the
113 * scheduler what the delay is.
114 *
115 * This delay is mostly used to adjust the placement of the tags
116 * and is not currently used for any signal processing. When a tag
117 * is passed through a block with internal delay, its location
118 * should be moved based on the delay of the block. This interface
119 * allows us to tell the scheduler this value.
120 *
121 * \param which The buffer on which to set the delay.
122 * \param delay The sample delay of the data stream.
123 */
124 void declare_sample_delay(int which, unsigned delay);
125
126 /*!
127 * Convenience wrapper to gr::block::declare_delay(int which, unsigned delay)
128 * to set all ports to the same delay.
129 */
130 void declare_sample_delay(unsigned delay);
131
132 /*!
133 * Gets the delay of the block. Since the delay of blocks like
134 * filters is derived from the taps and not the block itself, we
135 * cannot automatically calculate this value and so leave it as a
136 * user-defined property. It defaults to 0 is not set.
137 *
138 * \param which Which port from which to get the sample delay.
139 */
140 unsigned sample_delay(int which) const;
141
142 /*!
143 * \brief Return true if this block has a fixed input to output rate.
144 *
145 * If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
146 */
fixed_rate()147 bool fixed_rate() const { return d_fixed_rate; }
148
149 // ----------------------------------------------------------------
150 // override these to define your behavior
151 // ----------------------------------------------------------------
152
153 /*!
154 * \brief Estimate input requirements given output request
155 *
156 * \param noutput_items number of output items to produce
157 * \param ninput_items_required number of input items required on each input stream
158 *
159 * Given a request to product \p noutput_items, estimate the
160 * number of data items required on each input stream. The
161 * estimate doesn't have to be exact, but should be close.
162 */
163 virtual void forecast(int noutput_items, gr_vector_int& ninput_items_required);
164
165 /*!
166 * \brief compute output items from input items
167 *
168 * \param noutput_items number of output items to write on each output stream
169 * \param ninput_items number of input items available on each input stream
170 * \param input_items vector of pointers to the input items, one entry per input
171 * stream
172 * \param output_items vector of pointers to the output items, one entry per
173 * output stream
174 *
175 * \returns number of items actually written to each output stream
176 * or WORK_CALLED_PRODUCE or WORK_DONE. It is OK to return a
177 * value less than noutput_items.
178 *
179 * WORK_CALLED_PRODUCE is used where not all outputs produce the
180 * same number of items. general_work must call produce() for each
181 * output to indicate the number of items actually produced.
182 *
183 * WORK_DONE indicates that no more data will be produced by this block.
184 *
185 * general_work must call consume or consume_each to indicate how
186 * many items were consumed on each input stream.
187 */
188 virtual int general_work(int noutput_items,
189 gr_vector_int& ninput_items,
190 gr_vector_const_void_star& input_items,
191 gr_vector_void_star& output_items);
192
193 /*!
194 * \brief Called to enable drivers, etc for i/o devices.
195 *
196 * This allows a block to enable an associated driver to begin
197 * transferring data just before we start to execute the scheduler.
198 * The end result is that this reduces latency in the pipeline
199 * when dealing with audio devices, usrps, etc.
200 */
201 virtual bool start();
202
203 /*!
204 * \brief Called to disable drivers, etc for i/o devices.
205 */
206 virtual bool stop();
207
208 // ----------------------------------------------------------------
209
210 /*!
211 * \brief Constrain the noutput_items argument passed to forecast and general_work
212 *
213 * set_output_multiple causes the scheduler to ensure that the
214 * noutput_items argument passed to forecast and general_work will
215 * be an integer multiple of \param multiple The default value of
216 * output multiple is 1.
217 */
218 void set_output_multiple(int multiple);
output_multiple()219 int output_multiple() const { return d_output_multiple; }
output_multiple_set()220 bool output_multiple_set() const { return d_output_multiple_set; }
221
222 /*!
223 * \brief Constrains buffers to work on a set item alignment (for SIMD)
224 *
225 * set_alignment_multiple causes the scheduler to ensure that the
226 * noutput_items argument passed to forecast and general_work will
227 * be an integer multiple of \param multiple The default value is
228 * 1.
229 *
230 * This control is similar to the output_multiple setting, except
231 * that if the number of items passed to the block is less than
232 * the output_multiple, this value is ignored and the block can
233 * produce like normal. The d_unaligned value is set to the number
234 * of items the block is off by. In the next call to general_work,
235 * the noutput_items is set to d_unaligned or less until
236 * d_unaligned==0. The buffers are now aligned again and the
237 * aligned calls can be performed again.
238 */
239 void set_alignment(int multiple);
alignment()240 int alignment() const { return d_output_multiple; }
241
242 void set_unaligned(int na);
unaligned()243 int unaligned() const { return d_unaligned; }
244 void set_is_unaligned(bool u);
is_unaligned()245 bool is_unaligned() const { return d_is_unaligned; }
246
247 /*!
248 * \brief Tell the scheduler \p how_many_items of input stream \p
249 * which_input were consumed.
250 *
251 * This function should be used in general_work() to tell the scheduler the
252 * number of input items processed. Calling consume() multiple times in the
253 * same general_work() call is safe. Every invocation of consume() updates
254 * the values returned by nitems_read().
255 */
256 void consume(int which_input, int how_many_items);
257
258 /*!
259 * \brief Tell the scheduler \p how_many_items were consumed on
260 * each input stream.
261 *
262 * Also see notes on consume().
263 */
264 void consume_each(int how_many_items);
265
266 /*!
267 * \brief Tell the scheduler \p how_many_items were produced on
268 * output stream \p which_output.
269 *
270 * This function should be used in general_work() to tell the scheduler the
271 * number of output items produced. If produce() is called in
272 * general_work(), general_work() must return \p WORK_CALLED_PRODUCE.
273 * Calling produce() multiple times in the same general_work() call is safe.
274 * Every invocation of produce() updates the values returned by
275 * nitems_written().
276 */
277 void produce(int which_output, int how_many_items);
278
279 /*!
280 * \brief Set the approximate output rate / input rate
281 *
282 * Provide a hint to the buffer allocator and scheduler.
283 * The default relative_rate is 1.0
284 *
285 * decimators have relative_rates < 1.0
286 * interpolators have relative_rates > 1.0
287 */
288 void set_relative_rate(double relative_rate);
289
290 /*!
291 * \brief Set the approximate output rate / input rate
292 * using its reciprocal
293 *
294 * This is a convenience function to avoid
295 * numerical problems with tag propagation that calling
296 * set_relative_rate(1.0/relative_rate) might introduce.
297 */
298 void set_inverse_relative_rate(double inverse_relative_rate);
299
300 /*!
301 * \brief Set the approximate output rate / input rate as an integer ratio
302 *
303 * Provide a hint to the buffer allocator and scheduler.
304 * The default relative_rate is interpolation / decimation = 1 / 1
305 *
306 * decimators have relative_rates < 1.0
307 * interpolators have relative_rates > 1.0
308 */
309 void set_relative_rate(uint64_t interpolation, uint64_t decimation);
310
311 /*!
312 * \brief return the approximate output rate / input rate
313 */
relative_rate()314 double relative_rate() const { return d_relative_rate; }
315
316 /*!
317 * \brief return the numerator, or interpolation rate, of the
318 * approximate output rate / input rate
319 */
relative_rate_i()320 uint64_t relative_rate_i() const
321 {
322 return (uint64_t)d_mp_relative_rate.get_num().get_ui();
323 }
324
325 /*!
326 * \brief return the denominator, or decimation rate, of the
327 * approximate output rate / input rate
328 */
relative_rate_d()329 uint64_t relative_rate_d() const
330 {
331 return (uint64_t)d_mp_relative_rate.get_den().get_ui();
332 }
333
334 /*!
335 * \brief return a reference to the multiple precision rational
336 * representation of the approximate output rate / input rate
337 */
mp_relative_rate()338 mpq_class& mp_relative_rate() { return d_mp_relative_rate; }
339
340 /*
341 * The following two methods provide special case info to the
342 * scheduler in the event that a block has a fixed input to output
343 * ratio. sync_block, sync_decimator and
344 * sync_interpolator override these. If you're fixed rate,
345 * subclass one of those.
346 */
347 /*!
348 * \brief Given ninput samples, return number of output samples that will be produced.
349 * N.B. this is only defined if fixed_rate returns true.
350 * Generally speaking, you don't need to override this.
351 */
352 virtual int fixed_rate_ninput_to_noutput(int ninput);
353
354 /*!
355 * \brief Given noutput samples, return number of input samples required to produce
356 * noutput. N.B. this is only defined if fixed_rate returns true. Generally speaking,
357 * you don't need to override this.
358 */
359 virtual int fixed_rate_noutput_to_ninput(int noutput);
360
361 /*!
362 * \brief Return the number of items read on input stream which_input
363 */
364 uint64_t nitems_read(unsigned int which_input);
365
366 /*!
367 * \brief Return the number of items written on output stream which_output
368 */
369 uint64_t nitems_written(unsigned int which_output);
370
371 /*!
372 * \brief Asks for the policy used by the scheduler to moved tags downstream.
373 */
374 tag_propagation_policy_t tag_propagation_policy();
375
376 /*!
377 * \brief Set the policy by the scheduler to determine how tags are moved downstream.
378 */
379 void set_tag_propagation_policy(tag_propagation_policy_t p);
380
381 /*!
382 * \brief Return the minimum number of output items this block can
383 * produce during a call to work.
384 *
385 * Should be 0 for most blocks. Useful if we're dealing with
386 * packets and the block produces one packet per call to work.
387 */
min_noutput_items()388 int min_noutput_items() const { return d_min_noutput_items; }
389
390 /*!
391 * \brief Set the minimum number of output items this block can
392 * produce during a call to work.
393 *
394 * \param m the minimum noutput_items this block can produce.
395 */
set_min_noutput_items(int m)396 void set_min_noutput_items(int m) { d_min_noutput_items = m; }
397
398 /*!
399 * \brief Return the maximum number of output items this block will
400 * handle during a call to work.
401 */
402 int max_noutput_items();
403
404 /*!
405 * \brief Set the maximum number of output items this block will
406 * handle during a call to work.
407 *
408 * \param m the maximum noutput_items this block will handle.
409 */
410 void set_max_noutput_items(int m);
411
412 /*!
413 * \brief Clear the switch for using the max_noutput_items value of this block.
414 *
415 * When is_set_max_noutput_items() returns 'true', the scheduler
416 * will use the value returned by max_noutput_items() to limit the
417 * size of the number of items possible for this block's work
418 * function. If is_set_max_notput_items() returns 'false', then
419 * the scheduler ignores the internal value and uses the value set
420 * globally in the top_block.
421 *
422 * Use this value to clear the 'is_set' flag so the scheduler will
423 * ignore this. Use the set_max_noutput_items(m) call to both set
424 * a new value for max_noutput_items and to re-enable its use in
425 * the scheduler.
426 */
427 void unset_max_noutput_items();
428
429 /*!
430 * \brief Ask the block if the flag is or is not set to use the
431 * internal value of max_noutput_items during a call to work.
432 */
433 bool is_set_max_noutput_items();
434
435 /*
436 * Used to expand the vectors that hold the min/max buffer sizes.
437 *
438 * Specifically, when -1 is used, the vectors are just initialized
439 * with 1 value; this is used by the flat_flowgraph to expand when
440 * required to add a new value for new ports on these blocks.
441 */
442 void expand_minmax_buffer(int port);
443
444 /*!
445 * \brief Returns max buffer size on output port \p i.
446 */
447 long max_output_buffer(size_t i);
448
449 /*!
450 * \brief Request limit on max buffer size on all output ports.
451 *
452 * \details
453 * This is an advanced feature. Calling this can affect some
454 * fundamental assumptions about the system behavior and
455 * performance.
456 *
457 * The actual buffer size is determined by a number of other
458 * factors from the block and system. This function only provides
459 * a requested maximum. The buffers will always be a multiple of
460 * the system page size, which may be larger than the value asked
461 * for here.
462 *
463 * \param max_output_buffer the requested maximum output size in items.
464 */
465 void set_max_output_buffer(long max_output_buffer);
466
467 /*!
468 * \brief Request limit on max buffer size on output port \p port.
469 *
470 * \details
471 * This is an advanced feature. Calling this can affect some
472 * fundamental assumptions about the system behavior and
473 * performance.
474 *
475 * The actual buffer size is determined by a number of other
476 * factors from the block and system. This function only provides
477 * a requested maximum. The buffers will always be a multiple of
478 * the system page size, which may be larger than the value asked
479 * for here.
480 *
481 * \param port the output port the request applies to.
482 * \param max_output_buffer the requested maximum output size in items.
483 */
484 void set_max_output_buffer(int port, long max_output_buffer);
485
486 /*!
487 * \brief Returns min buffer size on output port \p i.
488 */
489 long min_output_buffer(size_t i);
490
491 /*!
492 * \brief Request limit on the minimum buffer size on all output
493 * ports.
494 *
495 * \details
496 * This is an advanced feature. Calling this can affect some
497 * fundamental assumptions about the system behavior and
498 * performance.
499 *
500 * The actual buffer size is determined by a number of other
501 * factors from the block and system. This function only provides
502 * a requested minimum. The buffers will always be a multiple of
503 * the system page size, which may be larger than the value asked
504 * for here.
505 *
506 * \param min_output_buffer the requested minimum output size in items.
507 */
508 void set_min_output_buffer(long min_output_buffer);
509
510 /*!
511 * \brief Request limit on min buffer size on output port \p port.
512 *
513 * \details
514 * This is an advanced feature. Calling this can affect some
515 * fundamental assumptions about the system behavior and
516 * performance.
517 *
518 * The actual buffer size is determined by a number of other
519 * factors from the block and system. This function only provides
520 * a requested minimum. The buffers will always be a multiple of
521 * the system page size, which may be larger than the value asked
522 * for here.
523 *
524 * \param port the output port the request applies to.
525 * \param min_output_buffer the requested minimum output size in items.
526 */
527 void set_min_output_buffer(int port, long min_output_buffer);
528
529 // --------------- Performance counter functions -------------
530
531 /*!
532 * \brief Gets instantaneous noutput_items performance counter.
533 */
534 float pc_noutput_items();
535
536 /*!
537 * \brief Gets average noutput_items performance counter.
538 */
539 float pc_noutput_items_avg();
540
541 /*!
542 * \brief Gets variance of noutput_items performance counter.
543 */
544 float pc_noutput_items_var();
545
546 /*!
547 * \brief Gets instantaneous num items produced performance counter.
548 */
549 float pc_nproduced();
550
551 /*!
552 * \brief Gets average num items produced performance counter.
553 */
554 float pc_nproduced_avg();
555
556 /*!
557 * \brief Gets variance of num items produced performance counter.
558 */
559 float pc_nproduced_var();
560
561 /*!
562 * \brief Gets instantaneous fullness of \p which input buffer.
563 */
564 float pc_input_buffers_full(int which);
565
566 /*!
567 * \brief Gets average fullness of \p which input buffer.
568 */
569 float pc_input_buffers_full_avg(int which);
570
571 /*!
572 * \brief Gets variance of fullness of \p which input buffer.
573 */
574 float pc_input_buffers_full_var(int which);
575
576 /*!
577 * \brief Gets instantaneous fullness of all input buffers.
578 */
579 std::vector<float> pc_input_buffers_full();
580
581 /*!
582 * \brief Gets average fullness of all input buffers.
583 */
584 std::vector<float> pc_input_buffers_full_avg();
585
586 /*!
587 * \brief Gets variance of fullness of all input buffers.
588 */
589 std::vector<float> pc_input_buffers_full_var();
590
591 /*!
592 * \brief Gets instantaneous fullness of \p which output buffer.
593 */
594 float pc_output_buffers_full(int which);
595
596 /*!
597 * \brief Gets average fullness of \p which output buffer.
598 */
599 float pc_output_buffers_full_avg(int which);
600
601 /*!
602 * \brief Gets variance of fullness of \p which output buffer.
603 */
604 float pc_output_buffers_full_var(int which);
605
606 /*!
607 * \brief Gets instantaneous fullness of all output buffers.
608 */
609 std::vector<float> pc_output_buffers_full();
610
611 /*!
612 * \brief Gets average fullness of all output buffers.
613 */
614 std::vector<float> pc_output_buffers_full_avg();
615
616 /*!
617 * \brief Gets variance of fullness of all output buffers.
618 */
619 std::vector<float> pc_output_buffers_full_var();
620
621 /*!
622 * \brief Gets instantaneous clock cycles spent in work.
623 */
624 float pc_work_time();
625
626 /*!
627 * \brief Gets average clock cycles spent in work.
628 */
629 float pc_work_time_avg();
630
631 /*!
632 * \brief Gets average clock cycles spent in work.
633 */
634 float pc_work_time_var();
635
636 /*!
637 * \brief Gets total clock cycles spent in work.
638 */
639 float pc_work_time_total();
640
641 /*!
642 * \brief Gets average throughput.
643 */
644 float pc_throughput_avg();
645
646 /*!
647 * \brief Resets the performance counters
648 */
649 void reset_perf_counters();
650
651 /*!
652 * \brief Sets up export of perf. counters to ControlPort. Only
653 * called by the scheduler.
654 */
655 void setup_pc_rpc();
656
657 /*!
658 * \brief Checks if this block is already exporting perf. counters
659 * to ControlPort.
660 */
is_pc_rpc_set()661 bool is_pc_rpc_set() { return d_pc_rpc_set; }
662
663 /*!
664 * \brief If the block calls this in its constructor, it's
665 * perf. counters will not be exported.
666 */
no_pc_rpc()667 void no_pc_rpc() { d_pc_rpc_set = true; }
668
669
670 // ----------------------------------------------------------------------------
671 // Functions to handle thread affinity
672
673 /*!
674 * \brief Set the thread's affinity to processor core \p n.
675 *
676 * \param mask a vector of ints of the core numbers available to this block.
677 */
678 void set_processor_affinity(const std::vector<int>& mask);
679
680 /*!
681 * \brief Remove processor affinity to a specific core.
682 */
683 void unset_processor_affinity();
684
685 /*!
686 * \brief Get the current processor affinity.
687 */
processor_affinity()688 std::vector<int> processor_affinity() { return d_affinity; }
689
690 /*!
691 * \brief Get the current thread priority in use
692 */
693 int active_thread_priority();
694
695 /*!
696 * \brief Get the current thread priority stored
697 */
698 int thread_priority();
699
700 /*!
701 * \brief Set the current thread priority
702 */
703 int set_thread_priority(int priority);
704
705 bool update_rate() const;
706
707 // ----------------------------------------------------------------------------
708
709 /*!
710 * \brief the system message handler
711 */
712 void system_handler(pmt::pmt_t msg);
713
714 /*!
715 * \brief Set the logger's output level.
716 *
717 * Sets the level of the logger. This takes a string that is
718 * translated to the standard levels and can be (case insensitive):
719 *
720 * \li off , notset
721 * \li debug
722 * \li info
723 * \li notice
724 * \li warn
725 * \li error
726 * \li crit
727 * \li alert
728 * \li fatal
729 * \li emerg
730 */
731 void set_log_level(std::string level);
732
733 /*!
734 * \brief Get the logger's output level
735 */
736 std::string log_level();
737
738 /*!
739 * \brief returns true when execution has completed due to a message connection
740 */
741 bool finished();
742
743 private:
744 int d_output_multiple;
745 bool d_output_multiple_set;
746 int d_unaligned;
747 bool d_is_unaligned;
748 double d_relative_rate; // approx output_rate / input_rate
749 mpq_class d_mp_relative_rate;
750 block_detail_sptr d_detail; // implementation details
751 unsigned d_history;
752 unsigned d_attr_delay; // the block's sample delay
753 bool d_fixed_rate;
754 bool d_max_noutput_items_set; // if d_max_noutput_items is valid
755 int d_max_noutput_items; // value of max_noutput_items for this block
756 int d_min_noutput_items;
757 tag_propagation_policy_t
758 d_tag_propagation_policy; // policy for moving tags downstream
759 std::vector<int> d_affinity; // thread affinity proc. mask
760 int d_priority; // thread priority level
761 bool d_pc_rpc_set;
762 bool d_update_rate; // should sched update rel rate?
763 bool d_finished; // true if msg ports think we are finished
764
765 protected:
block(void)766 block(void) {} // allows pure virtual interface sub-classes
767 block(const std::string& name,
768 gr::io_signature::sptr input_signature,
769 gr::io_signature::sptr output_signature);
770
set_fixed_rate(bool fixed_rate)771 void set_fixed_rate(bool fixed_rate) { d_fixed_rate = fixed_rate; }
772
773 /*!
774 * \brief Adds a new tag onto the given output buffer.
775 *
776 * \param which_output an integer of which output stream to attach the tag
777 * \param abs_offset a uint64 number of the absolute item number
778 * assicated with the tag. Can get from nitems_written.
779 * \param key the tag key as a PMT symbol
780 * \param value any PMT holding any value for the given key
781 * \param srcid optional source ID specifier; defaults to PMT_F
782 */
783 inline void add_item_tag(unsigned int which_output,
784 uint64_t abs_offset,
785 const pmt::pmt_t& key,
786 const pmt::pmt_t& value,
787 const pmt::pmt_t& srcid = pmt::PMT_F)
788 {
789 tag_t tag;
790 tag.offset = abs_offset;
791 tag.key = key;
792 tag.value = value;
793 tag.srcid = srcid;
794 this->add_item_tag(which_output, tag);
795 }
796
797 /*!
798 * \brief Adds a new tag onto the given output buffer.
799 *
800 * \param which_output an integer of which output stream to attach the tag
801 * \param tag the tag object to add
802 */
803 void add_item_tag(unsigned int which_output, const tag_t& tag);
804
805 /*!
806 * \brief DEPRECATED. Will be removed in 3.8.
807 *
808 * \param which_input an integer of which input stream to remove the tag from
809 * \param abs_offset a uint64 number of the absolute item number
810 * assicated with the tag. Can get from nitems_written.
811 * \param key the tag key as a PMT symbol
812 * \param value any PMT holding any value for the given key
813 * \param srcid optional source ID specifier; defaults to PMT_F
814 *
815 * If no such tag is found, does nothing.
816 */
817 inline void remove_item_tag(unsigned int which_input,
818 uint64_t abs_offset,
819 const pmt::pmt_t& key,
820 const pmt::pmt_t& value,
821 const pmt::pmt_t& srcid = pmt::PMT_F)
822 {
823 tag_t tag;
824 tag.offset = abs_offset;
825 tag.key = key;
826 tag.value = value;
827 tag.srcid = srcid;
828 this->remove_item_tag(which_input, tag);
829 }
830
831 /*!
832 * \brief DEPRECATED. Will be removed in 3.8.
833 *
834 * \param which_input an integer of which input stream to remove the tag from
835 * \param tag the tag object to remove
836 */
837 void remove_item_tag(unsigned int which_input, const tag_t& tag);
838
839 /*!
840 * \brief Given a [start,end), returns a vector of all tags in the range.
841 *
842 * Range of counts is from start to end-1.
843 *
844 * Tags are tuples of:
845 * (item count, source id, key, value)
846 *
847 * \param v a vector reference to return tags into
848 * \param which_input an integer of which input stream to pull from
849 * \param abs_start a uint64 count of the start of the range of interest
850 * \param abs_end a uint64 count of the end of the range of interest
851 */
852 void get_tags_in_range(std::vector<tag_t>& v,
853 unsigned int which_input,
854 uint64_t abs_start,
855 uint64_t abs_end);
856
857 /*!
858 * \brief Given a [start,end), returns a vector of all tags in the
859 * range with a given key.
860 *
861 * Range of counts is from start to end-1.
862 *
863 * Tags are tuples of:
864 * (item count, source id, key, value)
865 *
866 * \param v a vector reference to return tags into
867 * \param which_input an integer of which input stream to pull from
868 * \param abs_start a uint64 count of the start of the range of interest
869 * \param abs_end a uint64 count of the end of the range of interest
870 * \param key a PMT symbol key to filter only tags of this key
871 */
872 void get_tags_in_range(std::vector<tag_t>& v,
873 unsigned int which_input,
874 uint64_t abs_start,
875 uint64_t abs_end,
876 const pmt::pmt_t& key);
877
878 /*!
879 * \brief Gets all tags within the relative window of the current call to work.
880 *
881 * \details
882 *
883 * This opperates much like get_tags_in_range but allows us to
884 * work within the current window of items. Item range is
885 * therefore within the possible range of 0 to
886 * ninput_items[whic_input].
887 *
888 * Range of items counts from \p rel_start to \p rel_end-1 within
889 * current window.
890 *
891 * Tags are tuples of:
892 * (item count, source id, key, value)
893 *
894 * \param v a vector reference to return tags into
895 * \param which_input an integer of which input stream to pull from
896 * \param rel_start a uint64 count of the start of the range of interest
897 * \param rel_end a uint64 count of the end of the range of interest
898 */
899 void get_tags_in_window(std::vector<tag_t>& v,
900 unsigned int which_input,
901 uint64_t rel_start,
902 uint64_t rel_end);
903
904 /*!
905 * \brief Operates like gr::block::get_tags_in_window with the
906 * ability to only return tags with the specified \p key.
907 *
908 * \details
909 *
910 * \param v a vector reference to return tags into
911 * \param which_input an integer of which input stream to pull from
912 * \param rel_start a uint64 count of the start of the range of interest
913 * \param rel_end a uint64 count of the end of the range of interest
914 * \param key a PMT symbol key to filter only tags of this key
915 */
916 void get_tags_in_window(std::vector<tag_t>& v,
917 unsigned int which_input,
918 uint64_t rel_start,
919 uint64_t rel_end,
920 const pmt::pmt_t& key);
921
922 void enable_update_rate(bool en);
923
924 std::vector<long> d_max_output_buffer;
925 std::vector<long> d_min_output_buffer;
926
927 /*! Used by block's setters and work functions to make
928 * setting/resetting of parameters thread-safe.
929 *
930 * Used by calling gr::thread::scoped_lock l(d_setlock);
931 */
932 gr::thread::mutex d_setlock;
933
934 /*! Used by blocks to access the logger system.
935 */
936 gr::logger_ptr d_logger;
937 gr::logger_ptr d_debug_logger;
938
939 // These are really only for internal use, but leaving them public avoids
940 // having to work up an ever-varying list of friend GR_RUNTIME_APIs
941
942 /*! PMT Symbol for "hey, we're done here"
943 */
944 const pmt::pmt_t d_pmt_done;
945
946 /*! PMT Symbol of the system port, `pmt::mp("system")`
947 */
948 const pmt::pmt_t d_system_port;
949
950 public:
detail()951 block_detail_sptr detail() const { return d_detail; }
set_detail(block_detail_sptr detail)952 void set_detail(block_detail_sptr detail) { d_detail = detail; }
953
954 /*! \brief Tell msg neighbors we are finished
955 */
956 void notify_msg_neighbors();
957
958 /*! \brief Make sure we don't think we are finished
959 */
clear_finished()960 void clear_finished() { d_finished = false; }
961
962 std::string identifier() const;
963 };
964
965 typedef std::vector<block_sptr> block_vector_t;
966 typedef std::vector<block_sptr>::iterator block_viter_t;
967
cast_to_block_sptr(basic_block_sptr p)968 inline block_sptr cast_to_block_sptr(basic_block_sptr p)
969 {
970 return boost::dynamic_pointer_cast<block, basic_block>(p);
971 }
972
973 GR_RUNTIME_API std::ostream& operator<<(std::ostream& os, const block* m);
974
975 } /* namespace gr */
976
977 #endif /* INCLUDED_GR_RUNTIME_BLOCK_H */
978