summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/lib
diff options
context:
space:
mode:
authorMarcus Müller <marcus@hostalia.de>2018-08-31 23:02:22 +0200
committerMarcus Müller <marcus@hostalia.de>2018-08-31 23:02:22 +0200
commit254fe5e89403d4de1fa6663d09efdf946996aff3 (patch)
tree62877d7ac7fdedf6c397c51e22ac6f97eba97ddf /gnuradio-runtime/lib
parent896d1c9da31963ecf5b0d90942c2af51ca998a69 (diff)
parent5ad935c3a3dd46ce2860b13e2b774e4841784616 (diff)
Merge remote-tracking branch 'origin/next' into merge_next
Diffstat (limited to 'gnuradio-runtime/lib')
-rw-r--r--gnuradio-runtime/lib/CMakeLists.txt27
-rw-r--r--gnuradio-runtime/lib/basic_block.cc23
-rw-r--r--gnuradio-runtime/lib/block.cc22
-rw-r--r--gnuradio-runtime/lib/complex_vec_test.cc82
-rw-r--r--gnuradio-runtime/lib/complex_vec_test.h50
-rw-r--r--gnuradio-runtime/lib/controlport/CMakeLists.txt1
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_selector.cc4
-rw-r--r--gnuradio-runtime/lib/flat_flowgraph.cc233
-rw-r--r--gnuradio-runtime/lib/hier_block2.cc12
-rw-r--r--gnuradio-runtime/lib/hier_block2_detail.cc18
-rw-r--r--gnuradio-runtime/lib/hier_block2_detail.h3
-rw-r--r--gnuradio-runtime/lib/logger.cc46
-rw-r--r--gnuradio-runtime/lib/malloc16.c46
-rw-r--r--gnuradio-runtime/lib/malloc16.h37
-rw-r--r--[-rwxr-xr-x]gnuradio-runtime/lib/math/gen_sine_table.py6
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt.cc16
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt_nco.cc8
-rw-r--r--gnuradio-runtime/lib/math/random.cc8
-rw-r--r--gnuradio-runtime/lib/math/vco.h14
-rw-r--r--gnuradio-runtime/lib/pmt/CMakeLists.txt97
-rw-r--r--gnuradio-runtime/lib/pmt/gen-serial-tags.py53
-rwxr-xr-xgnuradio-runtime/lib/pmt/generate_unv.py162
-rw-r--r--gnuradio-runtime/lib/pmt/pmt-serial-tags.scm77
-rw-r--r--gnuradio-runtime/lib/pmt/pmt.cc8
-rw-r--r--gnuradio-runtime/lib/pmt/pmt_int.h24
-rw-r--r--gnuradio-runtime/lib/pmt/pmt_unv.cc1821
-rw-r--r--gnuradio-runtime/lib/pmt/pmt_unv_int.h331
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt_unv.h61
-rw-r--r--gnuradio-runtime/lib/pmt/unv_template.cc.t149
-rw-r--r--gnuradio-runtime/lib/pmt/unv_template.h.t25
-rw-r--r--gnuradio-runtime/lib/posix_memalign.cc114
-rw-r--r--gnuradio-runtime/lib/posix_memalign.h42
-rw-r--r--gnuradio-runtime/lib/qa_logger.cc2
-rw-r--r--gnuradio-runtime/lib/scheduler_sts.cc90
-rw-r--r--gnuradio-runtime/lib/scheduler_sts.h66
-rw-r--r--gnuradio-runtime/lib/single_threaded_scheduler.cc366
-rw-r--r--gnuradio-runtime/lib/single_threaded_scheduler.h65
-rw-r--r--gnuradio-runtime/lib/sptr_magic.cc2
-rw-r--r--gnuradio-runtime/lib/sys_pri.cc63
-rw-r--r--gnuradio-runtime/lib/thread/thread_group.cc2
-rw-r--r--gnuradio-runtime/lib/top_block_impl.cc4
-rw-r--r--gnuradio-runtime/lib/tpb_thread_body.cc92
42 files changed, 2480 insertions, 1892 deletions
diff --git a/gnuradio-runtime/lib/CMakeLists.txt b/gnuradio-runtime/lib/CMakeLists.txt
index 3482c69d3f..58cd9866fa 100644
--- a/gnuradio-runtime/lib/CMakeLists.txt
+++ b/gnuradio-runtime/lib/CMakeLists.txt
@@ -24,7 +24,7 @@ GR_CHECK_HDR_N_DEF(sys/resource.h HAVE_SYS_RESOURCE_H)
# Handle the generated constants
########################################################################
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
- "import time;print time.strftime('%a, %d %b %Y %H:%M:%S', time.gmtime())"
+ "import time;print(time.strftime('%a, %d %b %Y %H:%M:%S', time.gmtime()))"
OUTPUT_VARIABLE BUILD_DATE OUTPUT_STRIP_TRAILING_WHITESPACE
)
message(STATUS "Loading build date ${BUILD_DATE} into constants...")
@@ -48,8 +48,8 @@ list(APPEND gnuradio_runtime_sources ${CMAKE_CURRENT_BINARY_DIR}/constants.cc)
########################################################################
include_directories(${GNURADIO_RUNTIME_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}/../include/
- ${VOLK_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_BINARY_DIR}/../include/
+ ${VOLK_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${MPLIB_INCLUDE_DIRS}
)
@@ -81,7 +81,6 @@ list(APPEND gnuradio_runtime_sources
block_registry.cc
buffer.cc
circular_file.cc
- complex_vec_test.cc
feval.cc
flat_flowgraph.cc
flowgraph.cc
@@ -91,7 +90,6 @@ list(APPEND gnuradio_runtime_sources
io_signature.cc
local_sighandler.cc
logger.cc
- malloc16.c
message.cc
misc.cc
msg_accepter.cc
@@ -102,9 +100,7 @@ list(APPEND gnuradio_runtime_sources
realtime.cc
realtime_impl.cc
scheduler.cc
- scheduler_sts.cc
scheduler_tpb.cc
- single_threaded_scheduler.cc
sptr_magic.cc
sync_block.cc
sync_decimator.cc
@@ -125,14 +121,6 @@ list(APPEND gnuradio_runtime_sources
${gnuradio_ctrlport_sources}
)
-# PowerPC workaround for posix_memalign
-# Might not be needed, but we'll keep it for now.
-if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
- list(APPEND gnuradio_runtime_sources
- ${CMAKE_CURRENT_SOURCE_DIR}/posix_memalign.cc
- )
-endif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
-
list(APPEND gnuradio_runtime_libs
gnuradio-pmt
${VOLK_LIBRARIES}
@@ -200,12 +188,7 @@ endif(TRY_SHM_VMCIRCBUF)
#######################################################
add_library(gnuradio-runtime SHARED ${gnuradio_runtime_sources})
target_link_libraries(gnuradio-runtime ${gnuradio_runtime_libs})
-GR_LIBRARY_FOO(gnuradio-runtime RUNTIME_COMPONENT "runtime_runtime" DEVEL_COMPONENT "runtime_devel")
-
-add_dependencies(gnuradio-runtime
- pmt_generated runtime_generated_includes
-)
-
+GR_LIBRARY_FOO(gnuradio-runtime)
#######################################################
# STATIC LIB BUILD
@@ -238,7 +221,7 @@ if(ENABLE_STATIC_LIBS)
endif(NOT WIN32)
install(TARGETS gnuradio-runtime_static
- ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "runtime_devel" # .lib file
+ ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file
)
endif(ENABLE_STATIC_LIBS)
diff --git a/gnuradio-runtime/lib/basic_block.cc b/gnuradio-runtime/lib/basic_block.cc
index 082d0753c8..89aa9b8671 100644
--- a/gnuradio-runtime/lib/basic_block.cc
+++ b/gnuradio-runtime/lib/basic_block.cc
@@ -228,29 +228,6 @@ namespace gr {
}
pmt::pmt_t
- basic_block::delete_head_blocking(pmt::pmt_t which_port, unsigned int millisec)
- {
- gr::thread::scoped_lock guard(mutex);
-
- if (millisec) {
- boost::system_time const timeout = boost::get_system_time() + boost::posix_time::milliseconds(millisec);
- while (empty_p(which_port)) {
- if (!msg_queue_ready[which_port]->timed_wait(guard, timeout)) {
- return pmt::pmt_t();
- }
- }
- } else {
- while(empty_p(which_port)) {
- msg_queue_ready[which_port]->wait(guard);
- }
- }
-
- pmt::pmt_t m(msg_queue[which_port].front());
- msg_queue[which_port].pop_front();
- return m;
- }
-
- pmt::pmt_t
basic_block::message_subscribers(pmt::pmt_t port)
{
return pmt::dict_ref(d_message_subscribers,port,pmt::PMT_NIL);
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
index 7d364de32d..c86e792127 100644
--- a/gnuradio-runtime/lib/block.cc
+++ b/gnuradio-runtime/lib/block.cc
@@ -745,6 +745,20 @@ namespace gr {
}
void
+ block::set_log_level(std::string level)
+ {
+ logger_set_level(d_logger, level);
+ }
+
+ std::string
+ block::log_level()
+ {
+ std::string level;
+ logger_get_level(d_logger, level);
+ return level;
+ }
+
+ void
block::notify_msg_neighbors()
{
size_t len = pmt::length(d_message_subscribers);
@@ -773,7 +787,7 @@ namespace gr {
bool
block::finished()
{
- if((detail()->ninputs() != 0) || (detail()->noutputs() != 0))
+ if(detail()->ninputs() != 0)
return false;
else
return d_finished;
@@ -913,10 +927,14 @@ namespace gr {
#endif /* defined(GR_CTRLPORT) && defined(GR_PERFORMANCE_COUNTERS) */
}
+ std::string block::identifier() const {
+ return d_name + "(" + std::to_string(d_unique_id) + ")";
+ }
+
std::ostream&
operator << (std::ostream& os, const block *m)
{
- os << "<block " << m->name() << " (" << m->unique_id() << ")>";
+ os << "<block " << m->identifier() << ">";
return os;
}
diff --git a/gnuradio-runtime/lib/complex_vec_test.cc b/gnuradio-runtime/lib/complex_vec_test.cc
deleted file mode 100644
index 99acc2f355..0000000000
--- a/gnuradio-runtime/lib/complex_vec_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-#include <complex_vec_test.h>
-#include <stddef.h>
-
-std::vector<std::complex<float> >
-complex_vec_test0()
-{
- std::vector<std::complex<float> > r(5);
-
- for (size_t i = 0; i < r.size(); i++)
- r[i] = std::complex<float>(i, i);
-
- return r;
-}
-
-std::vector<std::complex<float> >
-complex_vec_test1(const std::vector<std::complex<float> > &input)
-{
- std::vector<std::complex<float> > r(input.size());
-
- for (size_t i = 0; i < input.size(); i++)
- r[i] = std::complex<float>(input[i].real()+0.5, input[i].imag()-0.5);
-
- return r;
-}
-
-std::complex<float>
-complex_scalar_test0()
-{
- return std::complex<float>(5, 5);
-}
-
-std::complex<float>
-complex_scalar_test1(std::complex<float> input)
-{
- return std::complex<float>(input.real()+0.5, input.imag()-0.5);
-}
-
-
-std::vector<float>
-float_vec_test0()
-{
- std::vector<float> r(5);
-
- for (size_t i = 0; i < r.size(); i++)
- r[i] = (float) i;
-
- return r;
-}
-
-std::vector<float>
-float_vec_test1(const std::vector<float> &input)
-{
- std::vector<float> r(input.size());
-
- for (size_t i = 0; i < input.size(); i++)
- r[i] = input[i] + 0.5;
-
- return r;
-}
-
-std::vector<int>
-int_vec_test0()
-{
- std::vector<int> r(5);
-
- for (size_t i = 0; i < r.size(); i++)
- r[i] = (int) i;
-
- return r;
-}
-
-std::vector<int>
-int_vec_test1(const std::vector<int> &input)
-{
- std::vector<int> r(input.size());
-
- for (size_t i = 0; i < input.size(); i++)
- r[i] = input[i] + 1;
-
- return r;
-}
-
diff --git a/gnuradio-runtime/lib/complex_vec_test.h b/gnuradio-runtime/lib/complex_vec_test.h
deleted file mode 100644
index d69d523374..0000000000
--- a/gnuradio-runtime/lib/complex_vec_test.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2013 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <gnuradio/api.h>
-#include <vector>
-#include <complex>
-
-GR_RUNTIME_API std::vector<std::complex<float> >
-complex_vec_test0();
-
-GR_RUNTIME_API std::vector<std::complex<float> >
-complex_vec_test1(const std::vector<std::complex<float> > &input);
-
-GR_RUNTIME_API std::complex<float>
-complex_scalar_test0();
-
-GR_RUNTIME_API std::complex<float>
-complex_scalar_test1(std::complex<float> input);
-
-GR_RUNTIME_API std::vector<int>
-int_vec_test0();
-
-GR_RUNTIME_API std::vector<int>
-int_vec_test1(const std::vector<int> &input);
-
-GR_RUNTIME_API std::vector<float>
-float_vec_test0();
-
-GR_RUNTIME_API std::vector<float>
-float_vec_test1(const std::vector<float> &input);
-
diff --git a/gnuradio-runtime/lib/controlport/CMakeLists.txt b/gnuradio-runtime/lib/controlport/CMakeLists.txt
index 0d5d0376cc..0aa8539742 100644
--- a/gnuradio-runtime/lib/controlport/CMakeLists.txt
+++ b/gnuradio-runtime/lib/controlport/CMakeLists.txt
@@ -84,7 +84,6 @@ list(APPEND gnuradio_runtime_libs
install(
FILES ${CMAKE_CURRENT_SOURCE_DIR}/thrift/thrift.conf.example
DESTINATION ${SYSCONFDIR}/${CMAKE_PROJECT_NAME}
- COMPONENT "runtime_runtime"
)
endif(THRIFT_FOUND)
diff --git a/gnuradio-runtime/lib/controlport/rpcserver_selector.cc b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
index fcba1ab524..2785513a46 100644
--- a/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
@@ -27,8 +27,8 @@
bool rpcmanager::make_aggregator(false);
bool rpcmanager::booter_registered(false);
bool rpcmanager::aggregator_registered(false);
-std::auto_ptr<rpcserver_booter_base> rpcmanager::boot(0);
-std::auto_ptr<rpcserver_booter_aggregator> rpcmanager::aggregator(0);
+std::unique_ptr<rpcserver_booter_base> rpcmanager::boot;
+std::unique_ptr<rpcserver_booter_aggregator> rpcmanager::aggregator;
#ifdef GR_RPCSERVER_ENABLED
rpcmanager manager_instance;
diff --git a/gnuradio-runtime/lib/flat_flowgraph.cc b/gnuradio-runtime/lib/flat_flowgraph.cc
index b7e949127a..c83ab20769 100644
--- a/gnuradio-runtime/lib/flat_flowgraph.cc
+++ b/gnuradio-runtime/lib/flat_flowgraph.cc
@@ -27,6 +27,7 @@
#include "flat_flowgraph.h"
#include <gnuradio/block_detail.h>
#include <gnuradio/buffer.h>
+#include <gnuradio/logger.h>
#include <gnuradio/prefs.h>
#include <volk/volk.h>
#include <iostream>
@@ -35,8 +36,6 @@
namespace gr {
-#define FLAT_FLOWGRAPH_DEBUG 0
-
// 32Kbyte buffer size between blocks
#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
@@ -77,11 +76,12 @@ namespace gr {
// Connect message ports connetions
for(msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") %
- i->src().block() % i->src().port() %
- i->dst().block() % i->dst().port();
- i->src().block()->message_port_sub(i->src().port(), pmt::cons(i->dst().block()->alias_pmt(), i->dst().port()));
+ GR_LOG_DEBUG(d_debug_logger,
+ boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") %
+ i->src().block() % i->src().port() %
+ i->dst().block() % i->dst().port()
+ );
+ i->src().block()->message_port_sub(i->src().port(), pmt::cons(i->dst().block()->alias_pmt(), i->dst().port()));
}
}
@@ -98,15 +98,13 @@ namespace gr {
(boost::format("allocate_block_detail found non-gr::block (%s)")%
block->alias()).str());
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Creating block detail for " << block << std::endl;
+ GR_LOG_DEBUG(d_debug_logger, "Creating block detail for " + block->identifier());
for(int i = 0; i < noutputs; i++) {
grblock->expand_minmax_buffer(i);
buffer_sptr buffer = allocate_buffer(block, i);
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Allocated buffer for output " << block << ":" << i << std::endl;
+ GR_LOG_DEBUG(d_debug_logger, "Allocated buffer for output " + block->identifier() + " " + std::to_string(i));
detail->set_output(i, buffer);
// Update the block's max_output_buffer based on what was actually allocated.
@@ -210,8 +208,8 @@ namespace gr {
throw std::runtime_error("connect_block_inputs found non-gr::block");
buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Setting input " << dst_port << " from edge " << (*e) << std::endl;
+
+ GR_LOG_DEBUG(d_debug_logger, "Setting input " + std::to_string(dst_port) + " from edge " + (*e).identifier());
detail->set_input(dst_port, buffer_add_reader(src_buffer, grblock->history()-1, grblock,
grblock->sample_delay(src_port)));
@@ -227,89 +225,81 @@ namespace gr {
for(basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
block_sptr block = cast_to_block_sptr(*p);
- if(!block->detail()) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: allocating new detail for block " << (*p) << std::endl;
- block->set_detail(allocate_block_detail(block));
- }
- else {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: reusing original detail for block " << (*p) << std::endl;
+ if (!block->detail()) {
+ GR_LOG_DEBUG(d_debug_logger,
+ "merge: allocating new detail for block " + block->identifier());
+ block->set_detail(allocate_block_detail(block));
+ } else {
+ GR_LOG_DEBUG(d_debug_logger,
+ "merge: reusing original detail for block " + block->identifier());
}
}
// Calculate the old edges that will be going away, and clear the
// buffer readers on the RHS.
- for(edge_viter_t old_edge = old_ffg->d_edges.begin(); old_edge != old_ffg->d_edges.end(); old_edge++) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: testing old edge " << (*old_edge) << "...";
-
- edge_viter_t new_edge;
- for(new_edge = d_edges.begin(); new_edge != d_edges.end(); new_edge++)
- if(new_edge->src() == old_edge->src() &&
- new_edge->dst() == old_edge->dst())
- break;
-
- if(new_edge == d_edges.end()) { // not found in new edge list
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "not in new edge list" << std::endl;
- // zero the buffer reader on RHS of old edge
- block_sptr block(cast_to_block_sptr(old_edge->dst().block()));
- int port = old_edge->dst().port();
- block->detail()->set_input(port, buffer_reader_sptr());
- }
- else {
- if (FLAT_FLOWGRAPH_DEBUG)
- std::cout << "found in new edge list" << std::endl;
- }
+ for (edge_viter_t old_edge = old_ffg->d_edges.begin(); old_edge != old_ffg->d_edges.end();
+ old_edge++) {
+ GR_LOG_DEBUG(d_debug_logger,
+ "merge: testing old edge " + old_edge->identifier() + "...");
+
+ edge_viter_t new_edge;
+ for (new_edge = d_edges.begin(); new_edge != d_edges.end(); new_edge++)
+ if (new_edge->src() == old_edge->src() && new_edge->dst() == old_edge->dst())
+ break;
+
+ if (new_edge == d_edges.end()) { // not found in new edge list
+ GR_LOG_DEBUG(d_debug_logger, "not in new edge list");
+ // zero the buffer reader on RHS of old edge
+ block_sptr block(cast_to_block_sptr(old_edge->dst().block()));
+ int port = old_edge->dst().port();
+ block->detail()->set_input(port, buffer_reader_sptr());
+ } else {
+ GR_LOG_DEBUG(d_debug_logger, "found in new edge list");
+ }
}
// Now connect inputs to outputs, reusing old buffer readers if they exist
for(basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
block_sptr block = cast_to_block_sptr(*p);
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: merging " << (*p) << "...";
-
- if(old_ffg->has_block_p(*p)) {
- // Block exists in old flow graph
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "used in old flow graph" << std::endl;
- block_detail_sptr detail = block->detail();
-
- // Iterate through the inputs and see what needs to be done
- int ninputs = calc_used_ports(block, true).size(); // Might be different now
- for(int i = 0; i < ninputs; i++) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Checking input " << block << ":" << i << "...";
- edge edge = calc_upstream_edge(*p, i);
-
- // Fish out old buffer reader and see if it matches correct buffer from edge list
- block_sptr src_block = cast_to_block_sptr(edge.src().block());
- block_detail_sptr src_detail = src_block->detail();
- buffer_sptr src_buffer = src_detail->output(edge.src().port());
- buffer_reader_sptr old_reader;
- if(i < detail->ninputs()) // Don't exceed what the original detail has
- old_reader = detail->input(i);
-
- // If there's a match, use it
- if(old_reader && (src_buffer == old_reader->buffer())) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "matched, reusing" << std::endl;
- }
- else {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "needs a new reader" << std::endl;
-
- // Create new buffer reader and assign
- detail->set_input(i, buffer_add_reader(src_buffer, block->history()-1, block));
+ GR_LOG_DEBUG(d_debug_logger,
+ "merge: merging " + block->identifier() + "...");
+
+ if (old_ffg->has_block_p(*p)) {
+ // Block exists in old flow graph
+ GR_LOG_DEBUG(d_debug_logger, "used in old flow graph")
+ block_detail_sptr detail = block->detail();
+
+ // Iterate through the inputs and see what needs to be done
+ int ninputs = calc_used_ports(block, true).size(); // Might be different now
+ for (int i = 0; i < ninputs; i++) {
+ GR_LOG_DEBUG(d_debug_logger,
+ "Checking input " + block->identifier() + ":" + std::to_string(i) +
+ "...");
+ edge edge = calc_upstream_edge(*p, i);
+
+ // Fish out old buffer reader and see if it matches correct buffer from edge list
+ block_sptr src_block = cast_to_block_sptr(edge.src().block());
+ block_detail_sptr src_detail = src_block->detail();
+ buffer_sptr src_buffer = src_detail->output(edge.src().port());
+ buffer_reader_sptr old_reader;
+ if (i < detail->ninputs()) // Don't exceed what the original detail has
+ old_reader = detail->input(i);
+
+ // If there's a match, use it
+ if (old_reader && (src_buffer == old_reader->buffer())) {
+ GR_LOG_DEBUG(d_debug_logger, "matched, reusing");
+ } else {
+ GR_LOG_DEBUG(d_debug_logger, "needs a new reader");
+
+ // Create new buffer reader and assign
+ detail->set_input(i, buffer_add_reader(src_buffer, block->history() - 1, block));
+ }
}
- }
}
else {
// Block is new, it just needs buffer readers at this point
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "new block" << std::endl;
+ GR_LOG_DEBUG(d_debug_logger, "new block");
connect_block_inputs(block);
// Make sure all buffers are aligned
@@ -317,12 +307,12 @@ namespace gr {
}
// Connect message ports connetions
- for(msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") %
- i->src().block() % i->src().port() %
- i->dst().block() % i->dst().port();
- i->src().block()->message_port_sub(i->src().port(), pmt::cons(i->dst().block()->alias_pmt(), i->dst().port()));
+ for (msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++) {
+ GR_LOG_DEBUG(d_debug_logger,
+ boost::format("flat_fg connecting msg primitives: (%s, %s)->(%s, %s)\n") %
+ i->src().block() % i->src().port() % i->dst().block() % i->dst().port());
+ i->src().block()->message_port_sub(
+ i->src().port(), pmt::cons(i->dst().block()->alias_pmt(), i->dst().port()));
}
// Now deal with the fact that the block details might have
@@ -439,45 +429,48 @@ namespace gr {
void
flat_flowgraph::clear_hier()
{
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Clear_hier()" << std::endl;
- for(size_t i=0; i<d_msg_edges.size(); i++) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "edge: " << d_msg_edges[i].src() << "-->" << d_msg_edges[i].dst() << std::endl;
- if(d_msg_edges[i].src().is_hier() || d_msg_edges[i].dst().is_hier()){
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << "is hier" << std::endl;
- d_msg_edges.erase(d_msg_edges.begin() + i);
- i--;
- }
+ GR_LOG_DEBUG(d_debug_logger, "Clear_hier()");
+ for (size_t i = 0; i < d_msg_edges.size(); i++) {
+ GR_LOG_DEBUG(d_debug_logger,
+ "edge: " + d_msg_edges[i].src().identifier() + "-->" +
+ d_msg_edges[i].dst().identifier());
+ if (d_msg_edges[i].src().is_hier() || d_msg_edges[i].dst().is_hier()) {
+ GR_LOG_DEBUG(d_debug_logger, "is hier");
+ d_msg_edges.erase(d_msg_edges.begin() + i);
+ i--;
+ }
}
}
void
flat_flowgraph::replace_endpoint(const msg_endpoint &e, const msg_endpoint &r, bool is_src)
{
- size_t n_replr(0);
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("flat_flowgraph::replace_endpoint( %s, %s, %d )\n") % e.block()% r.block()% is_src;
- for(size_t i=0; i<d_msg_edges.size(); i++) {
- if(is_src) {
- if(d_msg_edges[i].src() == e) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") \
- % r% d_msg_edges[i].dst();
- d_msg_edges.push_back( msg_edge(r, d_msg_edges[i].dst() ) );
- n_replr++;
- }
- }
- else {
- if(d_msg_edges[i].dst() == e) {
- if(FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") \
- % r% d_msg_edges[i].src();
- d_msg_edges.push_back( msg_edge(d_msg_edges[i].src(), r ) );
- n_replr++;
- }
- }
+ size_t n_replr(0);
+ GR_LOG_DEBUG(d_debug_logger,
+ boost::format("flat_flowgraph::replace_endpoint( %s, %s, %d )\n") % e.block() %
+ r.block() % is_src);
+ for (size_t i = 0; i < d_msg_edges.size(); i++) {
+ if (is_src) {
+ if (d_msg_edges[i].src() == e) {
+ GR_LOG_DEBUG(
+ d_debug_logger,
+ boost::format(
+ "flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") %
+ r % d_msg_edges[i].dst())
+ d_msg_edges.push_back(msg_edge(r, d_msg_edges[i].dst()));
+ n_replr++;
+ }
+ } else {
+ if (d_msg_edges[i].dst() == e) {
+ GR_LOG_DEBUG(
+ d_debug_logger,
+ boost::format(
+ "flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") %
+ r % d_msg_edges[i].src());
+ d_msg_edges.push_back(msg_edge(d_msg_edges[i].src(), r));
+ n_replr++;
+ }
+ }
}
}
diff --git a/gnuradio-runtime/lib/hier_block2.cc b/gnuradio-runtime/lib/hier_block2.cc
index 597ae032ec..8ebbbda587 100644
--- a/gnuradio-runtime/lib/hier_block2.cc
+++ b/gnuradio-runtime/lib/hier_block2.cc
@@ -178,6 +178,18 @@ namespace gr {
return d_detail->processor_affinity();
}
+ void
+ hier_block2::set_log_level(std::string level)
+ {
+ d_detail->set_log_level(level);
+ }
+
+ std::string
+ hier_block2::log_level()
+ {
+ return d_detail->log_level();
+ }
+
std::string
dot_graph(hier_block2_sptr hierblock2)
{
diff --git a/gnuradio-runtime/lib/hier_block2_detail.cc b/gnuradio-runtime/lib/hier_block2_detail.cc
index 82a40fe211..dbf519b6ef 100644
--- a/gnuradio-runtime/lib/hier_block2_detail.cc
+++ b/gnuradio-runtime/lib/hier_block2_detail.cc
@@ -955,4 +955,22 @@ namespace gr {
return tmp[0]->processor_affinity();
}
+ void
+ hier_block2_detail::set_log_level(std::string level)
+ {
+ basic_block_vector_t tmp = d_fg->calc_used_blocks();
+ for(basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
+ (*p)->set_log_level(level);
+ }
+ }
+
+ std::string
+ hier_block2_detail::log_level()
+ {
+ // Assume that log_level was set for all hier_block2 blocks
+ basic_block_vector_t tmp = d_fg->calc_used_blocks();
+ return tmp[0]->log_level();
+ }
+
+
} /* namespace gr */
diff --git a/gnuradio-runtime/lib/hier_block2_detail.h b/gnuradio-runtime/lib/hier_block2_detail.h
index a5584fe92a..aa419c49bd 100644
--- a/gnuradio-runtime/lib/hier_block2_detail.h
+++ b/gnuradio-runtime/lib/hier_block2_detail.h
@@ -57,6 +57,9 @@ namespace gr {
void set_processor_affinity(const std::vector<int> &mask);
void unset_processor_affinity();
std::vector<int> processor_affinity();
+
+ void set_log_level(std::string level);
+ std::string log_level();
// Track output buffer min/max settings
std::vector<size_t> d_max_output_buffer;
diff --git a/gnuradio-runtime/lib/logger.cc b/gnuradio-runtime/lib/logger.cc
index 17e1aa154c..064b74b3ed 100644
--- a/gnuradio-runtime/lib/logger.cc
+++ b/gnuradio-runtime/lib/logger.cc
@@ -35,10 +35,6 @@
#include <stdexcept>
#include <algorithm>
-
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
-
namespace gr {
bool logger_config::logger_configured(false);
@@ -311,8 +307,6 @@ namespace gr {
} /* namespace gr */
-#endif /* HAVE_LOG4CPP */
-
/****** Start Methods to provide Python the capabilities of the macros ********/
void
gr_logger_config(const std::string config_filename, unsigned int watch_period)
@@ -336,38 +330,12 @@ gr_logger_reset_config(void)
// Remaining capability provided by gr::logger class in gnuradio/logger.h
-#else /* ENABLE_GR_LOG */
-
-/****** Start Methods to provide Python the capabilities of the macros ********/
-void
-gr_logger_config(const std::string config_filename, unsigned int watch_period)
-{
- //NOP
-}
-
-std::vector<std::string>
-gr_logger_get_logger_names(void)
-{
- return std::vector<std::string>(1, "");
-}
-
-void
-gr_logger_reset_config(void)
-{
- //NOP
-}
-
-#endif /* ENABLE_GR_LOG */
-
-
namespace gr {
bool
configure_default_loggers(gr::logger_ptr &l, gr::logger_ptr &d,
const std::string name)
{
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
prefs *p = prefs::singleton();
std::string config_file = p->get_string("LOG", "log_config", "");
std::string log_level = p->get_string("LOG", "log_level", "off");
@@ -408,21 +376,11 @@ namespace gr {
}
d = DLOG;
return true;
-#endif /* HAVE_LOG4CPP */
-
-#else /* ENABLE_GR_LOG */
- l = NULL;
- d = NULL;
- return false;
-#endif /* ENABLE_GR_LOG */
- return false;
}
bool
update_logger_alias(const std::string &name, const std::string &alias)
{
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
prefs *p = prefs::singleton();
std::string log_file = p->get_string("LOG", "log_file", "");
std::string debug_file = p->get_string("LOG", "debug_file", "");
@@ -443,10 +401,6 @@ namespace gr {
}
}
return true;
-#endif /* HAVE_LOG4CPP */
-#endif /* ENABLE_GR_LOG */
-
- return false;
}
} /* namespace gr */
diff --git a/gnuradio-runtime/lib/malloc16.c b/gnuradio-runtime/lib/malloc16.c
deleted file mode 100644
index 2cc6135e77..0000000000
--- a/gnuradio-runtime/lib/malloc16.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Wrapper functions for malloc/free that force 16-byte alignment
- * See http://perso.club-internet.fr/matmac/sourcesc.htm
-
- * Copyright 2001 Phil Karn, KA9Q
- * May be used under the terms of the GNU Public License (GPL)
- */
-
-#include "malloc16.h"
-#include <string.h>
-
-void *malloc16Align(int size){
- void *p;
- void **p1;
-
- if((p = malloc(size+31)) == NULL)
- return NULL;
-
- /* Round up to next 16-byte boundary */
- p1 = (void **)(((long)p + 31) & (~15));
-
- /* Stash actual start of block just before ptr we return */
- p1[-1] = p;
-
- /* Return 16-byte aligned address */
- return (void *)p1;
-}
-
-void *calloc16Align(size_t nmemb,size_t size){
- int nbytes;
- void *p;
-
- nbytes = nmemb*size;
- if((p = malloc16Align(nbytes)) == NULL)
- return NULL;
-
- memset(p,0,nbytes);
- return p;
-}
-
-void free16Align(void *p){
-
- if(p != NULL){
- /* Retrieve pointer to actual start of block and free it */
- free(((void **)p)[-1]);
- }
-}
diff --git a/gnuradio-runtime/lib/malloc16.h b/gnuradio-runtime/lib/malloc16.h
deleted file mode 100644
index 05f80cbf4f..0000000000
--- a/gnuradio-runtime/lib/malloc16.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <gnuradio/api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdlib.h>
-
-GR_RUNTIME_API void *malloc16Align(int size);
-GR_RUNTIME_API void *calloc16Align(size_t nmemb,size_t size);
-GR_RUNTIME_API void free16Align(void *p);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/gnuradio-runtime/lib/math/gen_sine_table.py b/gnuradio-runtime/lib/math/gen_sine_table.py
index d7d11eff11..5b459fa1a3 100755..100644
--- a/gnuradio-runtime/lib/math/gen_sine_table.py
+++ b/gnuradio-runtime/lib/math/gen_sine_table.py
@@ -20,6 +20,8 @@
# Boston, MA 02110-1301, USA.
#
+from __future__ import division
+from __future__ import unicode_literals
import math
import sys
@@ -38,8 +40,8 @@ def gen_approx_table (f, nentries, min_x, max_x):
for i in range (nentries):
a = (i * incx) + min_x
b = ((i + 1) * incx) + min_x
- m = (f(b)-f(a))/(b-a)
- c = (3*a+b)*(f(a)-f(b))/(4*(b-a)) + (f((a+b)/2) + f(a))/2
+ m = (f(b)-f(a)) / (b-a)
+ c = (3*a+b)*(f(a)-f(b))/(4*(b-a)) + (f((a+b)/2) + f(a))//2
abs_error = c+m*a-f(a)
r.append ((m, c, abs_error))
return r
diff --git a/gnuradio-runtime/lib/math/qa_fxpt.cc b/gnuradio-runtime/lib/math/qa_fxpt.cc
index f369cd356a..5073df6e39 100644
--- a/gnuradio-runtime/lib/math/qa_fxpt.cc
+++ b/gnuradio-runtime/lib/math/qa_fxpt.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2013 Free Software Foundation, Inc.
+ * Copyright 2004,2013,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -34,9 +34,9 @@
static const float SIN_COS_TOLERANCE = 1e-5;
BOOST_AUTO_TEST_CASE(t0) {
- BOOST_CHECK(std::abs(M_PI/2 - gr::fxpt::fixed_to_float(0x40000000)) <= SIN_COS_TOLERANCE);
+ BOOST_CHECK(std::abs(GR_M_PI/2 - gr::fxpt::fixed_to_float(0x40000000)) <= SIN_COS_TOLERANCE);
BOOST_CHECK(std::abs(0.0 - gr::fxpt::fixed_to_float(0x00000000)) <= SIN_COS_TOLERANCE);
- BOOST_CHECK(std::abs(-M_PI - gr::fxpt::fixed_to_float(0x80000000)) <= SIN_COS_TOLERANCE);
+ BOOST_CHECK(std::abs(-GR_M_PI - gr::fxpt::fixed_to_float(0x80000000)) <= SIN_COS_TOLERANCE);
if(0) {
/*
@@ -48,9 +48,9 @@ BOOST_AUTO_TEST_CASE(t0) {
* sometimes the answer is off by a few bits at the bottom.
* Hence, the disabled check.
*/
- BOOST_CHECK_EQUAL((int32_t)0x40000000, gr::fxpt::float_to_fixed(M_PI/2));
+ BOOST_CHECK_EQUAL((int32_t)0x40000000, gr::fxpt::float_to_fixed(GR_M_PI/2));
BOOST_CHECK_EQUAL((int32_t)0, gr::fxpt::float_to_fixed(0));
- BOOST_CHECK_EQUAL((int32_t)0x80000000, gr::fxpt::float_to_fixed(-M_PI));
+ BOOST_CHECK_EQUAL((int32_t)0x80000000, gr::fxpt::float_to_fixed(-GR_M_PI));
}
}
@@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE(t1) {
BOOST_CHECK(std::abs(-1 - gr::fxpt::sin(-0x40000000)) <= SIN_COS_TOLERANCE);
BOOST_CHECK(std::abs(-0.707106781 - gr::fxpt::sin(-0x20000000)) <= SIN_COS_TOLERANCE);
- for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ for(float p = -GR_M_PI; p < GR_M_PI; p += 2 * GR_M_PI / 3600) {
float expected = sin(p);
float actual = gr::fxpt::sin(gr::fxpt::float_to_fixed (p));
BOOST_CHECK(std::abs(expected - actual) <= SIN_COS_TOLERANCE);
@@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE(t1) {
}
BOOST_AUTO_TEST_CASE(t2) {
- for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ for(float p = -GR_M_PI; p < GR_M_PI; p += 2 * GR_M_PI / 3600) {
float expected = cos(p);
float actual = gr::fxpt::cos(gr::fxpt::float_to_fixed(p));
BOOST_CHECK(std::abs(expected - actual) <= SIN_COS_TOLERANCE);
@@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(t2) {
}
BOOST_AUTO_TEST_CASE(t3) {
- for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ for(float p = -GR_M_PI; p < GR_M_PI; p += 2 * GR_M_PI / 3600) {
float expected_sin = sin(p);
float expected_cos = cos(p);
float actual_sin;
diff --git a/gnuradio-runtime/lib/math/qa_fxpt_nco.cc b/gnuradio-runtime/lib/math/qa_fxpt_nco.cc
index cd05747630..da10f49c92 100644
--- a/gnuradio-runtime/lib/math/qa_fxpt_nco.cc
+++ b/gnuradio-runtime/lib/math/qa_fxpt_nco.cc
@@ -50,8 +50,8 @@ BOOST_AUTO_TEST_CASE(t0) {
gr::fxpt_nco new_nco;
double max_error = 0, max_phase_error = 0;
- ref_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
- new_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
+ ref_nco.set_freq((float)(2 * GR_M_PI / SIN_COS_FREQ));
+ new_nco.set_freq((float)(2 * GR_M_PI / SIN_COS_FREQ));
BOOST_CHECK(std::abs(ref_nco.get_freq() - new_nco.get_freq()) <= SIN_COS_TOLERANCE);
@@ -86,8 +86,8 @@ BOOST_AUTO_TEST_CASE(t1) {
gr_complex* new_block = new gr_complex[SIN_COS_BLOCK_SIZE];
double max_error = 0;
- ref_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
- new_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
+ ref_nco.set_freq((float)(2 * GR_M_PI / SIN_COS_FREQ));
+ new_nco.set_freq((float)(2 * GR_M_PI / SIN_COS_FREQ));
BOOST_CHECK(std::abs(ref_nco.get_freq() - new_nco.get_freq()) <= SIN_COS_TOLERANCE);
diff --git a/gnuradio-runtime/lib/math/random.cc b/gnuradio-runtime/lib/math/random.cc
index cedaf4b97f..6a509f1796 100644
--- a/gnuradio-runtime/lib/math/random.cc
+++ b/gnuradio-runtime/lib/math/random.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2002, 2015 Free Software Foundation, Inc.
+ * Copyright 2002,2015,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -39,8 +39,10 @@
#include <config.h>
#endif
-#include <math.h>
#include <gnuradio/random.h>
+#include <gnuradio/math.h>
+
+#include <cmath>
namespace gr {
@@ -155,7 +157,7 @@ namespace gr {
float
random::impulse(float factor = 5)
{
- float z = -M_SQRT2 * logf(ran1());
+ float z = -GR_M_SQRT2 * logf(ran1());
if(fabsf(z) <= factor)
return 0.0;
else
diff --git a/gnuradio-runtime/lib/math/vco.h b/gnuradio-runtime/lib/math/vco.h
index d8a6fbb415..7ac1e1ca6d 100644
--- a/gnuradio-runtime/lib/math/vco.h
+++ b/gnuradio-runtime/lib/math/vco.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005,2013 Free Software Foundation, Inc.
+ * Copyright 2005,2013,2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -25,6 +25,8 @@
#include <gnuradio/sincos.h>
#include <gnuradio/gr_complex.h>
+#include <gnuradio/math.h>
+
#include <vector>
#include <cmath>
@@ -49,13 +51,13 @@ namespace gr {
void adjust_phase(double delta_phase) {
d_phase += delta_phase;
- if(fabs (d_phase) > M_PI){
+ if(fabs (d_phase) > GR_M_PI){
- while(d_phase > M_PI)
- d_phase -= 2*M_PI;
+ while(d_phase > GR_M_PI)
+ d_phase -= 2*GR_M_PI;
- while(d_phase < -M_PI)
- d_phase += 2*M_PI;
+ while(d_phase < -GR_M_PI)
+ d_phase += 2*GR_M_PI;
}
}
diff --git a/gnuradio-runtime/lib/pmt/CMakeLists.txt b/gnuradio-runtime/lib/pmt/CMakeLists.txt
index 469c569cdc..c840b8b930 100644
--- a/gnuradio-runtime/lib/pmt/CMakeLists.txt
+++ b/gnuradio-runtime/lib/pmt/CMakeLists.txt
@@ -23,57 +23,8 @@
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-########################################################################
-# Generate serial tags header file
-########################################################################
-
-get_filename_component(PMT_SERIAL_TAGS_H
- ${CMAKE_CURRENT_BINARY_DIR}/../../include/pmt/pmt_serial_tags.h ABSOLUTE
-)
-
-add_custom_command(
- OUTPUT ${PMT_SERIAL_TAGS_H}
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/gen-serial-tags.py
- DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pmt-serial-tags.scm
- COMMAND ${PYTHON_EXECUTABLE}
- ${CMAKE_CURRENT_SOURCE_DIR}/gen-serial-tags.py
- ${CMAKE_CURRENT_SOURCE_DIR}/pmt-serial-tags.scm
- ${PMT_SERIAL_TAGS_H}
-)
-
-install(
- FILES ${PMT_SERIAL_TAGS_H}
- DESTINATION ${GR_INCLUDE_DIR}/pmt
- COMPONENT "runtime_devel"
-)
-
-include(AddFileDependencies)
-ADD_FILE_DEPENDENCIES(
- ${CMAKE_CURRENT_SOURCE_DIR}/pmt_serialize.cc
- ${PMT_SERIAL_TAGS_H}
-)
-
-########################################################################
-# Generate other pmt stuff
-########################################################################
-add_custom_command(
- OUTPUT
- ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv_int.h
- ${CMAKE_CURRENT_BINARY_DIR}/qa_pmt_unv.h
- ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv.cc
- DEPENDS
- ${CMAKE_CURRENT_SOURCE_DIR}/generate_unv.py
- ${CMAKE_CURRENT_SOURCE_DIR}/unv_template.h.t
- ${CMAKE_CURRENT_SOURCE_DIR}/unv_template.cc.t
- ${CMAKE_CURRENT_SOURCE_DIR}/unv_qa_template.h.t
- COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} -c
- "import os, sys; srcdir='${CMAKE_CURRENT_SOURCE_DIR}'; sys.path.append(srcdir); os.environ['srcdir']=srcdir; from generate_unv import main; main()"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- VERBATIM
-)
-
set(pmt_sources
- ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/pmt_unv.cc
${CMAKE_CURRENT_SOURCE_DIR}/pmt.cc
${CMAKE_CURRENT_SOURCE_DIR}/pmt_io.cc
${CMAKE_CURRENT_SOURCE_DIR}/pmt_pool.cc
@@ -85,10 +36,6 @@ list(APPEND gnuradio_pmt_libs
${LOG4CPP_LIBRARIES}
)
-add_custom_target(pmt_generated
- DEPENDS ${PMT_SERIAL_TAGS_H} ${CMAKE_CURRENT_BINARY_DIR}/pmt_unv_int.h)
-
-
#Add Windows DLL resource file if using MSVC
if(MSVC)
include(${CMAKE_SOURCE_DIR}/cmake/Modules/GrVersion.cmake)
@@ -107,16 +54,12 @@ endif(MSVC)
add_library(gnuradio-pmt SHARED ${pmt_sources})
target_link_libraries(gnuradio-pmt ${gnuradio_pmt_libs})
-GR_LIBRARY_FOO(gnuradio-pmt RUNTIME_COMPONENT "runtime_runtime" DEVEL_COMPONENT "runtime_devel")
-
-add_dependencies(gnuradio-pmt
- pmt_generated
-)
+GR_LIBRARY_FOO(gnuradio-pmt)
if(ENABLE_STATIC_LIBS)
add_library(gnuradio-pmt_static STATIC ${pmt_sources})
- add_dependencies(gnuradio-pmt_static pmt_generated)
+ add_dependencies(gnuradio-pmt_static)
if(NOT WIN32)
set_target_properties(gnuradio-pmt_static
@@ -124,7 +67,39 @@ if(ENABLE_STATIC_LIBS)
endif(NOT WIN32)
install(TARGETS gnuradio-pmt_static
- ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "runtime_devel" # .lib file
+ ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file
)
endif(ENABLE_STATIC_LIBS)
+########################################################################
+# Setup tests
+########################################################################
+if(ENABLE_TESTING)
+include(GrTest)
+
+########################################################################
+# Append gnuradio-runtime test sources
+########################################################################
+list(APPEND test_gnuradio_pmt_sources
+ qa_pmt.cc
+ qa_pmt_prims.cc
+ qa_pmt_unv.cc
+)
+
+include_directories(${CPPUNIT_INCLUDE_DIRS})
+link_directories(${CPPUNIT_LIBRARY_DIRS})
+
+add_library(test-gnuradio-pmt SHARED ${test_gnuradio_pmt_sources})
+target_link_libraries(test-gnuradio-pmt gnuradio-runtime gnuradio-pmt
+ ${CPPUNIT_LIBRARIES} ${Boost_LIBRARIES} ${LOG4CPP_LIBRARIES})
+
+########################################################################
+# Build the test executable
+# Set the test environment so the build libs will be found under MSVC.
+########################################################################
+list(APPEND GR_TEST_TARGET_DEPS test-gnuradio-pmt)
+add_executable(gr_pmt_test test_pmt.cc)
+target_link_libraries(gr_pmt_test test-gnuradio-pmt)
+GR_ADD_TEST(gr-pmt-test gr_pmt_test)
+
+endif(ENABLE_TESTING)
diff --git a/gnuradio-runtime/lib/pmt/gen-serial-tags.py b/gnuradio-runtime/lib/pmt/gen-serial-tags.py
deleted file mode 100644
index 18e927beb5..0000000000
--- a/gnuradio-runtime/lib/pmt/gen-serial-tags.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""
-//
-// Copyright 2011 Free Software Foundation, Inc.
-//
-// This file is part of GNU Radio
-//
-// GNU Radio is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3, or (at your option)
-// any later version.
-//
-// GNU Radio is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-//
-// THIS FILE IS MACHINE GENERATED FROM %s. DO NOT EDIT BY HAND.
-// See %s for additional commentary.
-//
-
-#ifndef INCLUDED_PMT_SERIAL_TAGS_H
-#define INCLUDED_PMT_SERIAL_TAGS_H
-
-enum pst_tags {
-%s
-};
-#endif /* INCLUDED_PMT_SERIAL_TAGS_H */
-"""
-
-import sys, os, re
-
-if __name__ == '__main__':
- if len(sys.argv) != 3:
- print "Usage %s <input_scm_file> <output_hdr_file>"%__file__
- exit()
- input_scm_file, output_hdr_file = sys.argv[1:]
- enums = list()
- for line in open(input_scm_file).readlines():
- match = re.match('^\s*\(define\s+([\w|-]+)\s+#x([0-9a-fA-F]+)\)', line)
- if not match: continue
- name, value = match.groups()
- name = name.upper().replace('-', '_')
- enums.append(' %s = 0x%s'%(name, value))
- open(output_hdr_file, 'w').write(__doc__%(
- os.path.basename(__file__),
- os.path.basename(input_scm_file),
- ',\n'.join(enums),
- ))
diff --git a/gnuradio-runtime/lib/pmt/generate_unv.py b/gnuradio-runtime/lib/pmt/generate_unv.py
deleted file mode 100755
index c7daee9e45..0000000000
--- a/gnuradio-runtime/lib/pmt/generate_unv.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2006,2009 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-"""
-Generate code for uniform numeric vectors
-"""
-
-import re, os, os.path
-
-
-unv_types = (
- ('u8', 'uint8_t'),
- ('s8', 'int8_t'),
- ('u16', 'uint16_t'),
- ('s16', 'int16_t'),
- ('u32', 'uint32_t'),
- ('s32', 'int32_t'),
- ('u64', 'uint64_t'),
- ('s64', 'int64_t'),
- ('f32', 'float'),
- ('f64', 'double'),
- ('c32', 'std::complex<float>'),
- ('c64', 'std::complex<double>')
- )
-
-header = """\
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-"""
-
-guard_tail = """
-#endif
-"""
-
-includes = """
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <vector>
-#include <pmt/pmt.h>
-#include <boost/lexical_cast.hpp>
-#include "pmt_int.h"
-"""
-
-qa_includes = """
-#include <pmt/pmt.h>
-#include <stdio.h>
-
-using namespace pmt;
-"""
-
-
-# set srcdir to the directory that contains Makefile.am
-try:
- srcdir = os.environ['srcdir']
-except KeyError, e:
- srcdir = "."
-srcdir = srcdir + '/'
-
-
-def open_src (name, mode):
- global srcdir
- return open(os.path.join (srcdir, name), mode)
-
-
-def guard_name(filename):
- return 'INCLUDED_' + re.sub('\.', '_', filename.upper())
-
-def guard_head(filename):
- guard = guard_name(filename)
- return """
-#ifndef %s
-#define %s
-""" % (guard, guard)
-
-
-def do_substitution (d, input, out_file):
- def repl (match_obj):
- key = match_obj.group (1)
- # print key
- return d[key]
-
- out = re.sub (r"@([a-zA-Z0-9_]+)@", repl, input)
- out_file.write (out)
-
-
-def generate_h():
- template = open_src('unv_template.h.t', 'r').read()
- output_filename = 'pmt_unv_int.h'
- output = open(output_filename, 'w')
- output.write(header)
- output.write(guard_head(output_filename))
- for tag, typ in unv_types:
- d = { 'TAG' : tag, 'TYPE' : typ }
- do_substitution(d, template, output)
- output.write(guard_tail)
-
-def generate_cc():
- template = open_src('unv_template.cc.t', 'r').read()
- output = open('pmt_unv.cc', 'w')
- output.write(header)
- output.write(includes)
- for tag, typ in unv_types:
- d = { 'TAG' : tag, 'TYPE' : typ }
- do_substitution(d, template, output)
-
-
-def generate_qa_h():
- template = open_src('unv_qa_template.h.t', 'r').read()
- output = open('qa_pmt_unv.h', 'w')
- output.write(header)
- output.write(qa_includes)
- for tag, typ in unv_types:
- d = { 'TAG' : tag, 'TYPE' : typ }
- do_substitution(d, template, output)
-
-
-def main():
- generate_h()
- generate_cc()
- generate_qa_h()
-
-if __name__ == '__main__':
- main()
diff --git a/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm b/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm
deleted file mode 100644
index 4f06bf75f8..0000000000
--- a/gnuradio-runtime/lib/pmt/pmt-serial-tags.scm
+++ /dev/null
@@ -1,77 +0,0 @@
-;;; -*-scheme-*-
-;;;
-;;; Copyright 2007 Free Software Foundation, Inc.
-;;;
-;;; This file is part of GNU Radio
-;;;
-;;; GNU Radio is free software; you can redistribute it and/or modify
-;;; it under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 3, or (define at your option)
-;;; any later version.
-;;;
-;;; GNU Radio is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License along
-;;; with this program; if not, write to the Free Software Foundation, Inc.,
-;;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-;;;
-
-;;; definitions of tag values used for marshalling pmt data
-
-(define pst-true #x00)
-(define pst-false #x01)
-(define pst-symbol #x02) ; untagged-int16 n; followed by n bytes of symbol name
-(define pst-int32 #x03)
-(define pst-double #x04)
-(define pst-complex #x05) ; complex<double>: real, imag
-(define pst-null #x06)
-(define pst-pair #x07) ; followed by two objects
-(define pst-vector #x08) ; untagged-int32 n; followed by n objects
-(define pst-dict #x09) ; untagged-int32 n; followed by n key/value tuples
-
-(define pst-uniform-vector #x0a)
-(define pst-uint64 #x0b)
-(define pst-tuple #x0c)
-
-;; u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c32, c64
-;;
-;; untagged-uint8 tag
-;; untagged-uint8 uvi (define uniform vector info, see below)
-;; untagged-int32 n-items
-;; untagged-uint8 npad
-;; npad bytes of zeros to align binary data
-;; n-items binary numeric items
-;;
-;; uvi:
-;; +-+-+-+-+-+-+-+-+
-;; |B| subtype |
-;; +-+-+-+-+-+-+-+-+
-;;
-;; B == 0, numeric data is little-endian.
-;; B == 1, numeric data is big-endian.
-
- (define uvi-endian-mask #x80)
- (define uvi-subtype-mask #x7f)
-
- (define uvi-little-endian #x00)
- (define uvi-big-endian #x80)
-
- (define uvi-u8 #x00)
- (define uvi-s8 #x01)
- (define uvi-u16 #x02)
- (define uvi-s16 #x03)
- (define uvi-u32 #x04)
- (define uvi-s32 #x05)
- (define uvi-u64 #x06)
- (define uvi-s64 #x07)
- (define uvi-f32 #x08)
- (define uvi-f64 #x09)
- (define uvi-c32 #x0a)
- (define uvi-c64 #x0b)
-
-
-(define pst-comment #x3b) ; ascii ';'
-(define pst-comment-end #x0a) ; ascii '\n'
diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index 0fe4dbde8e..763007132f 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -63,7 +63,6 @@ pmt_base::operator delete(void *p, size_t size)
#endif
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53))
void intrusive_ptr_add_ref(pmt_base* p)
{
p->refcount_.fetch_add(1, boost::memory_order_relaxed);
@@ -75,13 +74,6 @@ void intrusive_ptr_release(pmt_base* p) {
delete p;
}
}
-#else
-// boost::atomic not available before 1.53
-// This section will be removed when support for boost 1.48 ceases
-// NB: This code is prone to segfault on non-Intel architectures.
-void intrusive_ptr_add_ref(pmt_base* p) { ++(p->count_); }
-void intrusive_ptr_release(pmt_base* p) { if (--(p->count_) == 0 ) delete p; }
-#endif
pmt_base::~pmt_base()
{
diff --git a/gnuradio-runtime/lib/pmt/pmt_int.h b/gnuradio-runtime/lib/pmt/pmt_int.h
index da48a0ddc8..ead058598d 100644
--- a/gnuradio-runtime/lib/pmt/pmt_int.h
+++ b/gnuradio-runtime/lib/pmt/pmt_int.h
@@ -25,13 +25,7 @@
#include <pmt/pmt.h>
#include <boost/utility.hpp>
#include <boost/version.hpp>
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53))
- #include <boost/atomic.hpp>
-#else
- // boost::atomic not available before 1.53
- // This section will be removed when support for boost 1.48 ceases
- #include <boost/detail/atomic_count.hpp>
-#endif
+#include <boost/atomic.hpp>
/*
* EVERYTHING IN THIS FILE IS PRIVATE TO THE IMPLEMENTATION!
@@ -43,23 +37,10 @@
namespace pmt {
class PMT_API pmt_base : boost::noncopyable {
-
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53))
mutable boost::atomic<int> refcount_;
-#else
- // boost::atomic not available before 1.53
- // This section will be removed when support for boost 1.48 ceases
- mutable boost::detail::atomic_count count_;
-#endif
protected:
-#if ((BOOST_VERSION / 100000 >= 1) && (BOOST_VERSION / 100 % 1000 >= 53))
pmt_base() : refcount_(0) {};
-#else
- // boost::atomic not available before 1.53
- // This section will be removed when support for boost 1.48 ceases
- pmt_base() : count_(0) {};
-#endif
virtual ~pmt_base();
public:
@@ -261,9 +242,6 @@ public:
virtual size_t itemsize() const = 0;
virtual const std::string string_ref(size_t k) const { return std::string("not implemented"); }
};
-
-#include "pmt_unv_int.h"
-
} /* namespace pmt */
#endif /* INCLUDED_PMT_INT_H */
diff --git a/gnuradio-runtime/lib/pmt/pmt_unv.cc b/gnuradio-runtime/lib/pmt/pmt_unv.cc
new file mode 100644
index 0000000000..cda0c085cd
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/pmt_unv.cc
@@ -0,0 +1,1821 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+// This file is machine generated using the generate_unv.py tool
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pmt_unv_int.h"
+#include "pmt_int.h"
+#include <pmt/pmt.h>
+#include <boost/lexical_cast.hpp>
+#include <vector>
+////////////////////////////////////////////////////////////////////////////
+// pmt_u8vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u8vector *
+_u8vector(pmt_t x)
+{
+ return dynamic_cast<pmt_u8vector*>(x.get());
+}
+
+
+pmt_u8vector::pmt_u8vector(size_t k, uint8_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_u8vector::pmt_u8vector(size_t k, const uint8_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(uint8_t) );
+}
+
+uint8_t
+pmt_u8vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_u8vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_u8vector::set(size_t k, uint8_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_u8vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const uint8_t *
+pmt_u8vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+uint8_t *
+pmt_u8vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u8vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(uint8_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u8vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(uint8_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u8vector(pmt_t obj)
+{
+ return obj->is_u8vector();
+}
+
+pmt_t
+make_u8vector(size_t k, uint8_t fill)
+{
+ return pmt_t(new pmt_u8vector(k, fill));
+}
+
+pmt_t
+init_u8vector(size_t k, const uint8_t *data)
+{
+ return pmt_t(new pmt_u8vector(k, data));
+}
+
+pmt_t
+init_u8vector(size_t k, const std::vector< uint8_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_u8vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_u8vector(k, static_cast< uint8_t >(0))); // fills an empty vector with 0
+}
+
+uint8_t
+u8vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_u8vector())
+ throw wrong_type("pmt_u8vector_ref", vector);
+ return _u8vector(vector)->ref(k);
+}
+
+void
+u8vector_set(pmt_t vector, size_t k, uint8_t obj)
+{
+ if (!vector->is_u8vector())
+ throw wrong_type("pmt_u8vector_set", vector);
+ _u8vector(vector)->set(k, obj);
+}
+
+const uint8_t *
+u8vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u8vector())
+ throw wrong_type("pmt_u8vector_elements", vector);
+ return _u8vector(vector)->elements(len);
+}
+
+const std::vector< uint8_t >
+u8vector_elements(pmt_t vector)
+{
+ if (!vector->is_u8vector())
+ throw wrong_type("pmt_u8vector_elements", vector);
+ size_t len;
+ const uint8_t *array = _u8vector(vector)->elements(len);
+ const std::vector< uint8_t > vec(array, array+len);
+ return vec;
+}
+
+
+uint8_t *
+u8vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u8vector())
+ throw wrong_type("pmt_u8vector_writable_elements", vector);
+ return _u8vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u8vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, uint8_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_s8vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s8vector *
+_s8vector(pmt_t x)
+{
+ return dynamic_cast<pmt_s8vector*>(x.get());
+}
+
+
+pmt_s8vector::pmt_s8vector(size_t k, int8_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_s8vector::pmt_s8vector(size_t k, const int8_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(int8_t) );
+}
+
+int8_t
+pmt_s8vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_s8vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_s8vector::set(size_t k, int8_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_s8vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const int8_t *
+pmt_s8vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+int8_t *
+pmt_s8vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s8vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(int8_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s8vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(int8_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s8vector(pmt_t obj)
+{
+ return obj->is_s8vector();
+}
+
+pmt_t
+make_s8vector(size_t k, int8_t fill)
+{
+ return pmt_t(new pmt_s8vector(k, fill));
+}
+
+pmt_t
+init_s8vector(size_t k, const int8_t *data)
+{
+ return pmt_t(new pmt_s8vector(k, data));
+}
+
+pmt_t
+init_s8vector(size_t k, const std::vector< int8_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_s8vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_s8vector(k, static_cast< int8_t >(0))); // fills an empty vector with 0
+}
+
+int8_t
+s8vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_s8vector())
+ throw wrong_type("pmt_s8vector_ref", vector);
+ return _s8vector(vector)->ref(k);
+}
+
+void
+s8vector_set(pmt_t vector, size_t k, int8_t obj)
+{
+ if (!vector->is_s8vector())
+ throw wrong_type("pmt_s8vector_set", vector);
+ _s8vector(vector)->set(k, obj);
+}
+
+const int8_t *
+s8vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s8vector())
+ throw wrong_type("pmt_s8vector_elements", vector);
+ return _s8vector(vector)->elements(len);
+}
+
+const std::vector< int8_t >
+s8vector_elements(pmt_t vector)
+{
+ if (!vector->is_s8vector())
+ throw wrong_type("pmt_s8vector_elements", vector);
+ size_t len;
+ const int8_t *array = _s8vector(vector)->elements(len);
+ const std::vector< int8_t > vec(array, array+len);
+ return vec;
+}
+
+
+int8_t *
+s8vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s8vector())
+ throw wrong_type("pmt_s8vector_writable_elements", vector);
+ return _s8vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s8vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, int8_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_u16vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u16vector *
+_u16vector(pmt_t x)
+{
+ return dynamic_cast<pmt_u16vector*>(x.get());
+}
+
+
+pmt_u16vector::pmt_u16vector(size_t k, uint16_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_u16vector::pmt_u16vector(size_t k, const uint16_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(uint16_t) );
+}
+
+uint16_t
+pmt_u16vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_u16vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_u16vector::set(size_t k, uint16_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_u16vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const uint16_t *
+pmt_u16vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+uint16_t *
+pmt_u16vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u16vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(uint16_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u16vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(uint16_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u16vector(pmt_t obj)
+{
+ return obj->is_u16vector();
+}
+
+pmt_t
+make_u16vector(size_t k, uint16_t fill)
+{
+ return pmt_t(new pmt_u16vector(k, fill));
+}
+
+pmt_t
+init_u16vector(size_t k, const uint16_t *data)
+{
+ return pmt_t(new pmt_u16vector(k, data));
+}
+
+pmt_t
+init_u16vector(size_t k, const std::vector< uint16_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_u16vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_u16vector(k, static_cast< uint16_t >(0))); // fills an empty vector with 0
+}
+
+uint16_t
+u16vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_u16vector())
+ throw wrong_type("pmt_u16vector_ref", vector);
+ return _u16vector(vector)->ref(k);
+}
+
+void
+u16vector_set(pmt_t vector, size_t k, uint16_t obj)
+{
+ if (!vector->is_u16vector())
+ throw wrong_type("pmt_u16vector_set", vector);
+ _u16vector(vector)->set(k, obj);
+}
+
+const uint16_t *
+u16vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u16vector())
+ throw wrong_type("pmt_u16vector_elements", vector);
+ return _u16vector(vector)->elements(len);
+}
+
+const std::vector< uint16_t >
+u16vector_elements(pmt_t vector)
+{
+ if (!vector->is_u16vector())
+ throw wrong_type("pmt_u16vector_elements", vector);
+ size_t len;
+ const uint16_t *array = _u16vector(vector)->elements(len);
+ const std::vector< uint16_t > vec(array, array+len);
+ return vec;
+}
+
+
+uint16_t *
+u16vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u16vector())
+ throw wrong_type("pmt_u16vector_writable_elements", vector);
+ return _u16vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u16vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, uint16_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_s16vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s16vector *
+_s16vector(pmt_t x)
+{
+ return dynamic_cast<pmt_s16vector*>(x.get());
+}
+
+
+pmt_s16vector::pmt_s16vector(size_t k, int16_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_s16vector::pmt_s16vector(size_t k, const int16_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(int16_t) );
+}
+
+int16_t
+pmt_s16vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_s16vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_s16vector::set(size_t k, int16_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_s16vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const int16_t *
+pmt_s16vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+int16_t *
+pmt_s16vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s16vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(int16_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s16vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(int16_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s16vector(pmt_t obj)
+{
+ return obj->is_s16vector();
+}
+
+pmt_t
+make_s16vector(size_t k, int16_t fill)
+{
+ return pmt_t(new pmt_s16vector(k, fill));
+}
+
+pmt_t
+init_s16vector(size_t k, const int16_t *data)
+{
+ return pmt_t(new pmt_s16vector(k, data));
+}
+
+pmt_t
+init_s16vector(size_t k, const std::vector< int16_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_s16vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_s16vector(k, static_cast< int16_t >(0))); // fills an empty vector with 0
+}
+
+int16_t
+s16vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_s16vector())
+ throw wrong_type("pmt_s16vector_ref", vector);
+ return _s16vector(vector)->ref(k);
+}
+
+void
+s16vector_set(pmt_t vector, size_t k, int16_t obj)
+{
+ if (!vector->is_s16vector())
+ throw wrong_type("pmt_s16vector_set", vector);
+ _s16vector(vector)->set(k, obj);
+}
+
+const int16_t *
+s16vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s16vector())
+ throw wrong_type("pmt_s16vector_elements", vector);
+ return _s16vector(vector)->elements(len);
+}
+
+const std::vector< int16_t >
+s16vector_elements(pmt_t vector)
+{
+ if (!vector->is_s16vector())
+ throw wrong_type("pmt_s16vector_elements", vector);
+ size_t len;
+ const int16_t *array = _s16vector(vector)->elements(len);
+ const std::vector< int16_t > vec(array, array+len);
+ return vec;
+}
+
+
+int16_t *
+s16vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s16vector())
+ throw wrong_type("pmt_s16vector_writable_elements", vector);
+ return _s16vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s16vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, int16_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_u32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u32vector *
+_u32vector(pmt_t x)
+{
+ return dynamic_cast<pmt_u32vector*>(x.get());
+}
+
+
+pmt_u32vector::pmt_u32vector(size_t k, uint32_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_u32vector::pmt_u32vector(size_t k, const uint32_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(uint32_t) );
+}
+
+uint32_t
+pmt_u32vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_u32vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_u32vector::set(size_t k, uint32_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_u32vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const uint32_t *
+pmt_u32vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+uint32_t *
+pmt_u32vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u32vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(uint32_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u32vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(uint32_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u32vector(pmt_t obj)
+{
+ return obj->is_u32vector();
+}
+
+pmt_t
+make_u32vector(size_t k, uint32_t fill)
+{
+ return pmt_t(new pmt_u32vector(k, fill));
+}
+
+pmt_t
+init_u32vector(size_t k, const uint32_t *data)
+{
+ return pmt_t(new pmt_u32vector(k, data));
+}
+
+pmt_t
+init_u32vector(size_t k, const std::vector< uint32_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_u32vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_u32vector(k, static_cast< uint32_t >(0))); // fills an empty vector with 0
+}
+
+uint32_t
+u32vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_u32vector())
+ throw wrong_type("pmt_u32vector_ref", vector);
+ return _u32vector(vector)->ref(k);
+}
+
+void
+u32vector_set(pmt_t vector, size_t k, uint32_t obj)
+{
+ if (!vector->is_u32vector())
+ throw wrong_type("pmt_u32vector_set", vector);
+ _u32vector(vector)->set(k, obj);
+}
+
+const uint32_t *
+u32vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u32vector())
+ throw wrong_type("pmt_u32vector_elements", vector);
+ return _u32vector(vector)->elements(len);
+}
+
+const std::vector< uint32_t >
+u32vector_elements(pmt_t vector)
+{
+ if (!vector->is_u32vector())
+ throw wrong_type("pmt_u32vector_elements", vector);
+ size_t len;
+ const uint32_t *array = _u32vector(vector)->elements(len);
+ const std::vector< uint32_t > vec(array, array+len);
+ return vec;
+}
+
+
+uint32_t *
+u32vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u32vector())
+ throw wrong_type("pmt_u32vector_writable_elements", vector);
+ return _u32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u32vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, uint32_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_s32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s32vector *
+_s32vector(pmt_t x)
+{
+ return dynamic_cast<pmt_s32vector*>(x.get());
+}
+
+
+pmt_s32vector::pmt_s32vector(size_t k, int32_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_s32vector::pmt_s32vector(size_t k, const int32_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(int32_t) );
+}
+
+int32_t
+pmt_s32vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_s32vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_s32vector::set(size_t k, int32_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_s32vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const int32_t *
+pmt_s32vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+int32_t *
+pmt_s32vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s32vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(int32_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s32vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(int32_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s32vector(pmt_t obj)
+{
+ return obj->is_s32vector();
+}
+
+pmt_t
+make_s32vector(size_t k, int32_t fill)
+{
+ return pmt_t(new pmt_s32vector(k, fill));
+}
+
+pmt_t
+init_s32vector(size_t k, const int32_t *data)
+{
+ return pmt_t(new pmt_s32vector(k, data));
+}
+
+pmt_t
+init_s32vector(size_t k, const std::vector< int32_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_s32vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_s32vector(k, static_cast< int32_t >(0))); // fills an empty vector with 0
+}
+
+int32_t
+s32vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_s32vector())
+ throw wrong_type("pmt_s32vector_ref", vector);
+ return _s32vector(vector)->ref(k);
+}
+
+void
+s32vector_set(pmt_t vector, size_t k, int32_t obj)
+{
+ if (!vector->is_s32vector())
+ throw wrong_type("pmt_s32vector_set", vector);
+ _s32vector(vector)->set(k, obj);
+}
+
+const int32_t *
+s32vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s32vector())
+ throw wrong_type("pmt_s32vector_elements", vector);
+ return _s32vector(vector)->elements(len);
+}
+
+const std::vector< int32_t >
+s32vector_elements(pmt_t vector)
+{
+ if (!vector->is_s32vector())
+ throw wrong_type("pmt_s32vector_elements", vector);
+ size_t len;
+ const int32_t *array = _s32vector(vector)->elements(len);
+ const std::vector< int32_t > vec(array, array+len);
+ return vec;
+}
+
+
+int32_t *
+s32vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s32vector())
+ throw wrong_type("pmt_s32vector_writable_elements", vector);
+ return _s32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s32vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, int32_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_u64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_u64vector *
+_u64vector(pmt_t x)
+{
+ return dynamic_cast<pmt_u64vector*>(x.get());
+}
+
+
+pmt_u64vector::pmt_u64vector(size_t k, uint64_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_u64vector::pmt_u64vector(size_t k, const uint64_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(uint64_t) );
+}
+
+uint64_t
+pmt_u64vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_u64vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_u64vector::set(size_t k, uint64_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_u64vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const uint64_t *
+pmt_u64vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+uint64_t *
+pmt_u64vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_u64vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(uint64_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_u64vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(uint64_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_u64vector(pmt_t obj)
+{
+ return obj->is_u64vector();
+}
+
+pmt_t
+make_u64vector(size_t k, uint64_t fill)
+{
+ return pmt_t(new pmt_u64vector(k, fill));
+}
+
+pmt_t
+init_u64vector(size_t k, const uint64_t *data)
+{
+ return pmt_t(new pmt_u64vector(k, data));
+}
+
+pmt_t
+init_u64vector(size_t k, const std::vector< uint64_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_u64vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_u64vector(k, static_cast< uint64_t >(0))); // fills an empty vector with 0
+}
+
+uint64_t
+u64vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_u64vector())
+ throw wrong_type("pmt_u64vector_ref", vector);
+ return _u64vector(vector)->ref(k);
+}
+
+void
+u64vector_set(pmt_t vector, size_t k, uint64_t obj)
+{
+ if (!vector->is_u64vector())
+ throw wrong_type("pmt_u64vector_set", vector);
+ _u64vector(vector)->set(k, obj);
+}
+
+const uint64_t *
+u64vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u64vector())
+ throw wrong_type("pmt_u64vector_elements", vector);
+ return _u64vector(vector)->elements(len);
+}
+
+const std::vector< uint64_t >
+u64vector_elements(pmt_t vector)
+{
+ if (!vector->is_u64vector())
+ throw wrong_type("pmt_u64vector_elements", vector);
+ size_t len;
+ const uint64_t *array = _u64vector(vector)->elements(len);
+ const std::vector< uint64_t > vec(array, array+len);
+ return vec;
+}
+
+
+uint64_t *
+u64vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_u64vector())
+ throw wrong_type("pmt_u64vector_writable_elements", vector);
+ return _u64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_u64vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, uint64_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_s64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_s64vector *
+_s64vector(pmt_t x)
+{
+ return dynamic_cast<pmt_s64vector*>(x.get());
+}
+
+
+pmt_s64vector::pmt_s64vector(size_t k, int64_t fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_s64vector::pmt_s64vector(size_t k, const int64_t *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(int64_t) );
+}
+
+int64_t
+pmt_s64vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_s64vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_s64vector::set(size_t k, int64_t x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_s64vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const int64_t *
+pmt_s64vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+int64_t *
+pmt_s64vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_s64vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(int64_t);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_s64vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(int64_t);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_s64vector(pmt_t obj)
+{
+ return obj->is_s64vector();
+}
+
+pmt_t
+make_s64vector(size_t k, int64_t fill)
+{
+ return pmt_t(new pmt_s64vector(k, fill));
+}
+
+pmt_t
+init_s64vector(size_t k, const int64_t *data)
+{
+ return pmt_t(new pmt_s64vector(k, data));
+}
+
+pmt_t
+init_s64vector(size_t k, const std::vector< int64_t > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_s64vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_s64vector(k, static_cast< int64_t >(0))); // fills an empty vector with 0
+}
+
+int64_t
+s64vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_s64vector())
+ throw wrong_type("pmt_s64vector_ref", vector);
+ return _s64vector(vector)->ref(k);
+}
+
+void
+s64vector_set(pmt_t vector, size_t k, int64_t obj)
+{
+ if (!vector->is_s64vector())
+ throw wrong_type("pmt_s64vector_set", vector);
+ _s64vector(vector)->set(k, obj);
+}
+
+const int64_t *
+s64vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s64vector())
+ throw wrong_type("pmt_s64vector_elements", vector);
+ return _s64vector(vector)->elements(len);
+}
+
+const std::vector< int64_t >
+s64vector_elements(pmt_t vector)
+{
+ if (!vector->is_s64vector())
+ throw wrong_type("pmt_s64vector_elements", vector);
+ size_t len;
+ const int64_t *array = _s64vector(vector)->elements(len);
+ const std::vector< int64_t > vec(array, array+len);
+ return vec;
+}
+
+
+int64_t *
+s64vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_s64vector())
+ throw wrong_type("pmt_s64vector_writable_elements", vector);
+ return _s64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_s64vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, int64_t > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_f32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_f32vector *
+_f32vector(pmt_t x)
+{
+ return dynamic_cast<pmt_f32vector*>(x.get());
+}
+
+
+pmt_f32vector::pmt_f32vector(size_t k, float fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_f32vector::pmt_f32vector(size_t k, const float *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(float) );
+}
+
+float
+pmt_f32vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_f32vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_f32vector::set(size_t k, float x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_f32vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const float *
+pmt_f32vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+float *
+pmt_f32vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_f32vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(float);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_f32vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(float);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_f32vector(pmt_t obj)
+{
+ return obj->is_f32vector();
+}
+
+pmt_t
+make_f32vector(size_t k, float fill)
+{
+ return pmt_t(new pmt_f32vector(k, fill));
+}
+
+pmt_t
+init_f32vector(size_t k, const float *data)
+{
+ return pmt_t(new pmt_f32vector(k, data));
+}
+
+pmt_t
+init_f32vector(size_t k, const std::vector< float > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_f32vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_f32vector(k, static_cast< float >(0))); // fills an empty vector with 0
+}
+
+float
+f32vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_f32vector())
+ throw wrong_type("pmt_f32vector_ref", vector);
+ return _f32vector(vector)->ref(k);
+}
+
+void
+f32vector_set(pmt_t vector, size_t k, float obj)
+{
+ if (!vector->is_f32vector())
+ throw wrong_type("pmt_f32vector_set", vector);
+ _f32vector(vector)->set(k, obj);
+}
+
+const float *
+f32vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_f32vector())
+ throw wrong_type("pmt_f32vector_elements", vector);
+ return _f32vector(vector)->elements(len);
+}
+
+const std::vector< float >
+f32vector_elements(pmt_t vector)
+{
+ if (!vector->is_f32vector())
+ throw wrong_type("pmt_f32vector_elements", vector);
+ size_t len;
+ const float *array = _f32vector(vector)->elements(len);
+ const std::vector< float > vec(array, array+len);
+ return vec;
+}
+
+
+float *
+f32vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_f32vector())
+ throw wrong_type("pmt_f32vector_writable_elements", vector);
+ return _f32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_f32vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, float > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_f64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_f64vector *
+_f64vector(pmt_t x)
+{
+ return dynamic_cast<pmt_f64vector*>(x.get());
+}
+
+
+pmt_f64vector::pmt_f64vector(size_t k, double fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_f64vector::pmt_f64vector(size_t k, const double *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(double) );
+}
+
+double
+pmt_f64vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_f64vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_f64vector::set(size_t k, double x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_f64vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const double *
+pmt_f64vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+double *
+pmt_f64vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_f64vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(double);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_f64vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(double);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_f64vector(pmt_t obj)
+{
+ return obj->is_f64vector();
+}
+
+pmt_t
+make_f64vector(size_t k, double fill)
+{
+ return pmt_t(new pmt_f64vector(k, fill));
+}
+
+pmt_t
+init_f64vector(size_t k, const double *data)
+{
+ return pmt_t(new pmt_f64vector(k, data));
+}
+
+pmt_t
+init_f64vector(size_t k, const std::vector< double > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_f64vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_f64vector(k, static_cast< double >(0))); // fills an empty vector with 0
+}
+
+double
+f64vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_f64vector())
+ throw wrong_type("pmt_f64vector_ref", vector);
+ return _f64vector(vector)->ref(k);
+}
+
+void
+f64vector_set(pmt_t vector, size_t k, double obj)
+{
+ if (!vector->is_f64vector())
+ throw wrong_type("pmt_f64vector_set", vector);
+ _f64vector(vector)->set(k, obj);
+}
+
+const double *
+f64vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_f64vector())
+ throw wrong_type("pmt_f64vector_elements", vector);
+ return _f64vector(vector)->elements(len);
+}
+
+const std::vector< double >
+f64vector_elements(pmt_t vector)
+{
+ if (!vector->is_f64vector())
+ throw wrong_type("pmt_f64vector_elements", vector);
+ size_t len;
+ const double *array = _f64vector(vector)->elements(len);
+ const std::vector< double > vec(array, array+len);
+ return vec;
+}
+
+
+double *
+f64vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_f64vector())
+ throw wrong_type("pmt_f64vector_writable_elements", vector);
+ return _f64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_f64vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, double > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_c32vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_c32vector *
+_c32vector(pmt_t x)
+{
+ return dynamic_cast<pmt_c32vector*>(x.get());
+}
+
+
+pmt_c32vector::pmt_c32vector(size_t k, std::complex<float> fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_c32vector::pmt_c32vector(size_t k, const std::complex<float> *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(std::complex<float>) );
+}
+
+std::complex<float>
+pmt_c32vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_c32vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_c32vector::set(size_t k, std::complex<float> x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_c32vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const std::complex<float> *
+pmt_c32vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+std::complex<float> *
+pmt_c32vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_c32vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(std::complex<float>);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_c32vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(std::complex<float>);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_c32vector(pmt_t obj)
+{
+ return obj->is_c32vector();
+}
+
+pmt_t
+make_c32vector(size_t k, std::complex<float> fill)
+{
+ return pmt_t(new pmt_c32vector(k, fill));
+}
+
+pmt_t
+init_c32vector(size_t k, const std::complex<float> *data)
+{
+ return pmt_t(new pmt_c32vector(k, data));
+}
+
+pmt_t
+init_c32vector(size_t k, const std::vector< std::complex<float> > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_c32vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_c32vector(k, static_cast< std::complex<float> >(0))); // fills an empty vector with 0
+}
+
+std::complex<float>
+c32vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_c32vector())
+ throw wrong_type("pmt_c32vector_ref", vector);
+ return _c32vector(vector)->ref(k);
+}
+
+void
+c32vector_set(pmt_t vector, size_t k, std::complex<float> obj)
+{
+ if (!vector->is_c32vector())
+ throw wrong_type("pmt_c32vector_set", vector);
+ _c32vector(vector)->set(k, obj);
+}
+
+const std::complex<float> *
+c32vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_c32vector())
+ throw wrong_type("pmt_c32vector_elements", vector);
+ return _c32vector(vector)->elements(len);
+}
+
+const std::vector< std::complex<float> >
+c32vector_elements(pmt_t vector)
+{
+ if (!vector->is_c32vector())
+ throw wrong_type("pmt_c32vector_elements", vector);
+ size_t len;
+ const std::complex<float> *array = _c32vector(vector)->elements(len);
+ const std::vector< std::complex<float> > vec(array, array+len);
+ return vec;
+}
+
+
+std::complex<float> *
+c32vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_c32vector())
+ throw wrong_type("pmt_c32vector_writable_elements", vector);
+ return _c32vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_c32vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, std::complex<float> > (ref(k));
+}
+
+} /* namespace pmt */
+////////////////////////////////////////////////////////////////////////////
+// pmt_c64vector
+////////////////////////////////////////////////////////////////////////////
+
+namespace pmt {
+
+static pmt_c64vector *
+_c64vector(pmt_t x)
+{
+ return dynamic_cast<pmt_c64vector*>(x.get());
+}
+
+
+pmt_c64vector::pmt_c64vector(size_t k, std::complex<double> fill)
+ : d_v(k)
+{
+ for (size_t i = 0; i < k; i++)
+ d_v[i] = fill;
+}
+
+pmt_c64vector::pmt_c64vector(size_t k, const std::complex<double> *data)
+ : d_v(k)
+{
+ if(k)
+ memcpy( &d_v[0], data, k * sizeof(std::complex<double>) );
+}
+
+std::complex<double>
+pmt_c64vector::ref(size_t k) const
+{
+ if (k >= length())
+ throw out_of_range("pmt_c64vector_ref", from_long(k));
+ return d_v[k];
+}
+
+void
+pmt_c64vector::set(size_t k, std::complex<double> x)
+{
+ if (k >= length())
+ throw out_of_range("pmt_c64vector_set", from_long(k));
+ d_v[k] = x;
+}
+
+const std::complex<double> *
+pmt_c64vector::elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+std::complex<double> *
+pmt_c64vector::writable_elements(size_t &len)
+{
+ len = length();
+ return len ? &d_v[0] : nullptr;
+}
+
+const void*
+pmt_c64vector::uniform_elements(size_t &len)
+{
+ len = length() * sizeof(std::complex<double>);
+ return len ? &d_v[0] : nullptr;
+}
+
+void*
+pmt_c64vector::uniform_writable_elements(size_t &len)
+{
+ len = length() * sizeof(std::complex<double>);
+ return len ? (&d_v[0]) : nullptr;
+}
+
+bool
+is_c64vector(pmt_t obj)
+{
+ return obj->is_c64vector();
+}
+
+pmt_t
+make_c64vector(size_t k, std::complex<double> fill)
+{
+ return pmt_t(new pmt_c64vector(k, fill));
+}
+
+pmt_t
+init_c64vector(size_t k, const std::complex<double> *data)
+{
+ return pmt_t(new pmt_c64vector(k, data));
+}
+
+pmt_t
+init_c64vector(size_t k, const std::vector< std::complex<double> > &data)
+{
+ if(k) {
+ return pmt_t(new pmt_c64vector(k, &data[0]));
+ }
+ return pmt_t(new pmt_c64vector(k, static_cast< std::complex<double> >(0))); // fills an empty vector with 0
+}
+
+std::complex<double>
+c64vector_ref(pmt_t vector, size_t k)
+{
+ if (!vector->is_c64vector())
+ throw wrong_type("pmt_c64vector_ref", vector);
+ return _c64vector(vector)->ref(k);
+}
+
+void
+c64vector_set(pmt_t vector, size_t k, std::complex<double> obj)
+{
+ if (!vector->is_c64vector())
+ throw wrong_type("pmt_c64vector_set", vector);
+ _c64vector(vector)->set(k, obj);
+}
+
+const std::complex<double> *
+c64vector_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_c64vector())
+ throw wrong_type("pmt_c64vector_elements", vector);
+ return _c64vector(vector)->elements(len);
+}
+
+const std::vector< std::complex<double> >
+c64vector_elements(pmt_t vector)
+{
+ if (!vector->is_c64vector())
+ throw wrong_type("pmt_c64vector_elements", vector);
+ size_t len;
+ const std::complex<double> *array = _c64vector(vector)->elements(len);
+ const std::vector< std::complex<double> > vec(array, array+len);
+ return vec;
+}
+
+
+std::complex<double> *
+c64vector_writable_elements(pmt_t vector, size_t &len)
+{
+ if (!vector->is_c64vector())
+ throw wrong_type("pmt_c64vector_writable_elements", vector);
+ return _c64vector(vector)->writable_elements(len);
+}
+
+const std::string
+pmt_c64vector::string_ref(size_t k) const
+{
+ return boost::lexical_cast< std::string, std::complex<double> > (ref(k));
+}
+
+} /* namespace pmt */
diff --git a/gnuradio-runtime/lib/pmt/pmt_unv_int.h b/gnuradio-runtime/lib/pmt/pmt_unv_int.h
new file mode 100644
index 0000000000..4b4364b411
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/pmt_unv_int.h
@@ -0,0 +1,331 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009,2018 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_PMT_UNV_INT_H
+#define INCLUDED_PMT_UNV_INT_H
+
+#include "pmt_int.h"
+
+#include <vector>
+#include <cstdint>
+
+namespace pmt{
+////////////////////////////////////////////////////////////////////////////
+// pmt_u8vector
+////////////////////////////////////////////////////////////////////////////
+class PMT_API pmt_u8vector : public pmt_uniform_vector
+{
+ std::vector< uint8_t > d_v;
+
+public:
+ pmt_u8vector(size_t k, uint8_t fill);
+ pmt_u8vector(size_t k, const uint8_t *data);
+ // ~pmt_u8vector();
+
+ bool is_u8vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(uint8_t); }
+ uint8_t ref(size_t k) const;
+ void set(size_t k, uint8_t x);
+ const uint8_t *elements(size_t &len);
+ uint8_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_s8vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s8vector : public pmt_uniform_vector
+{
+ std::vector< int8_t > d_v;
+
+public:
+ pmt_s8vector(size_t k, int8_t fill);
+ pmt_s8vector(size_t k, const int8_t *data);
+ // ~pmt_s8vector();
+
+ bool is_s8vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(int8_t); }
+ int8_t ref(size_t k) const;
+ void set(size_t k, int8_t x);
+ const int8_t *elements(size_t &len);
+ int8_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_u16vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u16vector : public pmt_uniform_vector
+{
+ std::vector< uint16_t > d_v;
+
+public:
+ pmt_u16vector(size_t k, uint16_t fill);
+ pmt_u16vector(size_t k, const uint16_t *data);
+ // ~pmt_u16vector();
+
+ bool is_u16vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(uint16_t); }
+ uint16_t ref(size_t k) const;
+ void set(size_t k, uint16_t x);
+ const uint16_t *elements(size_t &len);
+ uint16_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_s16vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s16vector : public pmt_uniform_vector
+{
+ std::vector< int16_t > d_v;
+
+public:
+ pmt_s16vector(size_t k, int16_t fill);
+ pmt_s16vector(size_t k, const int16_t *data);
+ // ~pmt_s16vector();
+
+ bool is_s16vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(int16_t); }
+ int16_t ref(size_t k) const;
+ void set(size_t k, int16_t x);
+ const int16_t *elements(size_t &len);
+ int16_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_u32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u32vector : public pmt_uniform_vector
+{
+ std::vector< uint32_t > d_v;
+
+public:
+ pmt_u32vector(size_t k, uint32_t fill);
+ pmt_u32vector(size_t k, const uint32_t *data);
+ // ~pmt_u32vector();
+
+ bool is_u32vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(uint32_t); }
+ uint32_t ref(size_t k) const;
+ void set(size_t k, uint32_t x);
+ const uint32_t *elements(size_t &len);
+ uint32_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_s32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s32vector : public pmt_uniform_vector
+{
+ std::vector< int32_t > d_v;
+
+public:
+ pmt_s32vector(size_t k, int32_t fill);
+ pmt_s32vector(size_t k, const int32_t *data);
+ // ~pmt_s32vector();
+
+ bool is_s32vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(int32_t); }
+ int32_t ref(size_t k) const;
+ void set(size_t k, int32_t x);
+ const int32_t *elements(size_t &len);
+ int32_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_u64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_u64vector : public pmt_uniform_vector
+{
+ std::vector< uint64_t > d_v;
+
+public:
+ pmt_u64vector(size_t k, uint64_t fill);
+ pmt_u64vector(size_t k, const uint64_t *data);
+ // ~pmt_u64vector();
+
+ bool is_u64vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(uint64_t); }
+ uint64_t ref(size_t k) const;
+ void set(size_t k, uint64_t x);
+ const uint64_t *elements(size_t &len);
+ uint64_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_s64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_s64vector : public pmt_uniform_vector
+{
+ std::vector< int64_t > d_v;
+
+public:
+ pmt_s64vector(size_t k, int64_t fill);
+ pmt_s64vector(size_t k, const int64_t *data);
+ // ~pmt_s64vector();
+
+ bool is_s64vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(int64_t); }
+ int64_t ref(size_t k) const;
+ void set(size_t k, int64_t x);
+ const int64_t *elements(size_t &len);
+ int64_t *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_f32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_f32vector : public pmt_uniform_vector
+{
+ std::vector< float > d_v;
+
+public:
+ pmt_f32vector(size_t k, float fill);
+ pmt_f32vector(size_t k, const float *data);
+ // ~pmt_f32vector();
+
+ bool is_f32vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(float); }
+ float ref(size_t k) const;
+ void set(size_t k, float x);
+ const float *elements(size_t &len);
+ float *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_f64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_f64vector : public pmt_uniform_vector
+{
+ std::vector< double > d_v;
+
+public:
+ pmt_f64vector(size_t k, double fill);
+ pmt_f64vector(size_t k, const double *data);
+ // ~pmt_f64vector();
+
+ bool is_f64vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(double); }
+ double ref(size_t k) const;
+ void set(size_t k, double x);
+ const double *elements(size_t &len);
+ double *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_c32vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_c32vector : public pmt_uniform_vector
+{
+ std::vector< std::complex<float> > d_v;
+
+public:
+ pmt_c32vector(size_t k, std::complex<float> fill);
+ pmt_c32vector(size_t k, const std::complex<float> *data);
+ // ~pmt_c32vector();
+
+ bool is_c32vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(std::complex<float>); }
+ std::complex<float> ref(size_t k) const;
+ void set(size_t k, std::complex<float> x);
+ const std::complex<float> *elements(size_t &len);
+ std::complex<float> *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+
+////////////////////////////////////////////////////////////////////////////
+// pmt_c64vector
+////////////////////////////////////////////////////////////////////////////
+
+class pmt_c64vector : public pmt_uniform_vector
+{
+ std::vector< std::complex<double> > d_v;
+
+public:
+ pmt_c64vector(size_t k, std::complex<double> fill);
+ pmt_c64vector(size_t k, const std::complex<double> *data);
+ // ~pmt_c64vector();
+
+ bool is_c64vector() const { return true; }
+ size_t length() const { return d_v.size(); }
+ size_t itemsize() const { return sizeof(std::complex<double>); }
+ std::complex<double> ref(size_t k) const;
+ void set(size_t k, std::complex<double> x);
+ const std::complex<double> *elements(size_t &len);
+ std::complex<double> *writable_elements(size_t &len);
+ const void *uniform_elements(size_t &len);
+ void *uniform_writable_elements(size_t &len);
+ virtual const std::string string_ref(size_t k) const;
+};
+} /* namespace pmt */
+#endif
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_unv.h b/gnuradio-runtime/lib/pmt/qa_pmt_unv.h
new file mode 100644
index 0000000000..71462a9212
--- /dev/null
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_unv.h
@@ -0,0 +1,61 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Radio
+ *
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ *
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef INCLUDED_QA_PMT_UNV_H
+#define INCLUDED_QA_PMT_UNV_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_pmt_unv : public CppUnit::TestCase {
+
+ CPPUNIT_TEST_SUITE(qa_pmt_unv);
+ CPPUNIT_TEST(test_u8vector);
+ CPPUNIT_TEST(test_s8vector);
+ CPPUNIT_TEST(test_u16vector);
+ CPPUNIT_TEST(test_s16vector);
+ CPPUNIT_TEST(test_u32vector);
+ CPPUNIT_TEST(test_s32vector);
+ CPPUNIT_TEST(test_u64vector);
+ CPPUNIT_TEST(test_s64vector);
+ CPPUNIT_TEST(test_f32vector);
+ CPPUNIT_TEST(test_f64vector);
+ CPPUNIT_TEST(test_c32vector);
+ CPPUNIT_TEST(test_c64vector);
+ CPPUNIT_TEST_SUITE_END();
+
+ private:
+ void test_u8vector();
+ void test_s8vector();
+ void test_u16vector();
+ void test_s16vector();
+ void test_u32vector();
+ void test_s32vector();
+ void test_u64vector();
+ void test_s64vector();
+ void test_f32vector();
+ void test_f64vector();
+ void test_c32vector();
+ void test_c64vector();
+};
+
+#endif
diff --git a/gnuradio-runtime/lib/pmt/unv_template.cc.t b/gnuradio-runtime/lib/pmt/unv_template.cc.t
deleted file mode 100644
index 62b810acab..0000000000
--- a/gnuradio-runtime/lib/pmt/unv_template.cc.t
+++ /dev/null
@@ -1,149 +0,0 @@
-////////////////////////////////////////////////////////////////////////////
-// pmt_@TAG@vector
-////////////////////////////////////////////////////////////////////////////
-
-namespace pmt {
-
-static pmt_@TAG@vector *
-_@TAG@vector(pmt_t x)
-{
- return dynamic_cast<pmt_@TAG@vector*>(x.get());
-}
-
-
-pmt_@TAG@vector::pmt_@TAG@vector(size_t k, @TYPE@ fill)
- : d_v(k)
-{
- for (size_t i = 0; i < k; i++)
- d_v[i] = fill;
-}
-
-pmt_@TAG@vector::pmt_@TAG@vector(size_t k, const @TYPE@ *data)
- : d_v(k)
-{
- if(k)
- memcpy( &d_v[0], data, k * sizeof(@TYPE@) );
-}
-
-@TYPE@
-pmt_@TAG@vector::ref(size_t k) const
-{
- if (k >= length())
- throw out_of_range("pmt_@TAG@vector_ref", from_long(k));
- return d_v[k];
-}
-
-void
-pmt_@TAG@vector::set(size_t k, @TYPE@ x)
-{
- if (k >= length())
- throw out_of_range("pmt_@TAG@vector_set", from_long(k));
- d_v[k] = x;
-}
-
-const @TYPE@ *
-pmt_@TAG@vector::elements(size_t &len)
-{
- len = length();
- return len ? &d_v[0] : NULL;
-}
-
-@TYPE@ *
-pmt_@TAG@vector::writable_elements(size_t &len)
-{
- len = length();
- return len ? &d_v[0] : NULL;
-}
-
-const void*
-pmt_@TAG@vector::uniform_elements(size_t &len)
-{
- len = length() * sizeof(@TYPE@);
- return len ? &d_v[0] : NULL;
-}
-
-void*
-pmt_@TAG@vector::uniform_writable_elements(size_t &len)
-{
- len = length() * sizeof(@TYPE@);
- return len ? (&d_v[0]) : NULL;
-}
-
-bool
-is_@TAG@vector(pmt_t obj)
-{
- return obj->is_@TAG@vector();
-}
-
-pmt_t
-make_@TAG@vector(size_t k, @TYPE@ fill)
-{
- return pmt_t(new pmt_@TAG@vector(k, fill));
-}
-
-pmt_t
-init_@TAG@vector(size_t k, const @TYPE@ *data)
-{
- return pmt_t(new pmt_@TAG@vector(k, data));
-}
-
-pmt_t
-init_@TAG@vector(size_t k, const std::vector< @TYPE@ > &data)
-{
- if(k) {
- return pmt_t(new pmt_@TAG@vector(k, &data[0]));
- }
- return pmt_t(new pmt_@TAG@vector(k, static_cast< @TYPE@ >(0))); // fills an empty vector with 0
-}
-
-@TYPE@
-@TAG@vector_ref(pmt_t vector, size_t k)
-{
- if (!vector->is_@TAG@vector())
- throw wrong_type("pmt_@TAG@vector_ref", vector);
- return _@TAG@vector(vector)->ref(k);
-}
-
-void
-@TAG@vector_set(pmt_t vector, size_t k, @TYPE@ obj)
-{
- if (!vector->is_@TAG@vector())
- throw wrong_type("pmt_@TAG@vector_set", vector);
- _@TAG@vector(vector)->set(k, obj);
-}
-
-const @TYPE@ *
-@TAG@vector_elements(pmt_t vector, size_t &len)
-{
- if (!vector->is_@TAG@vector())
- throw wrong_type("pmt_@TAG@vector_elements", vector);
- return _@TAG@vector(vector)->elements(len);
-}
-
-const std::vector< @TYPE@ >
-@TAG@vector_elements(pmt_t vector)
-{
- if (!vector->is_@TAG@vector())
- throw wrong_type("pmt_@TAG@vector_elements", vector);
- size_t len;
- const @TYPE@ *array = _@TAG@vector(vector)->elements(len);
- const std::vector< @TYPE@ > vec(array, array+len);
- return vec;
-}
-
-
-@TYPE@ *
-@TAG@vector_writable_elements(pmt_t vector, size_t &len)
-{
- if (!vector->is_@TAG@vector())
- throw wrong_type("pmt_@TAG@vector_writable_elements", vector);
- return _@TAG@vector(vector)->writable_elements(len);
-}
-
-const std::string
-pmt_@TAG@vector::string_ref(size_t k) const
-{
- return boost::lexical_cast< std::string, @TYPE@ > (ref(k));
-}
-
-} /* namespace pmt */
diff --git a/gnuradio-runtime/lib/pmt/unv_template.h.t b/gnuradio-runtime/lib/pmt/unv_template.h.t
deleted file mode 100644
index ab5c163570..0000000000
--- a/gnuradio-runtime/lib/pmt/unv_template.h.t
+++ /dev/null
@@ -1,25 +0,0 @@
-
-////////////////////////////////////////////////////////////////////////////
-// pmt_@TAG@vector
-////////////////////////////////////////////////////////////////////////////
-
-class pmt_@TAG@vector : public pmt_uniform_vector
-{
- std::vector< @TYPE@ > d_v;
-
-public:
- pmt_@TAG@vector(size_t k, @TYPE@ fill);
- pmt_@TAG@vector(size_t k, const @TYPE@ *data);
- // ~pmt_@TAG@vector();
-
- bool is_@TAG@vector() const { return true; }
- size_t length() const { return d_v.size(); }
- size_t itemsize() const { return sizeof(@TYPE@); }
- @TYPE@ ref(size_t k) const;
- void set(size_t k, @TYPE@ x);
- const @TYPE@ *elements(size_t &len);
- @TYPE@ *writable_elements(size_t &len);
- const void *uniform_elements(size_t &len);
- void *uniform_writable_elements(size_t &len);
- virtual const std::string string_ref(size_t k) const;
-};
diff --git a/gnuradio-runtime/lib/posix_memalign.cc b/gnuradio-runtime/lib/posix_memalign.cc
deleted file mode 100644
index eb3bbe3e0f..0000000000
--- a/gnuradio-runtime/lib/posix_memalign.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "posix_memalign.h"
-
-#ifdef HAVE_MALLOC_H
-// for Cygwin valloc () prototype
-#include <malloc.h>
-#endif
-
-#ifndef HAVE_POSIX_MEMALIGN
-
-/* emulate posix_memalign functionality, to some degree */
-
-#include <errno.h>
-#include "pagesize.h"
-
-int posix_memalign
-(void **memptr, size_t alignment, size_t size)
-{
- /* emulate posix_memalign functionality, to some degree */
-
- /* make sure the return handle is valid; return "bad address" if not valid */
- if (memptr == 0)
- return (EFAULT);
- *memptr = (void*) 0;
-
- /* make sure 'alignment' is a power of 2
- * and multiple of sizeof (void*)
- */
-
- /* make sure 'alignment' is a multiple of sizeof (void*) */
- if ((alignment % sizeof (void*)) != 0)
- return (EINVAL);
-
- /* make sure 'alignment' is a power of 2 */
- if ((alignment & (alignment - 1)) != 0)
- return (EINVAL);
-
- /* good alignment */
-
-#if (ALIGNED_MALLOC != 0)
-
- /* if 'malloc' is known to be aligned, and the desired 'alignment'
- * matches is <= that provided by 'malloc', then use 'malloc'. This
- * works on, e.g., Darwin for which malloc is 16-byte aligned.
- */
- size_t am = (size_t) ALIGNED_MALLOC;
- if (alignment <= am) {
- /* make sure ALIGNED_MALLOC is a power of 2, to guarantee that the
- * alignment is correct (since 'alignment' must be a power of 2).
- */
- if ((am & (am - 1)) != 0)
- return (EINVAL);
- /* good malloc alignment */
- *memptr = malloc (size);
- }
-
-#endif /* (ALIGNED_MALLOC != 0) */
-#ifdef HAVE_VALLOC
-
- if (*memptr == (void*) 0) {
- /* try valloc if it exists */
- /* cheap and easy way to make sure alignment is met, so long as it
- * is <= pagesize () */
- if (alignment <= (size_t) gr::pagesize ()) {
- *memptr = valloc (size);
- }
- }
-
-#endif /* HAVE_VALLOC */
-
-#if (ALIGNED_MALLOC == 0) && !defined (HAVE_VALLOC)
- /* no posix_memalign, valloc, and malloc isn't known to be aligned
- * (enough for the input arguments); no idea what to do.
- */
-
-#error gnuradio-runtime/lib/posix_memalign.cc: Cannot find a way to alloc aligned memory.
-
-#endif
-
- /* if the pointer wasn't allocated properly, return that there was
- * not enough memory to allocate; otherwise, return OK (0).
- */
- if (*memptr == (void*) 0)
- return (ENOMEM);
- else
- return (0);
-};
-
-#endif /* ! HAVE_POSIX_MEMALIGN */
diff --git a/gnuradio-runtime/lib/posix_memalign.h b/gnuradio-runtime/lib/posix_memalign.h
deleted file mode 100644
index ea79ced2ef..0000000000
--- a/gnuradio-runtime/lib/posix_memalign.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef _POSIX_MEMALIGN_H_
-#define _POSIX_MEMALIGN_H_
-
-#include <stdlib.h>
-
-#ifndef HAVE_POSIX_MEMALIGN
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int posix_memalign (void** memptr, size_t alignment, size_t size);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* ! HAVE_POSIX_MEMALIGN */
-
-#endif /* _POSIX_MEMALIGN_H_ */
diff --git a/gnuradio-runtime/lib/qa_logger.cc b/gnuradio-runtime/lib/qa_logger.cc
index b74a0c0e27..dc47b53cef 100644
--- a/gnuradio-runtime/lib/qa_logger.cc
+++ b/gnuradio-runtime/lib/qa_logger.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2012 Free Software Foundation, Inc.
+ * Copyright 2012, 2018 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
diff --git a/gnuradio-runtime/lib/scheduler_sts.cc b/gnuradio-runtime/lib/scheduler_sts.cc
deleted file mode 100644
index 19d05b2316..0000000000
--- a/gnuradio-runtime/lib/scheduler_sts.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2013 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "scheduler_sts.h"
-#include "single_threaded_scheduler.h"
-#include <gnuradio/thread/thread_body_wrapper.h>
-
-namespace gr {
-
- class sts_container
- {
- block_vector_t d_blocks;
-
- public:
- sts_container(block_vector_t blocks)
- : d_blocks(blocks) {}
-
- void operator()()
- {
- make_single_threaded_scheduler(d_blocks)->run();
- }
- };
-
- scheduler_sptr
- scheduler_sts::make(flat_flowgraph_sptr ffg, int max_noutput_items)
- {
- return scheduler_sptr(new scheduler_sts(ffg, max_noutput_items));
- }
-
- scheduler_sts::scheduler_sts(flat_flowgraph_sptr ffg, int max_noutput_items)
- : scheduler(ffg, max_noutput_items)
- {
- // Split the flattened flow graph into discrete partitions, each
- // of which is topologically sorted.
-
- std::vector<basic_block_vector_t> graphs = ffg->partition();
-
- // For each partition, create a thread to evaluate it using
- // an instance of the gr_single_threaded_scheduler
-
- for(std::vector<basic_block_vector_t>::iterator p = graphs.begin();
- p != graphs.end(); p++) {
-
- block_vector_t blocks = flat_flowgraph::make_block_vector(*p);
- d_threads.create_thread(
- gr::thread::thread_body_wrapper<sts_container>(sts_container(blocks),
- "single-threaded-scheduler"));
- }
- }
-
- scheduler_sts::~scheduler_sts()
- {
- stop();
- }
-
- void
- scheduler_sts::stop()
- {
- d_threads.interrupt_all();
- }
-
- void
- scheduler_sts::wait()
- {
- d_threads.join_all();
- }
-
-} /* namespace gr */
diff --git a/gnuradio-runtime/lib/scheduler_sts.h b/gnuradio-runtime/lib/scheduler_sts.h
deleted file mode 100644
index b4cddb4614..0000000000
--- a/gnuradio-runtime/lib/scheduler_sts.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2013 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef INCLUDED_GR_SCHEDULER_STS_H
-#define INCLUDED_GR_SCHEDULER_STS_H
-
-#include <gnuradio/api.h>
-#include <gnuradio/thread/thread_group.h>
-#include "scheduler.h"
-
-namespace gr {
-
- /*!
- * \brief Concrete scheduler that uses the single_threaded_scheduler
- */
- class GR_RUNTIME_API scheduler_sts : public scheduler
- {
- gr::thread::thread_group d_threads;
-
- protected:
- /*!
- * \brief Construct a scheduler and begin evaluating the graph.
- *
- * The scheduler will continue running until all blocks until they
- * report that they are done or the stop method is called.
- */
- scheduler_sts(flat_flowgraph_sptr ffg, int max_noutput_items);
-
- public:
- static scheduler_sptr make(flat_flowgraph_sptr ffg,
- int max_noutput_items);
-
- ~scheduler_sts();
-
- /*!
- * \brief Tell the scheduler to stop executing.
- */
- void stop();
-
- /*!
- * \brief Block until the graph is done.
- */
- void wait();
- };
-
-} /* namespace gr */
-
-#endif /* INCLUDED_GR_SCHEDULER_STS_H */
diff --git a/gnuradio-runtime/lib/single_threaded_scheduler.cc b/gnuradio-runtime/lib/single_threaded_scheduler.cc
deleted file mode 100644
index a85f390a30..0000000000
--- a/gnuradio-runtime/lib/single_threaded_scheduler.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "single_threaded_scheduler.h"
-#include <gnuradio/block.h>
-#include <gnuradio/block_detail.h>
-#include <gnuradio/buffer.h>
-#include <boost/thread.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-#include <limits>
-#include <assert.h>
-#include <stdio.h>
-
-namespace gr {
-
- // must be defined to either 0 or 1
-#define ENABLE_LOGGING 0
-
-#if (ENABLE_LOGGING)
-#define LOG(x) do { x; } while(0)
-#else
-#define LOG(x) do {;} while(0)
-#endif
-
- static int which_scheduler = 0;
-
- single_threaded_scheduler_sptr
- make_single_threaded_scheduler(const std::vector<block_sptr> &blocks)
- {
- return single_threaded_scheduler_sptr
- (new single_threaded_scheduler(blocks));
- }
-
- single_threaded_scheduler::single_threaded_scheduler(const std::vector<block_sptr> &blocks)
- : d_blocks(blocks), d_enabled(true), d_log(0)
- {
- if(ENABLE_LOGGING) {
- std::string name = str(boost::format("sst-%d.log") % which_scheduler++);
- d_log = new std::ofstream(name.c_str());
- *d_log << "single_threaded_scheduler: "
- << d_blocks.size ()
- << " blocks\n";
- }
- }
-
- single_threaded_scheduler::~single_threaded_scheduler()
- {
- if(ENABLE_LOGGING)
- delete d_log;
- }
-
- void
- single_threaded_scheduler::run()
- {
- // d_enabled = true; // KLUDGE
- main_loop ();
- }
-
- void
- single_threaded_scheduler::stop()
- {
- if(0)
- std::cout << "gr_singled_threaded_scheduler::stop() "
- << this << std::endl;
- d_enabled = false;
- }
-
- inline static unsigned int
- round_up(unsigned int n, unsigned int multiple)
- {
- return ((n + multiple - 1) / multiple) * multiple;
- }
-
- inline static unsigned int
- round_down(unsigned int n, unsigned int multiple)
- {
- return (n / multiple) * multiple;
- }
-
- //
- // Return minimum available write space in all our downstream
- // buffers or -1 if we're output blocked and the output we're
- // blocked on is done.
- //
- static int
- min_available_space(block_detail *d, int output_multiple)
- {
- int min_space = std::numeric_limits<int>::max();
-
- for(int i = 0; i < d->noutputs (); i++) {
- buffer_sptr out_buf = d->output(i);
- int n = round_down (out_buf->space_available (), output_multiple);
- if(n == 0) { // We're blocked on output.
- if(out_buf->done()) { // Downstream is done, therefore we're done.
- return -1;
- }
- return 0;
- }
- min_space = std::min (min_space, n);
- }
- return min_space;
- }
-
- void
- single_threaded_scheduler::main_loop()
- {
- static const int DEFAULT_CAPACITY = 16;
-
- int noutput_items;
- gr_vector_int ninput_items_required(DEFAULT_CAPACITY);
- gr_vector_int ninput_items(DEFAULT_CAPACITY);
- gr_vector_const_void_star input_items(DEFAULT_CAPACITY);
- gr_vector_void_star output_items(DEFAULT_CAPACITY);
- unsigned int bi;
- unsigned int nalive;
- int max_items_avail;
- bool made_progress_last_pass;
- bool making_progress;
-
- for(unsigned i = 0; i < d_blocks.size (); i++)
- d_blocks[i]->detail()->set_done (false); // reset any done flags
-
- for(unsigned i = 0; i < d_blocks.size (); i++) // enable any drivers, etc.
- d_blocks[i]->start();
-
- bi = 0;
- made_progress_last_pass = true;
- making_progress = false;
-
- // Loop while there are still blocks alive
-
- nalive = d_blocks.size ();
- while(d_enabled && nalive > 0) {
- if(boost::this_thread::interruption_requested())
- break;
-
- block *m = d_blocks[bi].get ();
- block_detail *d = m->detail().get ();
-
- LOG(*d_log << std::endl << m);
-
- if(d->done ())
- goto next_block;
-
- if(d->source_p ()) {
- // Invoke sources as a last resort. As long as the previous
- // pass made progress, don't call a source.
- if(made_progress_last_pass) {
- LOG(*d_log << " Skipping source\n");
- goto next_block;
- }
-
- ninput_items_required.resize (0);
- ninput_items.resize (0);
- input_items.resize (0);
- output_items.resize (d->noutputs ());
-
- // determine the minimum available output space
- noutput_items = min_available_space (d, m->output_multiple ());
- LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl);
- if(noutput_items == -1) // we're done
- goto were_done;
-
- if(noutput_items == 0) { // we're output blocked
- LOG(*d_log << " BLKD_OUT\n");
- goto next_block;
- }
-
- goto setup_call_to_work; // jump to common code
- }
-
- else if(d->sink_p ()) {
- ninput_items_required.resize (d->ninputs ());
- ninput_items.resize (d->ninputs ());
- input_items.resize (d->ninputs ());
- output_items.resize (0);
- LOG(*d_log << " sink\n");
-
- max_items_avail = 0;
- for(int i = 0; i < d->ninputs (); i++) {
- buffer_reader_sptr in_buf = d->input(i);
- ninput_items[i] = in_buf->items_available();
- //if (ninput_items[i] == 0 && in_buf->done())
- if(ninput_items[i] < m->output_multiple() && in_buf->done())
- goto were_done;
-
- max_items_avail = std::max (max_items_avail, ninput_items[i]);
- }
-
- // take a swag at how much output we can sink
- noutput_items = (int) (max_items_avail * m->relative_rate ());
- noutput_items = round_down (noutput_items, m->output_multiple ());
- LOG(*d_log << " max_items_avail = " << max_items_avail << std::endl);
- LOG(*d_log << " noutput_items = " << noutput_items << std::endl);
-
- if(noutput_items == 0) { // we're blocked on input
- LOG(*d_log << " BLKD_IN\n");
- goto next_block;
- }
-
- goto try_again; // Jump to code shared with regular case.
- }
-
- else {
- // do the regular thing
- ninput_items_required.resize(d->ninputs ());
- ninput_items.resize(d->ninputs ());
- input_items.resize(d->ninputs ());
- output_items.resize(d->noutputs ());
-
- max_items_avail = 0;
- for(int i = 0; i < d->ninputs (); i++) {
- ninput_items[i] = d->input(i)->items_available ();
- max_items_avail = std::max(max_items_avail, ninput_items[i]);
- }
-
- // determine the minimum available output space
- noutput_items = min_available_space(d, m->output_multiple ());
- if(ENABLE_LOGGING){
- *d_log << " regular ";
- if(m->relative_rate() >= 1.0)
- *d_log << "1:" << m->relative_rate() << std::endl;
- else
- *d_log << 1.0/m->relative_rate() << ":1\n";
- *d_log << " max_items_avail = " << max_items_avail << std::endl;
- *d_log << " noutput_items = " << noutput_items << std::endl;
- }
- if(noutput_items == -1) // we're done
- goto were_done;
-
- if(noutput_items == 0) { // we're output blocked
- LOG(*d_log << " BLKD_OUT\n");
- goto next_block;
- }
-
-#if 0
- // Compute best estimate of noutput_items that we can really use.
- noutput_items =
- std::min((unsigned)noutput_items,
- std::max((unsigned)m->output_multiple(),
- round_up((unsigned)(max_items_avail * m->relative_rate()),
- m->output_multiple())));
-
- LOG(*d_log << " revised noutput_items = " << noutput_items << std::endl);
-#endif
-
- try_again:
- if(m->fixed_rate()) {
- // try to work it forward starting with max_items_avail.
- // We want to try to consume all the input we've got.
- int reqd_noutput_items = m->fixed_rate_ninput_to_noutput(max_items_avail);
- reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple());
- if(reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
- noutput_items = reqd_noutput_items;
- }
-
- // ask the block how much input they need to produce noutput_items
- m->forecast(noutput_items, ninput_items_required);
-
- // See if we've got sufficient input available
- int i;
- for(i = 0; i < d->ninputs (); i++)
- if(ninput_items_required[i] > ninput_items[i]) // not enough
- break;
-
- if(i < d->ninputs()) { // not enough input on input[i]
- // if we can, try reducing the size of our output request
- if(noutput_items > m->output_multiple ()){
- noutput_items /= 2;
- noutput_items = round_up (noutput_items, m->output_multiple ());
- goto try_again;
- }
-
- // We're blocked on input
- buffer_reader_sptr in_buf = d->input(i);
- LOG(*d_log << " BLKD_IN\n");
- if(in_buf->done()) // If the upstream block is done, we're done
- goto were_done;
-
- // Is it possible to ever fulfill this request?
- if(ninput_items_required[i] > in_buf->max_possible_items_available ()) {
- // Nope, never going to happen...
- std::cerr << "\nsched: <block " << m->name()
- << " (" << m->unique_id() << ")>"
- << " is requesting more input data\n"
- << " than we can provide.\n"
- << " ninput_items_required = "
- << ninput_items_required[i] << "\n"
- << " max_possible_items_available = "
- << in_buf->max_possible_items_available() << "\n"
- << " If this is a filter, consider reducing the number of taps.\n";
- goto were_done;
- }
-
- goto next_block;
- }
-
- // We've got enough data on each input to produce noutput_items.
- // Finish setting up the call to work.
- for(int i = 0; i < d->ninputs (); i++)
- input_items[i] = d->input(i)->read_pointer();
-
- setup_call_to_work:
-
- for(int i = 0; i < d->noutputs (); i++)
- output_items[i] = d->output(i)->write_pointer();
-
- // Do the actual work of the block
- int n = m->general_work(noutput_items, ninput_items,
- input_items, output_items);
- LOG(*d_log << " general_work: noutput_items = " << noutput_items
- << " result = " << n << std::endl);
-
- if(n == -1) // block is done
- goto were_done;
-
- d->produce_each(n); // advance write pointers
- if(n > 0)
- making_progress = true;
-
- goto next_block;
- }
- assert(0);
-
- were_done:
- LOG(*d_log << " were_done\n");
- d->set_done (true);
- nalive--;
-
- next_block:
- if(++bi >= d_blocks.size ()) {
- bi = 0;
- made_progress_last_pass = making_progress;
- making_progress = false;
- }
- }
-
- for(unsigned i = 0; i < d_blocks.size(); i++) // disable any drivers, etc.
- d_blocks[i]->stop();
- }
-
-} /* namespace gr */
diff --git a/gnuradio-runtime/lib/single_threaded_scheduler.h b/gnuradio-runtime/lib/single_threaded_scheduler.h
deleted file mode 100644
index eccbf03b36..0000000000
--- a/gnuradio-runtime/lib/single_threaded_scheduler.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GNU Radio; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
-#define INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H
-
-#include <gnuradio/api.h>
-#include <gnuradio/runtime_types.h>
-#include <fstream>
-
-namespace gr {
-
- class single_threaded_scheduler;
- typedef boost::shared_ptr<single_threaded_scheduler> single_threaded_scheduler_sptr;
-
- /*!
- * \brief Simple scheduler for stream computations.
- * \ingroup internal
- */
- class GR_RUNTIME_API single_threaded_scheduler
- {
- public:
- ~single_threaded_scheduler();
-
- void run();
- void stop();
-
- private:
- const std::vector<block_sptr> d_blocks;
- volatile bool d_enabled;
- std::ofstream *d_log;
-
- single_threaded_scheduler(const std::vector<block_sptr> &blocks);
-
- void main_loop();
-
- friend GR_RUNTIME_API single_threaded_scheduler_sptr
- make_single_threaded_scheduler(const std::vector<block_sptr> &blocks);
- };
-
- GR_RUNTIME_API single_threaded_scheduler_sptr
- make_single_threaded_scheduler(const std::vector<block_sptr> &blocks);
-
-} /* namespace gr */
-
-#endif /* INCLUDED_GR_SINGLE_THREADED_SCHEDULER_H */
diff --git a/gnuradio-runtime/lib/sptr_magic.cc b/gnuradio-runtime/lib/sptr_magic.cc
index e5e83722fc..bffef04756 100644
--- a/gnuradio-runtime/lib/sptr_magic.cc
+++ b/gnuradio-runtime/lib/sptr_magic.cc
@@ -102,4 +102,4 @@ namespace gnuradio {
s_map.erase(pos);
return sptr;
}
-};
+}
diff --git a/gnuradio-runtime/lib/sys_pri.cc b/gnuradio-runtime/lib/sys_pri.cc
deleted file mode 100644
index aa005ecd75..0000000000
--- a/gnuradio-runtime/lib/sys_pri.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008 Free Software Foundation, Inc.
- *
- * This file is part of GNU Radio
- *
- * GNU Radio is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3, or (at your option)
- * any later version.
- *
- * GNU Radio is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <sys_pri.h>
-
-namespace gr {
-
- /*
- * These may need per-OS tweaking.
- *
- * Under linux virtual_pri -> system_pri
- * 0 -> 0
- * 1 -> 5
- * 2 -> 10
- * 3 -> 15
- * 4 -> 20 // typically used by jack and pulse audio
- * 5 -> 25
- * 6 -> 30
- * 7 -> 35
- * 8 -> 40
- * 9 -> 45
- * 10 -> 50
- * 11 -> 54
- * 12 -> 59
- * 13 -> 64
- * 14 -> 69
- * 15 -> 74
- */
- rt_sched_param
- sys_pri::python() { return rt_sched_param(0, RT_SCHED_RR); }
-
- rt_sched_param
- sys_pri::normal() { return rt_sched_param(2, RT_SCHED_RR); }
-
- rt_sched_param
- sys_pri::gcell_event_handler(){ return rt_sched_param(5, RT_SCHED_FIFO); }
-
- rt_sched_param
- sys_pri::usrp2_backend() { return rt_sched_param(6, RT_SCHED_FIFO); }
-
-} /* namespace gr */
diff --git a/gnuradio-runtime/lib/thread/thread_group.cc b/gnuradio-runtime/lib/thread/thread_group.cc
index e467dfda5a..637525e19e 100644
--- a/gnuradio-runtime/lib/thread/thread_group.cc
+++ b/gnuradio-runtime/lib/thread/thread_group.cc
@@ -37,7 +37,7 @@ namespace gr {
{
// No scoped_lock required here since the only "shared data" that's
// modified here occurs inside add_thread which does scoped_lock.
- std::auto_ptr<boost::thread> thrd(new boost::thread(threadfunc));
+ std::unique_ptr<boost::thread> thrd(new boost::thread(threadfunc));
add_thread(thrd.get());
return thrd.release();
}
diff --git a/gnuradio-runtime/lib/top_block_impl.cc b/gnuradio-runtime/lib/top_block_impl.cc
index 3f94867bc2..d2a07e89ef 100644
--- a/gnuradio-runtime/lib/top_block_impl.cc
+++ b/gnuradio-runtime/lib/top_block_impl.cc
@@ -26,7 +26,6 @@
#include "top_block_impl.h"
#include "flat_flowgraph.h"
-#include "scheduler_sts.h"
#include "scheduler_tpb.h"
#include <gnuradio/top_block.h>
#include <gnuradio/prefs.h>
@@ -48,8 +47,7 @@ namespace gr {
const char *name;
scheduler_maker f;
} scheduler_table[] = {
- { "TPB", scheduler_tpb::make }, // first entry is default
- { "STS", scheduler_sts::make }
+ { "TPB", scheduler_tpb::make } // first entry is default
};
static scheduler_sptr
diff --git a/gnuradio-runtime/lib/tpb_thread_body.cc b/gnuradio-runtime/lib/tpb_thread_body.cc
index 45762b17f4..fa9de60ae3 100644
--- a/gnuradio-runtime/lib/tpb_thread_body.cc
+++ b/gnuradio-runtime/lib/tpb_thread_body.cc
@@ -55,8 +55,6 @@ namespace gr {
size_t max_nmsgs = static_cast<size_t>(p->get_long("DEFAULT", "max_messages", 100));
// Setup the logger for the scheduler
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
#undef LOG
std::string config_file = p->get_string("LOG", "log_config", "");
std::string log_level = p->get_string("LOG", "log_level", "off");
@@ -75,9 +73,6 @@ namespace gr {
GR_LOG_SET_FILE_APPENDER(LOG, log_file , true,"%r :%p: %c{1} - %m%n");
}
}
-#endif /* HAVE_LOG4CPP */
-#endif /* ENABLE_GR_LOG */
-
// Set thread affinity if it was set before fg was started.
if(block->processor_affinity().size() > 0) {
@@ -94,9 +89,10 @@ namespace gr {
start_sync->wait();
while(1) {
- tpb_loop_top:
boost::this_thread::interruption_point();
+ d->d_tpb.clear_changed();
+
// handle any queued up messages
BOOST_FOREACH(basic_block::msg_queue_map_t::value_type &i, block->msg_queue) {
// Check if we have a message handler attached before getting
@@ -117,97 +113,57 @@ namespace gr {
}
}
- d->d_tpb.clear_changed();
// run one iteration if we are a connected stream block
if(d->noutputs() >0 || d->ninputs()>0){
s = d_exec.run_one_iteration();
}
else {
s = block_executor::BLKD_IN;
+ // a msg port only block wants to shutdown
+ if(block->finished()) {
+ s = block_executor::DONE;
+ }
}
- // if msg ports think we are done, we are done
- if(block->finished())
+ if(block->finished() && s == block_executor::READY_NO_OUTPUT) {
s = block_executor::DONE;
+ d->set_done(true);
+ }
+
+ if(!d->ninputs() && s == block_executor::READY_NO_OUTPUT) {
+ s = block_executor::BLKD_IN;
+ }
switch(s){
- case block_executor::READY: // Tell neighbors we made progress.
+ case block_executor::READY: // Tell neighbors we made progress.
d->d_tpb.notify_neighbors(d);
break;
- case block_executor::READY_NO_OUTPUT: // Notify upstream only
+ case block_executor::READY_NO_OUTPUT: // Notify upstream only
d->d_tpb.notify_upstream(d);
break;
- case block_executor::DONE: // Game over.
+ case block_executor::DONE: // Game over.
block->notify_msg_neighbors();
d->d_tpb.notify_neighbors(d);
return;
- case block_executor::BLKD_IN: // Wait for input.
+ case block_executor::BLKD_IN: // Wait for input.
{
gr::thread::scoped_lock guard(d->d_tpb.mutex);
- while(!d->d_tpb.input_changed) {
-
- // wait for input or message
- while(!d->d_tpb.input_changed && block->empty_handled_p()){
- boost::system_time const timeout=boost::get_system_time()+ boost::posix_time::milliseconds(250);
- if(!d->d_tpb.input_cond.timed_wait(guard, timeout)){
- goto tpb_loop_top; // timeout occurred (perform sanity checks up top)
- }
- }
- // handle all pending messages
- BOOST_FOREACH(basic_block::msg_queue_map_t::value_type &i, block->msg_queue) {
- if(block->has_msg_handler(i.first)) {
- while((msg = block->delete_head_nowait(i.first))) {
- guard.unlock(); // release lock while processing msg
- block->dispatch_msg(i.first, msg);
- guard.lock();
- }
- }
- else {
- // leave msg in queue if no handler is defined
- // start dropping if we have too many
- if(block->nmsgs(i.first) > max_nmsgs){
- GR_LOG_WARN(LOG,"asynchronous message buffer overflowing, dropping message");
- msg = block->delete_head_nowait(i.first);
- }
- }
- }
- if (d->done()) {
- return;
- }
+ if(!d->d_tpb.input_changed) {
+ boost::system_time const timeout=boost::get_system_time()+ boost::posix_time::milliseconds(250);
+ d->d_tpb.input_cond.timed_wait(guard, timeout);
}
}
break;
- case block_executor::BLKD_OUT: // Wait for output buffer space.
+ case block_executor::BLKD_OUT: // Wait for output buffer space.
{
- gr::thread::scoped_lock guard(d->d_tpb.mutex);
- while(!d->d_tpb.output_changed) {
- // wait for output room or message
- while(!d->d_tpb.output_changed && block->empty_handled_p())
- d->d_tpb.output_cond.wait(guard);
-
- // handle all pending messages
- BOOST_FOREACH(basic_block::msg_queue_map_t::value_type &i, block->msg_queue) {
- if(block->has_msg_handler(i.first)) {
- while((msg = block->delete_head_nowait(i.first))) {
- guard.unlock(); // release lock while processing msg
- block->dispatch_msg(i.first, msg);
- guard.lock();
- }
- }
- else {
- // leave msg in queue if no handler is defined
- // start dropping if we have too many
- if(block->nmsgs(i.first) > max_nmsgs){
- GR_LOG_WARN(LOG,"asynchronous message buffer overflowing, dropping message");
- msg = block->delete_head_nowait(i.first);
- }
- }
- }
+ gr::thread::scoped_lock guard(d->d_tpb.mutex);
+ while(!d->d_tpb.output_changed) {
+ d->d_tpb.output_cond.wait(guard);
}
}
break;