1 /* -*- c++ -*- */
2 /*
3 * Copyright 2004,2009,2010,2013 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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gnuradio/block.h>
28 #include <gnuradio/block_detail.h>
29 #include <gnuradio/block_registry.h>
30 #include <gnuradio/buffer.h>
31 #include <gnuradio/prefs.h>
32 #include <iostream>
33 #include <stdexcept>
34
35 namespace gr {
36
block(const std::string & name,io_signature::sptr input_signature,io_signature::sptr output_signature)37 block::block(const std::string& name,
38 io_signature::sptr input_signature,
39 io_signature::sptr output_signature)
40 : basic_block(name, input_signature, output_signature),
41 d_output_multiple(1),
42 d_output_multiple_set(false),
43 d_unaligned(0),
44 d_is_unaligned(false),
45 d_relative_rate(1.0),
46 d_mp_relative_rate(1.0),
47 d_history(1),
48 d_attr_delay(0),
49 d_fixed_rate(false),
50 d_max_noutput_items_set(false),
51 d_max_noutput_items(0),
52 d_min_noutput_items(0),
53 d_tag_propagation_policy(TPP_ALL_TO_ALL),
54 d_priority(-1),
55 d_pc_rpc_set(false),
56 d_update_rate(false),
57 d_max_output_buffer(std::max(output_signature->max_streams(), 1), -1),
58 d_min_output_buffer(std::max(output_signature->max_streams(), 1), -1),
59 d_pmt_done(pmt::intern("done")),
60 d_system_port(pmt::intern("system"))
61 {
62 global_block_registry.register_primitive(d_symbol_name, this);
63 message_port_register_in(d_system_port);
64 configure_default_loggers(d_logger, d_debug_logger, symbol_name());
65 set_msg_handler(d_system_port, [this](pmt::pmt_t msg) { this->system_handler(msg); });
66 }
67
~block()68 block::~block() { global_block_registry.unregister_primitive(symbol_name()); }
69
history() const70 unsigned block::history() const { return d_history; }
71
set_history(unsigned history)72 void block::set_history(unsigned history) { d_history = history; }
73
declare_sample_delay(unsigned delay)74 void block::declare_sample_delay(unsigned delay)
75 {
76 d_attr_delay = delay;
77 if (d_detail) {
78 unsigned int nins = static_cast<unsigned int>(d_detail->ninputs());
79 for (unsigned int n = 0; n < nins; n++) {
80 d_detail->input(n)->declare_sample_delay(d_attr_delay);
81 }
82 }
83 }
84
declare_sample_delay(int which,unsigned delay)85 void block::declare_sample_delay(int which, unsigned delay)
86 {
87 d_attr_delay = delay;
88 if (d_detail) {
89 d_detail->input(which)->declare_sample_delay(d_attr_delay);
90 }
91 }
92
sample_delay(int which) const93 unsigned block::sample_delay(int which) const { return d_attr_delay; }
94
95 // stub implementation: 1:1
96
forecast(int noutput_items,gr_vector_int & ninput_items_required)97 void block::forecast(int noutput_items, gr_vector_int& ninput_items_required)
98 {
99 unsigned ninputs = ninput_items_required.size();
100 for (unsigned i = 0; i < ninputs; i++)
101 ninput_items_required[i] = noutput_items + history() - 1;
102 }
103
104 // default implementation
105
start()106 bool block::start() { return true; }
107
stop()108 bool block::stop() { return true; }
109
set_output_multiple(int multiple)110 void block::set_output_multiple(int multiple)
111 {
112 if (multiple < 1)
113 throw std::invalid_argument("block::set_output_multiple");
114
115 d_output_multiple_set = true;
116 d_output_multiple = multiple;
117 }
118
set_alignment(int multiple)119 void block::set_alignment(int multiple)
120 {
121 if (multiple < 1)
122 throw std::invalid_argument("block::set_alignment_multiple");
123
124 d_output_multiple = multiple;
125 }
126
set_unaligned(int na)127 void block::set_unaligned(int na)
128 {
129 // unaligned value must be less than 0 and it doesn't make sense
130 // that it's larger than the alignment value.
131 if ((na < 0) || (na > d_output_multiple))
132 throw std::invalid_argument("block::set_unaligned");
133
134 d_unaligned = na;
135 }
136
set_is_unaligned(bool u)137 void block::set_is_unaligned(bool u) { d_is_unaligned = u; }
138
set_relative_rate(double relative_rate)139 void block::set_relative_rate(double relative_rate)
140 {
141 if (relative_rate <= 0.0)
142 throw std::invalid_argument(
143 "block::set_relative_rate: relative rate must be > 0.0");
144
145 d_relative_rate = relative_rate;
146 d_mp_relative_rate = mpq_class(relative_rate);
147 }
148
set_inverse_relative_rate(double inverse_relative_rate)149 void block::set_inverse_relative_rate(double inverse_relative_rate)
150 {
151 if (inverse_relative_rate <= 0.0)
152 throw std::invalid_argument(
153 "block::set_inverse_relative_rate: inverse relative rate must be > 0.0");
154
155 mpq_class inv_rr_q(inverse_relative_rate);
156 set_relative_rate((uint64_t)inv_rr_q.get_den().get_ui(),
157 (uint64_t)inv_rr_q.get_num().get_ui());
158 }
159
set_relative_rate(uint64_t interpolation,uint64_t decimation)160 void block::set_relative_rate(uint64_t interpolation, uint64_t decimation)
161 {
162 mpz_class interp, decim;
163 if (interpolation < 1)
164 throw std::invalid_argument(
165 "block::set_relative_rate: interpolation rate cannot be 0");
166
167 if (decimation < 1)
168 throw std::invalid_argument(
169 "block::set_relative_rate: decimation rate cannot be 0");
170
171 mpz_import(interp.get_mpz_t(), 1, 1, sizeof(interpolation), 0, 0, &interpolation);
172 mpz_import(decim.get_mpz_t(), 1, 1, sizeof(decimation), 0, 0, &decimation);
173 d_mp_relative_rate = mpq_class(interp, decim);
174 d_mp_relative_rate.canonicalize();
175 d_relative_rate = d_mp_relative_rate.get_d();
176 }
177
consume(int which_input,int how_many_items)178 void block::consume(int which_input, int how_many_items)
179 {
180 d_detail->consume(which_input, how_many_items);
181 }
182
consume_each(int how_many_items)183 void block::consume_each(int how_many_items) { d_detail->consume_each(how_many_items); }
184
produce(int which_output,int how_many_items)185 void block::produce(int which_output, int how_many_items)
186 {
187 d_detail->produce(which_output, how_many_items);
188 }
189
fixed_rate_ninput_to_noutput(int ninput)190 int block::fixed_rate_ninput_to_noutput(int ninput)
191 {
192 throw std::runtime_error("Unimplemented");
193 }
194
fixed_rate_noutput_to_ninput(int noutput)195 int block::fixed_rate_noutput_to_ninput(int noutput)
196 {
197 throw std::runtime_error("Unimplemented");
198 }
199
nitems_read(unsigned int which_input)200 uint64_t block::nitems_read(unsigned int which_input)
201 {
202 if (d_detail) {
203 return d_detail->nitems_read(which_input);
204 } else {
205 // throw std::runtime_error("No block_detail associated with block yet");
206 return 0;
207 }
208 }
209
nitems_written(unsigned int which_output)210 uint64_t block::nitems_written(unsigned int which_output)
211 {
212 if (d_detail) {
213 return d_detail->nitems_written(which_output);
214 } else {
215 // throw std::runtime_error("No block_detail associated with block yet");
216 return 0;
217 }
218 }
219
add_item_tag(unsigned int which_output,const tag_t & tag)220 void block::add_item_tag(unsigned int which_output, const tag_t& tag)
221 {
222 d_detail->add_item_tag(which_output, tag);
223 }
224
remove_item_tag(unsigned int which_input,const tag_t & tag)225 void block::remove_item_tag(unsigned int which_input, const tag_t& tag)
226 {
227 d_detail->remove_item_tag(which_input, tag, unique_id());
228 }
229
get_tags_in_range(std::vector<tag_t> & v,unsigned int which_input,uint64_t start,uint64_t end)230 void block::get_tags_in_range(std::vector<tag_t>& v,
231 unsigned int which_input,
232 uint64_t start,
233 uint64_t end)
234 {
235 d_detail->get_tags_in_range(v, which_input, start, end, unique_id());
236 }
237
get_tags_in_range(std::vector<tag_t> & v,unsigned int which_input,uint64_t start,uint64_t end,const pmt::pmt_t & key)238 void block::get_tags_in_range(std::vector<tag_t>& v,
239 unsigned int which_input,
240 uint64_t start,
241 uint64_t end,
242 const pmt::pmt_t& key)
243 {
244 d_detail->get_tags_in_range(v, which_input, start, end, key, unique_id());
245 }
246
get_tags_in_window(std::vector<tag_t> & v,unsigned int which_input,uint64_t start,uint64_t end)247 void block::get_tags_in_window(std::vector<tag_t>& v,
248 unsigned int which_input,
249 uint64_t start,
250 uint64_t end)
251 {
252 d_detail->get_tags_in_range(v,
253 which_input,
254 nitems_read(which_input) + start,
255 nitems_read(which_input) + end,
256 unique_id());
257 }
258
get_tags_in_window(std::vector<tag_t> & v,unsigned int which_input,uint64_t start,uint64_t end,const pmt::pmt_t & key)259 void block::get_tags_in_window(std::vector<tag_t>& v,
260 unsigned int which_input,
261 uint64_t start,
262 uint64_t end,
263 const pmt::pmt_t& key)
264 {
265 d_detail->get_tags_in_range(v,
266 which_input,
267 nitems_read(which_input) + start,
268 nitems_read(which_input) + end,
269 key,
270 unique_id());
271 }
272
tag_propagation_policy()273 block::tag_propagation_policy_t block::tag_propagation_policy()
274 {
275 return d_tag_propagation_policy;
276 }
277
set_tag_propagation_policy(tag_propagation_policy_t p)278 void block::set_tag_propagation_policy(tag_propagation_policy_t p)
279 {
280 d_tag_propagation_policy = p;
281 }
282
max_noutput_items()283 int block::max_noutput_items() { return d_max_noutput_items; }
284
set_max_noutput_items(int m)285 void block::set_max_noutput_items(int m)
286 {
287 if (m <= 0)
288 throw std::runtime_error("block::set_max_noutput_items: value for "
289 "max_noutput_items must be greater than 0.\n");
290
291 d_max_noutput_items = m;
292 d_max_noutput_items_set = true;
293 }
294
unset_max_noutput_items()295 void block::unset_max_noutput_items() { d_max_noutput_items_set = false; }
296
is_set_max_noutput_items()297 bool block::is_set_max_noutput_items() { return d_max_noutput_items_set; }
298
set_processor_affinity(const std::vector<int> & mask)299 void block::set_processor_affinity(const std::vector<int>& mask)
300 {
301 d_affinity = mask;
302 if (d_detail) {
303 d_detail->set_processor_affinity(d_affinity);
304 }
305 }
306
unset_processor_affinity()307 void block::unset_processor_affinity()
308 {
309 d_affinity.clear();
310 if (d_detail) {
311 d_detail->unset_processor_affinity();
312 }
313 }
314
active_thread_priority()315 int block::active_thread_priority()
316 {
317 if (d_detail) {
318 return d_detail->thread_priority();
319 }
320 return -1;
321 }
322
thread_priority()323 int block::thread_priority() { return d_priority; }
324
set_thread_priority(int priority)325 int block::set_thread_priority(int priority)
326 {
327 d_priority = priority;
328 if (d_detail) {
329 return d_detail->set_thread_priority(priority);
330 }
331 return d_priority;
332 }
333
expand_minmax_buffer(int port)334 void block::expand_minmax_buffer(int port)
335 {
336 if ((size_t)port >= d_max_output_buffer.size())
337 set_max_output_buffer(port, -1);
338 if ((size_t)port >= d_min_output_buffer.size())
339 set_min_output_buffer(port, -1);
340 }
341
max_output_buffer(size_t i)342 long block::max_output_buffer(size_t i)
343 {
344 if (i >= d_max_output_buffer.size())
345 throw std::invalid_argument("basic_block::max_output_buffer: port out of range.");
346 return d_max_output_buffer[i];
347 }
348
set_max_output_buffer(long max_output_buffer)349 void block::set_max_output_buffer(long max_output_buffer)
350 {
351 for (int i = 0; i < output_signature()->max_streams(); i++) {
352 set_max_output_buffer(i, max_output_buffer);
353 }
354 }
355
set_max_output_buffer(int port,long max_output_buffer)356 void block::set_max_output_buffer(int port, long max_output_buffer)
357 {
358 if ((size_t)port >= d_max_output_buffer.size())
359 d_max_output_buffer.push_back(max_output_buffer);
360 else
361 d_max_output_buffer[port] = max_output_buffer;
362 }
363
min_output_buffer(size_t i)364 long block::min_output_buffer(size_t i)
365 {
366 if (i >= d_min_output_buffer.size())
367 throw std::invalid_argument("basic_block::min_output_buffer: port out of range.");
368 return d_min_output_buffer[i];
369 }
370
set_min_output_buffer(long min_output_buffer)371 void block::set_min_output_buffer(long min_output_buffer)
372 {
373 std::cout << "set_min_output_buffer on block " << unique_id() << " to "
374 << min_output_buffer << std::endl;
375 for (int i = 0; i < output_signature()->max_streams(); i++) {
376 set_min_output_buffer(i, min_output_buffer);
377 }
378 }
379
set_min_output_buffer(int port,long min_output_buffer)380 void block::set_min_output_buffer(int port, long min_output_buffer)
381 {
382 if ((size_t)port >= d_min_output_buffer.size())
383 d_min_output_buffer.push_back(min_output_buffer);
384 else
385 d_min_output_buffer[port] = min_output_buffer;
386 }
387
388
update_rate() const389 bool block::update_rate() const { return d_update_rate; }
390
enable_update_rate(bool en)391 void block::enable_update_rate(bool en) { d_update_rate = en; }
392
pc_noutput_items()393 float block::pc_noutput_items()
394 {
395 if (d_detail) {
396 return d_detail->pc_noutput_items();
397 } else {
398 return 0;
399 }
400 }
401
pc_noutput_items_avg()402 float block::pc_noutput_items_avg()
403 {
404 if (d_detail) {
405 return d_detail->pc_noutput_items_avg();
406 } else {
407 return 0;
408 }
409 }
410
pc_noutput_items_var()411 float block::pc_noutput_items_var()
412 {
413 if (d_detail) {
414 return d_detail->pc_noutput_items_var();
415 } else {
416 return 0;
417 }
418 }
419
pc_nproduced()420 float block::pc_nproduced()
421 {
422 if (d_detail) {
423 return d_detail->pc_nproduced();
424 } else {
425 return 0;
426 }
427 }
428
pc_nproduced_avg()429 float block::pc_nproduced_avg()
430 {
431 if (d_detail) {
432 return d_detail->pc_nproduced_avg();
433 } else {
434 return 0;
435 }
436 }
437
pc_nproduced_var()438 float block::pc_nproduced_var()
439 {
440 if (d_detail) {
441 return d_detail->pc_nproduced_var();
442 } else {
443 return 0;
444 }
445 }
446
pc_input_buffers_full(int which)447 float block::pc_input_buffers_full(int which)
448 {
449 if (d_detail) {
450 return d_detail->pc_input_buffers_full(static_cast<size_t>(which));
451 } else {
452 return 0;
453 }
454 }
455
pc_input_buffers_full_avg(int which)456 float block::pc_input_buffers_full_avg(int which)
457 {
458 if (d_detail) {
459 return d_detail->pc_input_buffers_full_avg(static_cast<size_t>(which));
460 } else {
461 return 0;
462 }
463 }
464
pc_input_buffers_full_var(int which)465 float block::pc_input_buffers_full_var(int which)
466 {
467 if (d_detail) {
468 return d_detail->pc_input_buffers_full_var(static_cast<size_t>(which));
469 } else {
470 return 0;
471 }
472 }
473
pc_input_buffers_full()474 std::vector<float> block::pc_input_buffers_full()
475 {
476 if (d_detail) {
477 return d_detail->pc_input_buffers_full();
478 } else {
479 return std::vector<float>(1, 0);
480 }
481 }
482
pc_input_buffers_full_avg()483 std::vector<float> block::pc_input_buffers_full_avg()
484 {
485 if (d_detail) {
486 return d_detail->pc_input_buffers_full_avg();
487 } else {
488 return std::vector<float>(1, 0);
489 }
490 }
491
pc_input_buffers_full_var()492 std::vector<float> block::pc_input_buffers_full_var()
493 {
494 if (d_detail) {
495 return d_detail->pc_input_buffers_full_var();
496 } else {
497 return std::vector<float>(1, 0);
498 }
499 }
500
pc_output_buffers_full(int which)501 float block::pc_output_buffers_full(int which)
502 {
503 if (d_detail) {
504 return d_detail->pc_output_buffers_full(static_cast<size_t>(which));
505 } else {
506 return 0;
507 }
508 }
509
pc_output_buffers_full_avg(int which)510 float block::pc_output_buffers_full_avg(int which)
511 {
512 if (d_detail) {
513 return d_detail->pc_output_buffers_full_avg(static_cast<size_t>(which));
514 } else {
515 return 0;
516 }
517 }
518
pc_output_buffers_full_var(int which)519 float block::pc_output_buffers_full_var(int which)
520 {
521 if (d_detail) {
522 return d_detail->pc_output_buffers_full_var(static_cast<size_t>(which));
523 } else {
524 return 0;
525 }
526 }
527
pc_output_buffers_full()528 std::vector<float> block::pc_output_buffers_full()
529 {
530 if (d_detail) {
531 return d_detail->pc_output_buffers_full();
532 } else {
533 return std::vector<float>(1, 0);
534 }
535 }
536
pc_output_buffers_full_avg()537 std::vector<float> block::pc_output_buffers_full_avg()
538 {
539 if (d_detail) {
540 return d_detail->pc_output_buffers_full_avg();
541 } else {
542 return std::vector<float>(1, 0);
543 }
544 }
545
pc_output_buffers_full_var()546 std::vector<float> block::pc_output_buffers_full_var()
547 {
548 if (d_detail) {
549 return d_detail->pc_output_buffers_full_var();
550 } else {
551 return std::vector<float>(1, 0);
552 }
553 }
554
pc_work_time()555 float block::pc_work_time()
556 {
557 if (d_detail) {
558 return d_detail->pc_work_time();
559 } else {
560 return 0;
561 }
562 }
563
pc_work_time_avg()564 float block::pc_work_time_avg()
565 {
566 if (d_detail) {
567 return d_detail->pc_work_time_avg();
568 } else {
569 return 0;
570 }
571 }
572
pc_work_time_var()573 float block::pc_work_time_var()
574 {
575 if (d_detail) {
576 return d_detail->pc_work_time_var();
577 } else {
578 return 0;
579 }
580 }
581
pc_work_time_total()582 float block::pc_work_time_total()
583 {
584 if (d_detail) {
585 return d_detail->pc_work_time_total();
586 } else {
587 return 0;
588 }
589 }
590
pc_throughput_avg()591 float block::pc_throughput_avg()
592 {
593 if (d_detail) {
594 return d_detail->pc_throughput_avg();
595 } else {
596 return 0;
597 }
598 }
599
reset_perf_counters()600 void block::reset_perf_counters()
601 {
602 if (d_detail) {
603 d_detail->reset_perf_counters();
604 }
605 }
606
607
system_handler(pmt::pmt_t msg)608 void block::system_handler(pmt::pmt_t msg)
609 {
610 // std::cout << "system_handler " << msg << "\n";
611 pmt::pmt_t op = pmt::car(msg);
612 if (pmt::eqv(op, d_pmt_done)) {
613 d_finished = pmt::to_long(pmt::cdr(msg));
614 global_block_registry.notify_blk(d_symbol_name);
615 } else {
616 std::cout << "WARNING: bad message op on system port!\n";
617 pmt::print(msg);
618 }
619 }
620
set_log_level(std::string level)621 void block::set_log_level(std::string level) { logger_set_level(d_logger, level); }
622
log_level()623 std::string block::log_level()
624 {
625 std::string level;
626 logger_get_level(d_logger, level);
627 return level;
628 }
629
notify_msg_neighbors()630 void block::notify_msg_neighbors()
631 {
632 size_t len = pmt::length(d_message_subscribers);
633 pmt::pmt_t port_names = pmt::make_vector(len, pmt::PMT_NIL);
634 pmt::pmt_t keys = pmt::dict_keys(d_message_subscribers);
635 for (size_t i = 0; i < len; i++) {
636 // for each output port
637 pmt::pmt_t oport = pmt::nth(i, keys);
638
639 // for each subscriber on this port
640 pmt::pmt_t currlist = pmt::dict_ref(d_message_subscribers, oport, pmt::PMT_NIL);
641
642 // iterate through subscribers on port
643 while (pmt::is_pair(currlist)) {
644 pmt::pmt_t target = pmt::car(currlist);
645
646 pmt::pmt_t block = pmt::car(target);
647
648 currlist = pmt::cdr(currlist);
649 basic_block_sptr blk = global_block_registry.block_lookup(block);
650 blk->post(d_system_port, pmt::cons(d_pmt_done, pmt::mp(true)));
651 }
652 }
653 }
654
finished()655 bool block::finished()
656 {
657 if (detail()->ninputs() != 0)
658 return false;
659 else
660 return d_finished;
661 }
662
663
setup_pc_rpc()664 void block::setup_pc_rpc()
665 {
666 d_pc_rpc_set = true;
667 #if defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS)
668 #include <gnuradio/rpcregisterhelpers.h>
669 d_rpc_vars.emplace_back(
670 new rpcbasic_register_trigger<block>(alias(),
671 "reset_perf_counters",
672 &block::reset_perf_counters,
673 "Reset the Performance Counters",
674 RPC_PRIVLVL_MIN));
675
676 d_rpc_vars.emplace_back(
677 new rpcbasic_register_get<block, float>(alias(),
678 "noutput_items",
679 &block::pc_noutput_items,
680 pmt::mp(0),
681 pmt::mp(32768),
682 pmt::mp(0),
683 "",
684 "noutput items",
685 RPC_PRIVLVL_MIN,
686 DISPTIME | DISPOPTSTRIP));
687
688 d_rpc_vars.emplace_back(
689 new rpcbasic_register_get<block, float>(alias(),
690 "avg noutput_items",
691 &block::pc_noutput_items_avg,
692 pmt::mp(0),
693 pmt::mp(32768),
694 pmt::mp(0),
695 "",
696 "Average noutput items",
697 RPC_PRIVLVL_MIN,
698 DISPTIME | DISPOPTSTRIP));
699
700 d_rpc_vars.emplace_back(
701 new rpcbasic_register_get<block, float>(alias(),
702 "var noutput_items",
703 &block::pc_noutput_items_var,
704 pmt::mp(0),
705 pmt::mp(32768),
706 pmt::mp(0),
707 "",
708 "Var. noutput items",
709 RPC_PRIVLVL_MIN,
710 DISPTIME | DISPOPTSTRIP));
711
712 d_rpc_vars.emplace_back(
713 new rpcbasic_register_get<block, float>(alias(),
714 "nproduced",
715 &block::pc_nproduced,
716 pmt::mp(0),
717 pmt::mp(32768),
718 pmt::mp(0),
719 "",
720 "items produced",
721 RPC_PRIVLVL_MIN,
722 DISPTIME | DISPOPTSTRIP));
723
724 d_rpc_vars.emplace_back(
725 new rpcbasic_register_get<block, float>(alias(),
726 "avg nproduced",
727 &block::pc_nproduced_avg,
728 pmt::mp(0),
729 pmt::mp(32768),
730 pmt::mp(0),
731 "",
732 "Average items produced",
733 RPC_PRIVLVL_MIN,
734 DISPTIME | DISPOPTSTRIP));
735
736 d_rpc_vars.emplace_back(
737 new rpcbasic_register_get<block, float>(alias(),
738 "var nproduced",
739 &block::pc_nproduced_var,
740 pmt::mp(0),
741 pmt::mp(32768),
742 pmt::mp(0),
743 "",
744 "Var. items produced",
745 RPC_PRIVLVL_MIN,
746 DISPTIME | DISPOPTSTRIP));
747
748 d_rpc_vars.emplace_back(
749 new rpcbasic_register_get<block, float>(alias(),
750 "work time",
751 &block::pc_work_time,
752 pmt::mp(0),
753 pmt::mp(1e9),
754 pmt::mp(0),
755 "",
756 "clock cycles in call to work",
757 RPC_PRIVLVL_MIN,
758 DISPTIME | DISPOPTSTRIP));
759
760 d_rpc_vars.emplace_back(
761 new rpcbasic_register_get<block, float>(alias(),
762 "avg work time",
763 &block::pc_work_time_avg,
764 pmt::mp(0),
765 pmt::mp(1e9),
766 pmt::mp(0),
767 "",
768 "Average clock cycles in call to work",
769 RPC_PRIVLVL_MIN,
770 DISPTIME | DISPOPTSTRIP));
771
772 d_rpc_vars.emplace_back(
773 new rpcbasic_register_get<block, float>(alias(),
774 "var work time",
775 &block::pc_work_time_var,
776 pmt::mp(0),
777 pmt::mp(1e9),
778 pmt::mp(0),
779 "",
780 "Var. clock cycles in call to work",
781 RPC_PRIVLVL_MIN,
782 DISPTIME | DISPOPTSTRIP));
783
784 d_rpc_vars.emplace_back(
785 new rpcbasic_register_get<block, float>(alias(),
786 "total work time",
787 &block::pc_work_time_total,
788 pmt::mp(0),
789 pmt::mp(1e9),
790 pmt::mp(0),
791 "",
792 "Total clock cycles in calls to work",
793 RPC_PRIVLVL_MIN,
794 DISPTIME | DISPOPTSTRIP));
795
796 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, float>(
797 alias(),
798 "avg throughput",
799 &block::pc_throughput_avg,
800 pmt::mp(0),
801 pmt::mp(1e9),
802 pmt::mp(0),
803 "items/s",
804 "Average items throughput in call to work",
805 RPC_PRIVLVL_MIN,
806 DISPTIME | DISPOPTSTRIP));
807
808 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
809 alias(),
810 "input \% full",
811 &block::pc_input_buffers_full,
812 pmt::make_f32vector(0, 0),
813 pmt::make_f32vector(0, 1),
814 pmt::make_f32vector(0, 0),
815 "",
816 "how full input buffers are",
817 RPC_PRIVLVL_MIN,
818 DISPTIME | DISPOPTSTRIP));
819
820 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
821 alias(),
822 "avg input \% full",
823 &block::pc_input_buffers_full_avg,
824 pmt::make_f32vector(0, 0),
825 pmt::make_f32vector(0, 1),
826 pmt::make_f32vector(0, 0),
827 "",
828 "Average of how full input buffers are",
829 RPC_PRIVLVL_MIN,
830 DISPTIME | DISPOPTSTRIP));
831
832 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
833 alias(),
834 "var input \% full",
835 &block::pc_input_buffers_full_var,
836 pmt::make_f32vector(0, 0),
837 pmt::make_f32vector(0, 1),
838 pmt::make_f32vector(0, 0),
839 "",
840 "Var. of how full input buffers are",
841 RPC_PRIVLVL_MIN,
842 DISPTIME | DISPOPTSTRIP));
843
844 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
845 alias(),
846 "output \% full",
847 &block::pc_output_buffers_full,
848 pmt::make_f32vector(0, 0),
849 pmt::make_f32vector(0, 1),
850 pmt::make_f32vector(0, 0),
851 "",
852 "how full output buffers are",
853 RPC_PRIVLVL_MIN,
854 DISPTIME | DISPOPTSTRIP));
855
856 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
857 alias(),
858 "avg output \% full",
859 &block::pc_output_buffers_full_avg,
860 pmt::make_f32vector(0, 0),
861 pmt::make_f32vector(0, 1),
862 pmt::make_f32vector(0, 0),
863 "",
864 "Average of how full output buffers are",
865 RPC_PRIVLVL_MIN,
866 DISPTIME | DISPOPTSTRIP));
867
868 d_rpc_vars.emplace_back(new rpcbasic_register_get<block, std::vector<float>>(
869 alias(),
870 "var output \% full",
871 &block::pc_output_buffers_full_var,
872 pmt::make_f32vector(0, 0),
873 pmt::make_f32vector(0, 1),
874 pmt::make_f32vector(0, 0),
875 "",
876 "Var. of how full output buffers are",
877 RPC_PRIVLVL_MIN,
878 DISPTIME | DISPOPTSTRIP));
879 #endif /* defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS) */
880 }
881
identifier() const882 std::string block::identifier() const
883 {
884 return d_name + "(" + std::to_string(d_unique_id) + ")";
885 }
886
operator <<(std::ostream & os,const block * m)887 std::ostream& operator<<(std::ostream& os, const block* m)
888 {
889 os << "<block " << m->identifier() << ">";
890 return os;
891 }
892
general_work(int noutput_items,gr_vector_int & ninput_items,gr_vector_const_void_star & input_items,gr_vector_void_star & output_items)893 int block::general_work(int noutput_items,
894 gr_vector_int& ninput_items,
895 gr_vector_const_void_star& input_items,
896 gr_vector_void_star& output_items)
897 {
898 throw std::runtime_error("block::general_work() not implemented");
899 return 0;
900 }
901
902 } /* namespace gr */
903