summaryrefslogtreecommitdiff
path: root/gnuradio-runtime/lib
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2013-04-17 13:43:52 -0400
committerTom Rondeau <trondeau@vt.edu>2013-04-29 14:52:56 -0400
commitf3e2e07201c50033bf6c9d0c6a6f068557b4f17f (patch)
tree140b3c2d20a951ffd4abd564c3378ee2e2f9fc7c /gnuradio-runtime/lib
parent35303ae975a5b1bdecc2492bc96e2b8e89b62a3d (diff)
runtime: converting runtime core to gr namespace, gnuradio include dir.
Diffstat (limited to 'gnuradio-runtime/lib')
-rw-r--r--gnuradio-runtime/lib/CMakeLists.txt182
-rw-r--r--gnuradio-runtime/lib/basic_block.cc233
-rw-r--r--gnuradio-runtime/lib/block.cc689
-rw-r--r--gnuradio-runtime/lib/block_detail.cc474
-rw-r--r--gnuradio-runtime/lib/block_executor.cc489
-rw-r--r--gnuradio-runtime/lib/block_executor.h78
-rw-r--r--gnuradio-runtime/lib/block_gateway_impl.cc186
-rw-r--r--gnuradio-runtime/lib/block_gateway_impl.h75
-rw-r--r--gnuradio-runtime/lib/block_registry.cc120
-rw-r--r--gnuradio-runtime/lib/buffer.cc343
-rw-r--r--gnuradio-runtime/lib/circular_file.cc208
-rw-r--r--gnuradio-runtime/lib/circular_file.h65
-rw-r--r--gnuradio-runtime/lib/complex_vec_test.h24
-rw-r--r--gnuradio-runtime/lib/constants.cc.in (renamed from gnuradio-runtime/lib/gr_constants.cc.in)68
-rw-r--r--gnuradio-runtime/lib/controlport/CMakeLists.txt62
-rw-r--r--gnuradio-runtime/lib/controlport/ICE_LICENSE (renamed from gnuradio-runtime/lib/ICE_LICENSE)0
-rw-r--r--gnuradio-runtime/lib/controlport/frontend.ice (renamed from gnuradio-runtime/lib/frontend.ice)0
-rw-r--r--gnuradio-runtime/lib/controlport/gnuradio.ice (renamed from gnuradio-runtime/lib/gnuradio.ice)0
-rw-r--r--gnuradio-runtime/lib/controlport/ice_application_base.cc (renamed from gnuradio-runtime/lib/ice_application_base.cc)2
-rw-r--r--gnuradio-runtime/lib/controlport/rpcmanager.cc (renamed from gnuradio-runtime/lib/rpcmanager.cc)2
-rw-r--r--gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc (renamed from gnuradio-runtime/lib/rpcpmtconverters_ice.cc)2
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_aggregator.cc (renamed from gnuradio-runtime/lib/rpcserver_aggregator.cc)4
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc (renamed from gnuradio-runtime/lib/rpcserver_booter_aggregator.cc)2
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_booter_ice.cc (renamed from gnuradio-runtime/lib/rpcserver_booter_ice.cc)4
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_ice.cc (renamed from gnuradio-runtime/lib/rpcserver_ice.cc)2
-rw-r--r--gnuradio-runtime/lib/controlport/rpcserver_selector.cc (renamed from gnuradio-runtime/lib/rpcserver_selector.cc)8
-rw-r--r--gnuradio-runtime/lib/dispatcher.cc195
-rw-r--r--gnuradio-runtime/lib/error_handler.cc249
-rw-r--r--gnuradio-runtime/lib/feval.cc136
-rw-r--r--gnuradio-runtime/lib/flat_flowgraph.cc436
-rw-r--r--gnuradio-runtime/lib/flat_flowgraph.h93
-rw-r--r--gnuradio-runtime/lib/flowgraph.cc519
-rw-r--r--gnuradio-runtime/lib/gr_basic_block.cc226
-rw-r--r--gnuradio-runtime/lib/gr_block.cc687
-rw-r--r--gnuradio-runtime/lib/gr_block_detail.cc473
-rw-r--r--gnuradio-runtime/lib/gr_block_executor.cc487
-rw-r--r--gnuradio-runtime/lib/gr_block_executor.h78
-rw-r--r--gnuradio-runtime/lib/gr_block_registry.cc98
-rw-r--r--gnuradio-runtime/lib/gr_buffer.cc347
-rw-r--r--gnuradio-runtime/lib/gr_circular_file.cc203
-rw-r--r--gnuradio-runtime/lib/gr_circular_file.h60
-rw-r--r--gnuradio-runtime/lib/gr_dispatcher.cc193
-rw-r--r--gnuradio-runtime/lib/gr_error_handler.cc244
-rw-r--r--gnuradio-runtime/lib/gr_fast_atan2f.cc199
-rw-r--r--gnuradio-runtime/lib/gr_feval.cc132
-rw-r--r--gnuradio-runtime/lib/gr_flat_flowgraph.cc427
-rw-r--r--gnuradio-runtime/lib/gr_flat_flowgraph.h89
-rw-r--r--gnuradio-runtime/lib/gr_flowgraph.cc514
-rw-r--r--gnuradio-runtime/lib/gr_hier_block2.cc153
-rw-r--r--gnuradio-runtime/lib/gr_hier_block2_detail.cc641
-rw-r--r--gnuradio-runtime/lib/gr_hier_block2_detail.h74
-rw-r--r--gnuradio-runtime/lib/gr_io_signature.cc112
-rw-r--r--gnuradio-runtime/lib/gr_local_sighandler.cc187
-rw-r--r--gnuradio-runtime/lib/gr_logger.cc295
-rw-r--r--gnuradio-runtime/lib/gr_message.cc78
-rw-r--r--gnuradio-runtime/lib/gr_misc.cc65
-rw-r--r--gnuradio-runtime/lib/gr_msg_queue.cc125
-rw-r--r--gnuradio-runtime/lib/gr_preferences.cc108
-rw-r--r--gnuradio-runtime/lib/gr_prefs.cc391
-rw-r--r--gnuradio-runtime/lib/gr_random.cc183
-rw-r--r--gnuradio-runtime/lib/gr_random.h65
-rw-r--r--gnuradio-runtime/lib/gr_realtime.cc33
-rw-r--r--gnuradio-runtime/lib/gr_reverse.h34
-rw-r--r--gnuradio-runtime/lib/gr_scheduler.h65
-rw-r--r--gnuradio-runtime/lib/gr_scheduler_sts.cc87
-rw-r--r--gnuradio-runtime/lib/gr_scheduler_sts.h63
-rw-r--r--gnuradio-runtime/lib/gr_scheduler_tpb.cc103
-rw-r--r--gnuradio-runtime/lib/gr_scheduler_tpb.h61
-rw-r--r--gnuradio-runtime/lib/gr_single_threaded_scheduler.cc364
-rw-r--r--gnuradio-runtime/lib/gr_sync_block.cc68
-rw-r--r--gnuradio-runtime/lib/gr_sync_decimator.cc69
-rw-r--r--gnuradio-runtime/lib/gr_sync_interpolator.cc70
-rw-r--r--gnuradio-runtime/lib/gr_tagged_stream_block.cc146
-rw-r--r--gnuradio-runtime/lib/gr_test.cc177
-rw-r--r--gnuradio-runtime/lib/gr_test.h195
-rw-r--r--gnuradio-runtime/lib/gr_top_block.cc162
-rw-r--r--gnuradio-runtime/lib/gr_top_block_impl.cc211
-rw-r--r--gnuradio-runtime/lib/gr_top_block_impl.h88
-rw-r--r--gnuradio-runtime/lib/gr_tpb_detail.cc70
-rw-r--r--gnuradio-runtime/lib/gr_tpb_thread_body.cc151
-rw-r--r--gnuradio-runtime/lib/gr_vco.h94
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf.cc295
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf.h122
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.cc204
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.h76
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.cc205
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.h67
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.cc197
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.h67
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.cc194
-rw-r--r--gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.h67
-rw-r--r--gnuradio-runtime/lib/gri_debugger_hook.cc29
-rw-r--r--gnuradio-runtime/lib/hier_block2.cc160
-rw-r--r--gnuradio-runtime/lib/hier_block2_detail.cc657
-rw-r--r--gnuradio-runtime/lib/hier_block2_detail.h77
-rw-r--r--gnuradio-runtime/lib/io_signature.cc117
-rw-r--r--gnuradio-runtime/lib/local_sighandler.cc189
-rw-r--r--gnuradio-runtime/lib/local_sighandler.h (renamed from gnuradio-runtime/lib/gr_local_sighandler.h)67
-rw-r--r--gnuradio-runtime/lib/logger.cc323
-rw-r--r--gnuradio-runtime/lib/malloc16.h2
-rw-r--r--gnuradio-runtime/lib/math/CMakeLists.txt29
-rw-r--r--gnuradio-runtime/lib/math/fast_atan2f.cc202
-rw-r--r--gnuradio-runtime/lib/math/fxpt.cc (renamed from gnuradio-runtime/lib/gr_fxpt.cc)17
-rwxr-xr-xgnuradio-runtime/lib/math/gen_sine_table.py (renamed from gnuradio-runtime/lib/gen_sine_table.py)0
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt.cc102
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt.h (renamed from gnuradio-runtime/lib/qa_gr_fxpt.h)29
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt_nco.cc (renamed from gnuradio-runtime/lib/qa_gr_fxpt_nco.cc)69
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt_nco.h (renamed from gnuradio-runtime/lib/qa_gr_fxpt_nco.h)33
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt_vco.cc (renamed from gnuradio-runtime/lib/qa_gr_fxpt_vco.cc)64
-rw-r--r--gnuradio-runtime/lib/math/qa_fxpt_vco.h (renamed from gnuradio-runtime/lib/qa_gr_fxpt_vco.h)33
-rw-r--r--gnuradio-runtime/lib/math/qa_math.cc (renamed from gnuradio-runtime/lib/qa_gr_math.cc)24
-rw-r--r--gnuradio-runtime/lib/math/qa_math.h (renamed from gnuradio-runtime/lib/qa_gr_math.h)6
-rw-r--r--gnuradio-runtime/lib/math/qa_sincos.cc (renamed from gnuradio-runtime/lib/qa_sincos.cc)7
-rw-r--r--gnuradio-runtime/lib/math/qa_sincos.h (renamed from gnuradio-runtime/lib/qa_sincos.h)0
-rw-r--r--gnuradio-runtime/lib/math/random.cc188
-rw-r--r--gnuradio-runtime/lib/math/sincos.cc (renamed from gnuradio-runtime/lib/gr_sincos.c)66
-rw-r--r--gnuradio-runtime/lib/math/sine_table.h (renamed from gnuradio-runtime/lib/sine_table.h)0
-rw-r--r--gnuradio-runtime/lib/math/vco.h99
-rw-r--r--gnuradio-runtime/lib/message.cc82
-rw-r--r--gnuradio-runtime/lib/messages/msg_accepter.cc2
-rw-r--r--gnuradio-runtime/lib/messages/msg_accepter_msgq.cc6
-rw-r--r--gnuradio-runtime/lib/messages/msg_producer.cc2
-rw-r--r--gnuradio-runtime/lib/messages/msg_queue.cc18
-rw-r--r--gnuradio-runtime/lib/misc.cc (renamed from gnuradio-runtime/lib/gr_reverse.cc)64
-rw-r--r--gnuradio-runtime/lib/misc.h (renamed from gnuradio-runtime/lib/gr_misc.h)23
-rw-r--r--gnuradio-runtime/lib/msg_accepter.cc (renamed from gnuradio-runtime/lib/gr_msg_accepter.cc)63
-rw-r--r--gnuradio-runtime/lib/msg_handler.cc (renamed from gnuradio-runtime/lib/gr_msg_handler.cc)15
-rw-r--r--gnuradio-runtime/lib/msg_queue.cc130
-rw-r--r--gnuradio-runtime/lib/pagesize.cc (renamed from gnuradio-runtime/lib/gr_pagesize.cc)39
-rw-r--r--gnuradio-runtime/lib/pagesize.h (renamed from gnuradio-runtime/lib/gr_pagesize.h)21
-rw-r--r--gnuradio-runtime/lib/pmt/pmt.cc2
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt.h2
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt_prims.cc2
-rw-r--r--gnuradio-runtime/lib/pmt/qa_pmt_prims.h6
-rw-r--r--gnuradio-runtime/lib/pmt/unv_qa_template.cc.t2
-rw-r--r--gnuradio-runtime/lib/posix_memalign.cc4
-rw-r--r--gnuradio-runtime/lib/prefs.cc401
-rw-r--r--gnuradio-runtime/lib/qa_buffer.cc304
-rw-r--r--gnuradio-runtime/lib/qa_buffer.h (renamed from gnuradio-runtime/lib/qa_gr_buffer.h)36
-rw-r--r--gnuradio-runtime/lib/qa_circular_file.cc (renamed from gnuradio-runtime/lib/qa_gr_circular_file.cc)38
-rw-r--r--gnuradio-runtime/lib/qa_circular_file.h (renamed from gnuradio-runtime/lib/qa_gr_vmcircbuf.h)24
-rw-r--r--gnuradio-runtime/lib/qa_gr_buffer.cc307
-rw-r--r--gnuradio-runtime/lib/qa_gr_fxpt.cc103
-rw-r--r--gnuradio-runtime/lib/qa_gr_io_signature.cc64
-rw-r--r--gnuradio-runtime/lib/qa_io_signature.cc65
-rw-r--r--gnuradio-runtime/lib/qa_io_signature.h (renamed from gnuradio-runtime/lib/qa_gr_io_signature.h)26
-rw-r--r--gnuradio-runtime/lib/qa_logger.cc (renamed from gnuradio-runtime/lib/qa_gr_logger.cc)6
-rw-r--r--gnuradio-runtime/lib/qa_logger.h (renamed from gnuradio-runtime/lib/qa_gr_logger.h)8
-rw-r--r--gnuradio-runtime/lib/qa_runtime.cc42
-rw-r--r--gnuradio-runtime/lib/qa_runtime.h2
-rw-r--r--gnuradio-runtime/lib/qa_vmcircbuf.cc (renamed from gnuradio-runtime/lib/qa_gr_vmcircbuf.cc)14
-rw-r--r--gnuradio-runtime/lib/qa_vmcircbuf.h (renamed from gnuradio-runtime/lib/qa_gr_circular_file.h)25
-rw-r--r--gnuradio-runtime/lib/random.h38
-rw-r--r--gnuradio-runtime/lib/realtime.cc151
-rw-r--r--gnuradio-runtime/lib/realtime_impl.cc178
-rw-r--r--gnuradio-runtime/lib/runtime_block_gateway.cc185
-rw-r--r--gnuradio-runtime/lib/scheduler.cc (renamed from gnuradio-runtime/lib/gr_scheduler.cc)22
-rw-r--r--gnuradio-runtime/lib/scheduler.h68
-rw-r--r--gnuradio-runtime/lib/scheduler_sts.cc90
-rw-r--r--gnuradio-runtime/lib/scheduler_sts.h66
-rw-r--r--gnuradio-runtime/lib/scheduler_tpb.cc106
-rw-r--r--gnuradio-runtime/lib/scheduler_tpb.h66
-rw-r--r--gnuradio-runtime/lib/select_handler.cc (renamed from gnuradio-runtime/lib/gr_select_handler.cc)22
-rw-r--r--gnuradio-runtime/lib/single_threaded_scheduler.cc363
-rw-r--r--gnuradio-runtime/lib/sptr_magic.cc (renamed from gnuradio-runtime/lib/gr_sptr_magic.cc)46
-rw-r--r--gnuradio-runtime/lib/sync_block.cc72
-rw-r--r--gnuradio-runtime/lib/sync_decimator.cc72
-rw-r--r--gnuradio-runtime/lib/sync_interpolator.cc73
-rw-r--r--gnuradio-runtime/lib/sys_paths.cc (renamed from gnuradio-runtime/lib/gr_sys_paths.cc)32
-rw-r--r--gnuradio-runtime/lib/tagged_stream_block.cc144
-rw-r--r--gnuradio-runtime/lib/test.cc181
-rw-r--r--gnuradio-runtime/lib/test.h225
-rw-r--r--gnuradio-runtime/lib/test_runtime.cc2
-rw-r--r--gnuradio-runtime/lib/test_types.h (renamed from gnuradio-runtime/lib/gr_test_types.h)45
-rw-r--r--gnuradio-runtime/lib/thread/thread.cc2
-rw-r--r--gnuradio-runtime/lib/thread/thread_body_wrapper.cc2
-rw-r--r--gnuradio-runtime/lib/thread/thread_group.cc2
-rw-r--r--gnuradio-runtime/lib/top_block.cc167
-rw-r--r--gnuradio-runtime/lib/top_block_impl.cc212
-rw-r--r--gnuradio-runtime/lib/top_block_impl.h90
-rw-r--r--gnuradio-runtime/lib/tpb_detail.cc71
-rw-r--r--gnuradio-runtime/lib/tpb_thread_body.cc151
-rw-r--r--gnuradio-runtime/lib/tpb_thread_body.h (renamed from gnuradio-runtime/lib/gr_tpb_thread_body.h)39
-rw-r--r--gnuradio-runtime/lib/vmcircbuf.cc299
-rw-r--r--gnuradio-runtime/lib/vmcircbuf.h125
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_createfilemapping.cc204
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_createfilemapping.h81
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc204
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.h70
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.cc197
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.h70
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_prefs.cc113
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_prefs.h (renamed from gnuradio-runtime/lib/gri_debugger_hook.h)21
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc196
-rw-r--r--gnuradio-runtime/lib/vmcircbuf_sysv_shm.h70
195 files changed, 12548 insertions, 12311 deletions
diff --git a/gnuradio-runtime/lib/CMakeLists.txt b/gnuradio-runtime/lib/CMakeLists.txt
index 98db673f5d..5193b98f57 100644
--- a/gnuradio-runtime/lib/CMakeLists.txt
+++ b/gnuradio-runtime/lib/CMakeLists.txt
@@ -27,8 +27,8 @@ execute_process(COMMAND ${PYTHON_EXECUTABLE} -c
"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 gr_constants...")
-message(STATUS "Loading version ${VERSION} into gr_constants...")
+message(STATUS "Loading build date ${BUILD_DATE} into constants...")
+message(STATUS "Loading version ${VERSION} into constants...")
#double escape for windows backslash path separators
string(REPLACE "\\" "\\\\" prefix ${prefix})
@@ -36,11 +36,11 @@ string(REPLACE "\\" "\\\\" SYSCONFDIR ${SYSCONFDIR})
string(REPLACE "\\" "\\\\" GR_PREFSDIR ${GR_PREFSDIR})
configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/gr_constants.cc.in
- ${CMAKE_CURRENT_BINARY_DIR}/gr_constants.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/constants.cc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/constants.cc
@ONLY)
-list(APPEND gnuradio_runtime_sources ${CMAKE_CURRENT_BINARY_DIR}/gr_constants.cc)
+list(APPEND gnuradio_runtime_sources ${CMAKE_CURRENT_BINARY_DIR}/constants.cc)
########################################################################
# Include subdirs rather to populate to the sources lists.
@@ -63,67 +63,62 @@ include_directories(${GNURADIO_RUNTIME_INCLUDE_DIRS}
GR_INCLUDE_SUBDIRECTORY(pmt)
GR_INCLUDE_SUBDIRECTORY(messages)
GR_INCLUDE_SUBDIRECTORY(thread)
+GR_INCLUDE_SUBDIRECTORY(math)
########################################################################
# Setup library
########################################################################
list(APPEND gnuradio_runtime_sources
complex_vec_test.cc
- gr_basic_block.cc
- gr_block.cc
- gr_block_detail.cc
- gr_block_executor.cc
- gr_block_registry.cc
- gr_buffer.cc
- gr_circular_file.cc
- gr_dispatcher.cc
- gr_error_handler.cc
- gr_fast_atan2f.cc
- gr_feval.cc
- gr_flat_flowgraph.cc
- gr_flowgraph.cc
- gr_fxpt.cc
- gr_hier_block2.cc
- gr_hier_block2_detail.cc
- gri_debugger_hook.cc
- gr_io_signature.cc
- gr_local_sighandler.cc
- gr_logger.cc
- gr_message.cc
- gr_misc.cc
- gr_msg_accepter.cc
- gr_msg_handler.cc
- gr_msg_queue.cc
- gr_pagesize.cc
- gr_preferences.cc
- gr_prefs.cc
- gr_random.cc
- gr_realtime.cc
- gr_reverse.cc
- gr_scheduler.cc
- gr_scheduler_sts.cc
- gr_scheduler_tpb.cc
- gr_select_handler.cc
- gr_sincos.c
- gr_single_threaded_scheduler.cc
- gr_sptr_magic.cc
- gr_sync_block.cc
- gr_sync_decimator.cc
- gr_sync_interpolator.cc
- gr_sys_paths.cc
- gr_tagged_stream_block.cc
- gr_test.cc
- gr_top_block.cc
- gr_top_block_impl.cc
- gr_tpb_detail.cc
- gr_tpb_thread_body.cc
- gr_vmcircbuf.cc
- gr_vmcircbuf_createfilemapping.cc
- gr_vmcircbuf_mmap_shm_open.cc
- gr_vmcircbuf_mmap_tmpfile.cc
- gr_vmcircbuf_sysv_shm.cc
malloc16.c
- runtime_block_gateway.cc
+ basic_block.cc
+ block.cc
+ block_detail.cc
+ block_executor.cc
+ block_gateway_impl.cc
+ block_registry.cc
+ buffer.cc
+ circular_file.cc
+ dispatcher.cc
+ error_handler.cc
+ feval.cc
+ flat_flowgraph.cc
+ flowgraph.cc
+ hier_block2.cc
+ hier_block2_detail.cc
+ io_signature.cc
+ local_sighandler.cc
+ logger.cc
+ message.cc
+ misc.cc
+ msg_accepter.cc
+ msg_handler.cc
+ msg_queue.cc
+ pagesize.cc
+ prefs.cc
+ tagged_stream_block.cc
+ test.cc
+ top_block.cc
+ top_block_impl.cc
+ realtime.cc
+ scheduler.cc
+ scheduler_sts.cc
+ scheduler_tpb.cc
+ select_handler.cc
+ single_threaded_scheduler.cc
+ sptr_magic.cc
+ sync_block.cc
+ sync_decimator.cc
+ sync_interpolator.cc
+ sys_paths.cc
+ tpb_detail.cc
+ tpb_thread_body.cc
+ vmcircbuf.cc
+ vmcircbuf_createfilemapping.cc
+ vmcircbuf_mmap_shm_open.cc
+ vmcircbuf_mmap_tmpfile.cc
+ vmcircbuf_prefs.cc
+ vmcircbuf_sysv_shm.cc
)
# PowerPC workaround for posix_memalign
@@ -154,50 +149,7 @@ if(LINUX)
list(APPEND gnuradio_runtime_libs rt)
endif()
-if(ENABLE_GR_CTRLPORT)
-
-include_directories(${ICE_INCLUDE_DIR})
-
-# Add definition so we can compile in ControlPort to the blocks.
-ADD_DEFINITIONS(-DGR_CTRLPORT)
-
-########################################################################
-# Run ICE To compile Slice files
-########################################################################
-EXECUTE_PROCESS(
- COMMAND "${ICE_SLICE2CPP}" "-I${CMAKE_CURRENT_SOURCE_DIR}"
- "--output-dir=${CMAKE_CURRENT_BINARY_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}/gnuradio.ice"
- )
-
-list(APPEND gnuradio_runtime_sources
- ice_application_base.cc
- rpcmanager.cc
- rpcpmtconverters_ice.cc
- rpcserver_aggregator.cc
- rpcserver_booter_aggregator.cc
- rpcserver_booter_ice.cc
- rpcserver_ice.cc
- rpcserver_selector.cc
- rpcpmtconverters_ice.cc
-)
-
-# Append generated file in build directory
-list(APPEND gnuradio_runtime_sources
- ${CMAKE_CURRENT_BINARY_DIR}/gnuradio.cpp
-)
-
-########################################################################
-# Add controlport stuff to gnuradio-runtime
-########################################################################
-
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-list(APPEND gnuradio_runtime_libs
- ${ICE_LIBRARIES}
-)
-
-endif(ENABLE_GR_CTRLPORT)
+GR_INCLUDE_SUBDIRECTORY(controlport)
########################################################################
# Add DLL resource file when using MSVC
@@ -257,23 +209,23 @@ include(GrTest)
# Append gnuradio-runtime test sources
########################################################################
list(APPEND test_gnuradio_runtime_sources
- qa_gr_buffer.cc
- qa_gr_circular_file.cc
- qa_gr_fxpt.cc
- qa_gr_fxpt_nco.cc
- qa_gr_fxpt_vco.cc
- qa_gr_io_signature.cc
- qa_gr_logger.cc
- qa_gr_math.cc
- qa_gr_vmcircbuf.cc
- qa_runtime.cc
- qa_sincos.cc
+ math/qa_fxpt.cc
+ math/qa_fxpt_nco.cc
+ math/qa_fxpt_vco.cc
+ math/qa_math.cc
+ math/qa_sincos.cc
pmt/qa_pmt.cc
pmt/qa_pmt_prims.cc
+ qa_buffer.cc
+ qa_io_signature.cc
+ qa_circular_file.cc
+ qa_logger.cc
+ qa_vmcircbuf.cc
+ qa_runtime.cc
${CMAKE_CURRENT_BINARY_DIR}/pmt/qa_pmt_unv.cc
)
-include_directories(${CPPUNIT_INCLUDE_DIRS})
+include_directories(${CPPUNIT_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/math)
link_directories(${CPPUNIT_LIBRARY_DIRS})
add_library(test-gnuradio-runtime SHARED ${test_gnuradio_runtime_sources})
diff --git a/gnuradio-runtime/lib/basic_block.cc b/gnuradio-runtime/lib/basic_block.cc
new file mode 100644
index 0000000000..8060c5355c
--- /dev/null
+++ b/gnuradio-runtime/lib/basic_block.cc
@@ -0,0 +1,233 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2012-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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/basic_block.h>
+#include <gnuradio/block_registry.h>
+#include <stdexcept>
+#include <sstream>
+#include <iostream>
+
+namespace gr {
+
+ static long s_next_id = 0;
+ static long s_ncurrently_allocated = 0;
+
+ long
+ basic_block_ncurrently_allocated()
+ {
+ return s_ncurrently_allocated;
+ }
+
+ basic_block::basic_block(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature)
+ : d_name(name),
+ d_input_signature(input_signature),
+ d_output_signature(output_signature),
+ d_unique_id(s_next_id++),
+ d_symbolic_id(global_block_registry.block_register(this)),
+ d_symbol_name(global_block_registry.register_symbolic_name(this)),
+ d_color(WHITE),
+ d_rpc_set(false),
+ message_subscribers(pmt::make_dict())
+ {
+ s_ncurrently_allocated++;
+ }
+
+ basic_block::~basic_block()
+ {
+ s_ncurrently_allocated--;
+ global_block_registry.block_unregister(this);
+ }
+
+ basic_block_sptr
+ basic_block::to_basic_block()
+ {
+ return shared_from_this();
+ }
+
+ void
+ basic_block::set_block_alias(std::string name)
+ {
+ global_block_registry.register_symbolic_name(this, name);
+ }
+
+ // ** Message passing interface **
+
+ // - register a new input message port
+ void
+ basic_block::message_port_register_in(pmt::pmt_t port_id)
+ {
+ if(!pmt::is_symbol(port_id)) {
+ throw std::runtime_error("message_port_register_in: bad port id");
+ }
+ msg_queue[port_id] = msg_queue_t();
+ msg_queue_ready[port_id] = boost::shared_ptr<boost::condition_variable>(new boost::condition_variable());
+ }
+
+ pmt::pmt_t
+ basic_block::message_ports_in()
+ {
+ pmt::pmt_t port_names = pmt::make_vector(msg_queue.size(), pmt::PMT_NIL);
+ msg_queue_map_itr itr = msg_queue.begin();
+ for(size_t i = 0; i < msg_queue.size(); i++) {
+ pmt::vector_set(port_names, i, (*itr).first);
+ itr++;
+ }
+ return port_names;
+ }
+
+ // - register a new output message port
+ void
+ basic_block::message_port_register_out(pmt::pmt_t port_id)
+ {
+ if(!pmt::is_symbol(port_id)) {
+ throw std::runtime_error("message_port_register_out: bad port id");
+ }
+ if(pmt::dict_has_key(message_subscribers, port_id)) {
+ throw std::runtime_error("message_port_register_out: port already in use");
+ }
+ message_subscribers = pmt::dict_add(message_subscribers, port_id, pmt::PMT_NIL);
+ }
+
+ pmt::pmt_t
+ basic_block::message_ports_out()
+ {
+ size_t len = pmt::length(message_subscribers);
+ pmt::pmt_t port_names = pmt::make_vector(len, pmt::PMT_NIL);
+ pmt::pmt_t keys = pmt::dict_keys(message_subscribers);
+ for(size_t i = 0; i < len; i++) {
+ pmt::vector_set(port_names, i, pmt::nth(i, keys));
+ }
+ return port_names;
+ }
+
+ // - publish a message on a message port
+ void basic_block::message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg)
+ {
+ if(!pmt::dict_has_key(message_subscribers, port_id)) {
+ throw std::runtime_error("port does not exist");
+ }
+
+ pmt::pmt_t currlist = pmt::dict_ref(message_subscribers, port_id, pmt::PMT_NIL);
+ // iterate through subscribers on port
+ while(pmt::is_pair(currlist)) {
+ pmt::pmt_t target = pmt::car(currlist);
+
+ pmt::pmt_t block = pmt::car(target);
+ pmt::pmt_t port = pmt::cdr(target);
+
+ currlist = pmt::cdr(currlist);
+ basic_block_sptr blk = global_block_registry.block_lookup(block);
+ //blk->post(msg);
+ blk->post(port, msg);
+ }
+ }
+
+ // - subscribe to a message port
+ void
+ basic_block::message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){
+ if(!pmt::dict_has_key(message_subscribers, port_id)){
+ std::stringstream ss;
+ ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: "
+ << pmt::write_string(target) << std::endl;
+ throw std::runtime_error(ss.str());
+ }
+ pmt::pmt_t currlist = pmt::dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
+
+ // ignore re-adds of the same target
+ if(!pmt::list_has(currlist, target))
+ message_subscribers = pmt::dict_add(message_subscribers,port_id,pmt::list_add(currlist,target));
+ }
+
+ void
+ basic_block::message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target)
+ {
+ if(!pmt::dict_has_key(message_subscribers, port_id)) {
+ std::stringstream ss;
+ ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: "
+ << pmt::write_string(target) << std::endl;
+ throw std::runtime_error(ss.str());
+ }
+
+ // ignore unsubs of unknown targets
+ pmt::pmt_t currlist = pmt::dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
+ message_subscribers = pmt::dict_add(message_subscribers,port_id,pmt::list_rm(currlist,target));
+ }
+
+ void
+ basic_block::_post(pmt::pmt_t which_port, pmt::pmt_t msg)
+ {
+ insert_tail(which_port, msg);
+ }
+
+ void
+ basic_block::insert_tail(pmt::pmt_t which_port, pmt::pmt_t msg)
+ {
+ gr::thread::scoped_lock guard(mutex);
+
+ if((msg_queue.find(which_port) == msg_queue.end()) || (msg_queue_ready.find(which_port) == msg_queue_ready.end())) {
+ std::cout << "target port = " << pmt::symbol_to_string(which_port) << std::endl;
+ throw std::runtime_error("attempted to insert_tail on invalid queue!");
+ }
+
+ msg_queue[which_port].push_back(msg);
+ msg_queue_ready[which_port]->notify_one();
+
+ // wake up thread if BLKD_IN or BLKD_OUT
+ global_block_registry.notify_blk(alias());
+ }
+
+ pmt::pmt_t
+ basic_block::delete_head_nowait(pmt::pmt_t which_port)
+ {
+ gr::thread::scoped_lock guard(mutex);
+
+ if(empty_p(which_port)) {
+ return pmt::pmt_t();
+ }
+
+ pmt::pmt_t m(msg_queue[which_port].front());
+ msg_queue[which_port].pop_front();
+
+ return m;
+ }
+
+ pmt::pmt_t
+ basic_block::delete_head_blocking(pmt::pmt_t which_port)
+ {
+ gr::thread::scoped_lock guard(mutex);
+
+ 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;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/block.cc b/gnuradio-runtime/lib/block.cc
new file mode 100644
index 0000000000..b38377e856
--- /dev/null
+++ b/gnuradio-runtime/lib/block.cc
@@ -0,0 +1,689 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/block.h>
+#include <gnuradio/block_registry.h>
+#include <gnuradio/block_detail.h>
+#include <gnuradio/prefs.h>
+#include <stdexcept>
+#include <iostream>
+
+namespace gr {
+
+ block::block(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature)
+ : basic_block(name, input_signature, output_signature),
+ d_output_multiple (1),
+ d_output_multiple_set(false),
+ d_unaligned(0),
+ d_is_unaligned(false),
+ d_relative_rate (1.0),
+ d_history(1),
+ d_fixed_rate(false),
+ d_max_noutput_items_set(false),
+ d_max_noutput_items(0),
+ d_min_noutput_items(0),
+ d_tag_propagation_policy(TPP_ALL_TO_ALL),
+ d_pc_rpc_set(false),
+ d_max_output_buffer(std::max(output_signature->max_streams(),1), -1),
+ d_min_output_buffer(std::max(output_signature->max_streams(),1), -1)
+ {
+ global_block_registry.register_primitive(alias(), this);
+
+#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");
+ std::string log_file = p->get_string("LOG", "log_file", "");
+ std::string debug_level = p->get_string("LOG", "debug_level", "off");
+ std::string debug_file = p->get_string("LOG", "debug_file", "");
+
+ GR_CONFIG_LOGGER(config_file);
+
+ GR_LOG_GETLOGGER(LOG, "gr_log." + alias());
+ GR_LOG_SET_LEVEL(LOG, log_level);
+ if(log_file.size() > 0) {
+ if(log_file == "stdout") {
+ GR_LOG_ADD_CONSOLE_APPENDER(LOG, "cout","gr::log :%p: %c{1} - %m%n");
+ }
+ else if(log_file == "stderr") {
+ GR_LOG_ADD_CONSOLE_APPENDER(LOG, "cerr","gr::log :%p: %c{1} - %m%n");
+ }
+ else {
+ GR_LOG_ADD_FILE_APPENDER(LOG, log_file , true,"%r :%p: %c{1} - %m%n");
+ }
+ }
+ d_logger = LOG;
+
+ GR_LOG_GETLOGGER(DLOG, "gr_log_debug." + alias());
+ GR_LOG_SET_LEVEL(DLOG, debug_level);
+ if(debug_file.size() > 0) {
+ if(debug_file == "stdout") {
+ GR_LOG_ADD_CONSOLE_APPENDER(DLOG, "cout","gr::debug :%p: %c{1} - %m%n");
+ }
+ else if(debug_file == "stderr") {
+ GR_LOG_ADD_CONSOLE_APPENDER(DLOG, "cerr", "gr::debug :%p: %c{1} - %m%n");
+ }
+ else {
+ GR_LOG_ADD_FILE_APPENDER(DLOG, debug_file, true, "%r :%p: %c{1} - %m%n");
+ }
+ }
+ d_debug_logger = DLOG;
+#endif /* HAVE_LOG4CPP */
+#else /* ENABLE_GR_LOG */
+ d_logger = NULL;
+ d_debug_logger = NULL;
+#endif /* ENABLE_GR_LOG */
+ }
+
+ block::~block()
+ {
+ global_block_registry.unregister_primitive(alias());
+ }
+
+ // stub implementation: 1:1
+
+ void
+ block::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size ();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = noutput_items + history() - 1;
+ }
+
+ // default implementation
+
+ bool
+ block::start()
+ {
+ return true;
+ }
+
+ bool
+ block::stop()
+ {
+ return true;
+ }
+
+ void
+ block::set_output_multiple(int multiple)
+ {
+ if(multiple < 1)
+ throw std::invalid_argument("block::set_output_multiple");
+
+ d_output_multiple_set = true;
+ d_output_multiple = multiple;
+ }
+
+ void
+ block::set_alignment(int multiple)
+ {
+ if(multiple < 1)
+ throw std::invalid_argument("block::set_alignment_multiple");
+
+ d_output_multiple = multiple;
+ }
+
+ void
+ block::set_unaligned(int na)
+ {
+ // unaligned value must be less than 0 and it doesn't make sense
+ // that it's larger than the alignment value.
+ if((na < 0) || (na > d_output_multiple))
+ throw std::invalid_argument("block::set_unaligned");
+
+ d_unaligned = na;
+ }
+
+ void
+ block::set_is_unaligned(bool u)
+ {
+ d_is_unaligned = u;
+ }
+
+ void
+ block::set_relative_rate(double relative_rate)
+ {
+ if(relative_rate < 0.0)
+ throw std::invalid_argument("block::set_relative_rate");
+
+ d_relative_rate = relative_rate;
+ }
+
+ void
+ block::consume(int which_input, int how_many_items)
+ {
+ d_detail->consume(which_input, how_many_items);
+ }
+
+ void
+ block::consume_each(int how_many_items)
+ {
+ d_detail->consume_each(how_many_items);
+ }
+
+ void
+ block::produce(int which_output, int how_many_items)
+ {
+ d_detail->produce(which_output, how_many_items);
+ }
+
+ int
+ block::fixed_rate_ninput_to_noutput(int ninput)
+ {
+ throw std::runtime_error("Unimplemented");
+ }
+
+ int
+ block::fixed_rate_noutput_to_ninput(int noutput)
+ {
+ throw std::runtime_error("Unimplemented");
+ }
+
+ uint64_t
+ block::nitems_read(unsigned int which_input)
+ {
+ if(d_detail) {
+ return d_detail->nitems_read(which_input);
+ }
+ else {
+ //throw std::runtime_error("No block_detail associated with block yet");
+ return 0;
+ }
+ }
+
+ uint64_t
+ block::nitems_written(unsigned int which_output)
+ {
+ if(d_detail) {
+ return d_detail->nitems_written(which_output);
+ }
+ else {
+ //throw std::runtime_error("No block_detail associated with block yet");
+ return 0;
+ }
+ }
+
+ void
+ block::add_item_tag(unsigned int which_output,
+ const tag_t &tag)
+ {
+ d_detail->add_item_tag(which_output, tag);
+ }
+
+ void
+ block::remove_item_tag(unsigned int which_input,
+ const tag_t &tag)
+ {
+ d_detail->remove_item_tag(which_input, tag);
+ }
+
+ void
+ block::get_tags_in_range(std::vector<tag_t> &v,
+ unsigned int which_output,
+ uint64_t start, uint64_t end)
+ {
+ d_detail->get_tags_in_range(v, which_output, start, end);
+ }
+
+ void
+ block::get_tags_in_range(std::vector<tag_t> &v,
+ unsigned int which_output,
+ uint64_t start, uint64_t end,
+ const pmt::pmt_t &key)
+ {
+ d_detail->get_tags_in_range(v, which_output, start, end, key);
+ }
+
+ block::tag_propagation_policy_t
+ block::tag_propagation_policy()
+ {
+ return d_tag_propagation_policy;
+ }
+
+ void
+ block::set_tag_propagation_policy(tag_propagation_policy_t p)
+ {
+ d_tag_propagation_policy = p;
+ }
+
+ int
+ block::max_noutput_items()
+ {
+ return d_max_noutput_items;
+ }
+
+ void
+ block::set_max_noutput_items(int m)
+ {
+ if(m <= 0)
+ throw std::runtime_error("block::set_max_noutput_items: value for max_noutput_items must be greater than 0.\n");
+
+ d_max_noutput_items = m;
+ d_max_noutput_items_set = true;
+ }
+
+ void
+ block::unset_max_noutput_items()
+ {
+ d_max_noutput_items_set = false;
+ }
+
+ bool
+ block::is_set_max_noutput_items()
+ {
+ return d_max_noutput_items_set;
+ }
+
+ void
+ block::set_processor_affinity(const std::vector<int> &mask)
+ {
+ d_affinity = mask;
+ if(d_detail) {
+ d_detail->set_processor_affinity(d_affinity);
+ }
+ }
+
+ void
+ block::unset_processor_affinity()
+ {
+ d_affinity.clear();
+ if(d_detail) {
+ d_detail->unset_processor_affinity();
+ }
+ }
+
+ float
+ block::pc_noutput_items()
+ {
+ if(d_detail) {
+ return d_detail->pc_noutput_items();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_noutput_items_avg()
+ {
+ if(d_detail) {
+ return d_detail->pc_noutput_items_avg();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_noutput_items_var()
+ {
+ if(d_detail) {
+ return d_detail->pc_noutput_items_var();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_nproduced()
+ {
+ if(d_detail) {
+ return d_detail->pc_nproduced();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_nproduced_avg()
+ {
+ if(d_detail) {
+ return d_detail->pc_nproduced_avg();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_nproduced_var()
+ {
+ if(d_detail) {
+ return d_detail->pc_nproduced_var();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_input_buffers_full(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_input_buffers_full_avg(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_avg(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_input_buffers_full_var(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_var(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ std::vector<float>
+ block::pc_input_buffers_full()
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ std::vector<float>
+ block::pc_input_buffers_full_avg()
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_avg();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ std::vector<float>
+ block::pc_input_buffers_full_var()
+ {
+ if(d_detail) {
+ return d_detail->pc_input_buffers_full_var();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ float
+ block::pc_output_buffers_full(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_output_buffers_full_avg(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_avg(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_output_buffers_full_var(int which)
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_var(static_cast<size_t>(which));
+ }
+ else {
+ return 0;
+ }
+ }
+
+ std::vector<float>
+ block::pc_output_buffers_full()
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ std::vector<float>
+ block::pc_output_buffers_full_avg()
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_avg();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ std::vector<float>
+ block::pc_output_buffers_full_var()
+ {
+ if(d_detail) {
+ return d_detail->pc_output_buffers_full_var();
+ }
+ else {
+ return std::vector<float>(1,0);
+ }
+ }
+
+ float
+ block::pc_work_time()
+ {
+ if(d_detail) {
+ return d_detail->pc_work_time();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_work_time_avg()
+ {
+ if(d_detail) {
+ return d_detail->pc_work_time_avg();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ float
+ block::pc_work_time_var()
+ {
+ if(d_detail) {
+ return d_detail->pc_work_time_var();
+ }
+ else {
+ return 0;
+ }
+ }
+
+ void
+ block::reset_perf_counters()
+ {
+ if(d_detail) {
+ d_detail->reset_perf_counters();
+ }
+ }
+
+ void
+ block::setup_pc_rpc()
+ {
+ d_pc_rpc_set = true;
+#ifdef GR_CTRLPORT
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "noutput_items", &block::pc_noutput_items,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "noutput items", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "avg noutput_items", &block::pc_noutput_items_avg,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Average noutput items", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "var noutput_items", &block::pc_noutput_items_var,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Var. noutput items", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "nproduced", &block::pc_nproduced,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "items produced", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "avg nproduced", &block::pc_nproduced_avg,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Average items produced", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "var nproduced", &block::pc_nproduced_var,
+ pmt::mp(0), pmt::mp(32768), pmt::mp(0),
+ "", "Var. items produced", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "work time", &block::pc_work_time,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "clock cycles in call to work", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "avg work time", &block::pc_work_time_avg,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "Average clock cycles in call to work", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, float>(
+ alias(), "var work time", &block::pc_work_time_var,
+ pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
+ "", "Var. clock cycles in call to work", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "input \% full", &block::pc_input_buffers_full,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "how full input buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "avg input \% full", &block::pc_input_buffers_full_avg,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Average of how full input buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "var input \% full", &block::pc_input_buffers_full_var,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Var. of how full input buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "output \% full", &block::pc_output_buffers_full,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "how full output buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "avg output \% full", &block::pc_output_buffers_full_avg,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Average of how full output buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+
+ d_rpc_vars.push_back(
+ rpcbasic_sptr(new rpcbasic_register_get<block, std::vector<float> >(
+ alias(), "var output \% full", &block::pc_output_buffers_full_var,
+ pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
+ "", "Var. of how full output buffers are", RPC_PRIVLVL_MIN,
+ DISPTIME | DISPOPTSTRIP)));
+#endif /* GR_CTRLPORT */
+ }
+
+ std::ostream&
+ operator << (std::ostream& os, const block *m)
+ {
+ os << "<block " << m->name() << " (" << m->unique_id() << ")>";
+ return os;
+ }
+
+ int
+ block::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ throw std::runtime_error("block::general_work() not implemented");
+ return 0;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/block_detail.cc b/gnuradio-runtime/lib/block_detail.cc
new file mode 100644
index 0000000000..a3ab4b3f7b
--- /dev/null
+++ b/gnuradio-runtime/lib/block_detail.cc
@@ -0,0 +1,474 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/block_detail.h>
+#include <gnuradio/buffer.h>
+#include <iostream>
+
+namespace gr {
+
+ static long s_ncurrently_allocated = 0;
+
+ long
+ block_detail_ncurrently_allocated()
+ {
+ return s_ncurrently_allocated;
+ }
+
+ block_detail::block_detail(unsigned int ninputs, unsigned int noutputs)
+ : d_produce_or(0),
+ d_ninputs(ninputs), d_noutputs(noutputs),
+ d_input(ninputs), d_output(noutputs),
+ d_done(false),
+ d_ins_noutput_items(0),
+ d_avg_noutput_items(0),
+ d_var_noutput_items(0),
+ d_ins_nproduced(0),
+ d_avg_nproduced(0),
+ d_var_nproduced(0),
+ d_ins_input_buffers_full(ninputs, 0),
+ d_avg_input_buffers_full(ninputs, 0),
+ d_var_input_buffers_full(ninputs, 0),
+ d_ins_output_buffers_full(noutputs, 0),
+ d_avg_output_buffers_full(noutputs, 0),
+ d_var_output_buffers_full(noutputs, 0),
+ d_ins_work_time(0),
+ d_avg_work_time(0),
+ d_var_work_time(0),
+ d_pc_counter(0)
+ {
+ s_ncurrently_allocated++;
+ }
+
+ block_detail::~block_detail()
+ {
+ // should take care of itself
+ s_ncurrently_allocated--;
+ }
+
+ void
+ block_detail::set_input(unsigned int which, buffer_reader_sptr reader)
+ {
+ if(which >= d_ninputs)
+ throw std::invalid_argument("block_detail::set_input");
+
+ d_input[which] = reader;
+ }
+
+ void
+ block_detail::set_output(unsigned int which, buffer_sptr buffer)
+ {
+ if(which >= d_noutputs)
+ throw std::invalid_argument("block_detail::set_output");
+
+ d_output[which] = buffer;
+ }
+
+ block_detail_sptr
+ make_block_detail(unsigned int ninputs, unsigned int noutputs)
+ {
+ return block_detail_sptr (new block_detail(ninputs, noutputs));
+ }
+
+ void
+ block_detail::set_done(bool done)
+ {
+ d_done = done;
+ for(unsigned int i = 0; i < d_noutputs; i++)
+ d_output[i]->set_done(done);
+
+ for(unsigned int i = 0; i < d_ninputs; i++)
+ d_input[i]->set_done(done);
+ }
+
+ void
+ block_detail::consume(int which_input, int how_many_items)
+ {
+ if(how_many_items > 0) {
+ input(which_input)->update_read_pointer(how_many_items);
+ }
+ }
+
+ void
+ block_detail::consume_each(int how_many_items)
+ {
+ if(how_many_items > 0) {
+ for(int i = 0; i < ninputs (); i++) {
+ d_input[i]->update_read_pointer(how_many_items);
+ }
+ }
+ }
+
+ void
+ block_detail::produce(int which_output, int how_many_items)
+ {
+ if(how_many_items > 0) {
+ d_output[which_output]->update_write_pointer(how_many_items);
+ d_produce_or |= how_many_items;
+ }
+ }
+
+ void
+ block_detail::produce_each(int how_many_items)
+ {
+ if(how_many_items > 0) {
+ for(int i = 0; i < noutputs (); i++) {
+ d_output[i]->update_write_pointer (how_many_items);
+ }
+ d_produce_or |= how_many_items;
+ }
+ }
+
+ uint64_t
+ block_detail::nitems_read(unsigned int which_input)
+ {
+ if(which_input >= d_ninputs)
+ throw std::invalid_argument ("block_detail::n_input_items");
+ return d_input[which_input]->nitems_read();
+ }
+
+ uint64_t
+ block_detail::nitems_written(unsigned int which_output)
+ {
+ if(which_output >= d_noutputs)
+ throw std::invalid_argument ("block_detail::n_output_items");
+ return d_output[which_output]->nitems_written();
+ }
+
+ void
+ block_detail::add_item_tag(unsigned int which_output, const tag_t &tag)
+ {
+ if(!pmt::is_symbol(tag.key)) {
+ throw pmt::wrong_type("block_detail::add_item_tag key", tag.key);
+ }
+ else {
+ // Add tag to gr_buffer's deque tags
+ d_output[which_output]->add_item_tag(tag);
+ }
+ }
+
+ void
+ block_detail::remove_item_tag(unsigned int which_input, const tag_t &tag)
+ {
+ if(!pmt::is_symbol(tag.key)) {
+ throw pmt::wrong_type("block_detail::add_item_tag key", tag.key);
+ }
+ else {
+ // Add tag to gr_buffer's deque tags
+ d_input[which_input]->buffer()->remove_item_tag(tag);
+ }
+ }
+
+ void
+ block_detail::get_tags_in_range(std::vector<tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end)
+ {
+ // get from gr_buffer_reader's deque of tags
+ d_input[which_input]->get_tags_in_range(v, abs_start, abs_end);
+ }
+
+ void
+ block_detail::get_tags_in_range(std::vector<tag_t> &v,
+ unsigned int which_input,
+ uint64_t abs_start,
+ uint64_t abs_end,
+ const pmt::pmt_t &key)
+ {
+ std::vector<tag_t> found_items;
+
+ v.resize(0);
+
+ // get from gr_buffer_reader's deque of tags
+ d_input[which_input]->get_tags_in_range(found_items, abs_start, abs_end);
+
+ // Filter further by key name
+ pmt::pmt_t itemkey;
+ std::vector<tag_t>::iterator itr;
+ for(itr = found_items.begin(); itr != found_items.end(); itr++) {
+ itemkey = (*itr).key;
+ if(pmt::eqv(key, itemkey)) {
+ v.push_back(*itr);
+ }
+ }
+ }
+
+ void
+ block_detail::set_processor_affinity(const std::vector<int> &mask)
+ {
+ if(threaded) {
+ try {
+ gr::thread::thread_bind_to_processor(thread, mask);
+ }
+ catch (std::runtime_error e) {
+ std::cerr << "set_processor_affinity: invalid mask." << std::endl;;
+ }
+ }
+ }
+
+ void
+ block_detail::unset_processor_affinity()
+ {
+ if(threaded) {
+ gr::thread::thread_unbind(thread);
+ }
+ }
+
+ void
+ block_detail::start_perf_counters()
+ {
+ d_start_of_work = gr::high_res_timer_now();
+ }
+
+ void
+ block_detail::stop_perf_counters(int noutput_items, int nproduced)
+ {
+ d_end_of_work = gr::high_res_timer_now();
+ gr::high_res_timer_type diff = d_end_of_work - d_start_of_work;
+
+ if(d_pc_counter == 0) {
+ d_ins_work_time = diff;
+ d_avg_work_time = diff;
+ d_var_work_time = 0;
+ d_ins_nproduced = nproduced;
+ d_avg_nproduced = nproduced;
+ d_var_nproduced = 0;
+ d_ins_noutput_items = noutput_items;
+ d_avg_noutput_items = noutput_items;
+ d_var_noutput_items = 0;
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+ d_ins_input_buffers_full[i] = pfull;
+ d_avg_input_buffers_full[i] = pfull;
+ d_var_input_buffers_full[i] = 0;
+ }
+ for(size_t i=0; i < d_output.size(); i++) {
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+ d_ins_output_buffers_full[i] = pfull;
+ d_avg_output_buffers_full[i] = pfull;
+ d_var_output_buffers_full[i] = 0;
+ }
+ }
+ else {
+ float d = diff - d_avg_work_time;
+ d_ins_work_time = diff;
+ d_avg_work_time = d_avg_work_time + d/d_pc_counter;
+ d_var_work_time = d_var_work_time + d*d;
+
+ d = nproduced - d_avg_nproduced;
+ d_ins_nproduced = nproduced;
+ d_avg_nproduced = d_avg_nproduced + d/d_pc_counter;
+ d_var_nproduced = d_var_nproduced + d*d;
+
+ d = noutput_items - d_avg_noutput_items;
+ d_ins_noutput_items = noutput_items;
+ d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
+ d_var_noutput_items = d_var_noutput_items + d*d;
+
+ for(size_t i=0; i < d_input.size(); i++) {
+ float pfull = static_cast<float>(d_input[i]->items_available()) /
+ static_cast<float>(d_input[i]->max_possible_items_available());
+
+ d = pfull - d_avg_input_buffers_full[i];
+ d_ins_input_buffers_full[i] = pfull;
+ d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter;
+ d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d;
+ }
+
+ for(size_t i=0; i < d_output.size(); i++) {
+ float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
+ static_cast<float>(d_output[i]->bufsize());
+
+ d = pfull - d_avg_output_buffers_full[i];
+ d_ins_output_buffers_full[i] = pfull;
+ d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter;
+ d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d;
+ }
+ }
+
+ d_pc_counter++;
+ }
+
+ void
+ block_detail::reset_perf_counters()
+ {
+ d_pc_counter = 0;
+ }
+
+ float
+ block_detail::pc_noutput_items()
+ {
+ return d_ins_noutput_items;
+ }
+
+ float
+ block_detail::pc_nproduced()
+ {
+ return d_ins_nproduced;
+ }
+
+ float
+ block_detail::pc_input_buffers_full(size_t which)
+ {
+ if(which < d_ins_input_buffers_full.size())
+ return d_ins_input_buffers_full[which];
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_input_buffers_full()
+ {
+ return d_ins_input_buffers_full;
+ }
+
+ float
+ block_detail::pc_output_buffers_full(size_t which)
+ {
+ if(which < d_ins_output_buffers_full.size())
+ return d_ins_output_buffers_full[which];
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_output_buffers_full()
+ {
+ return d_ins_output_buffers_full;
+ }
+
+ float
+ block_detail::pc_work_time()
+ {
+ return d_ins_work_time;
+ }
+
+ float
+ block_detail::pc_noutput_items_avg()
+ {
+ return d_avg_noutput_items;
+ }
+
+ float
+ block_detail::pc_nproduced_avg()
+ {
+ return d_avg_nproduced;
+ }
+
+ float
+ block_detail::pc_input_buffers_full_avg(size_t which)
+ {
+ if(which < d_avg_input_buffers_full.size())
+ return d_avg_input_buffers_full[which];
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_input_buffers_full_avg()
+ {
+ return d_avg_input_buffers_full;
+ }
+
+ float
+ block_detail::pc_output_buffers_full_avg(size_t which)
+ {
+ if(which < d_avg_output_buffers_full.size())
+ return d_avg_output_buffers_full[which];
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_output_buffers_full_avg()
+ {
+ return d_avg_output_buffers_full;
+ }
+
+ float
+ block_detail::pc_work_time_avg()
+ {
+ return d_avg_work_time;
+ }
+
+ float
+ block_detail::pc_noutput_items_var()
+ {
+ return d_var_noutput_items/(d_pc_counter-1);
+ }
+
+ float
+ block_detail::pc_nproduced_var()
+ {
+ return d_var_nproduced/(d_pc_counter-1);
+ }
+
+ float
+ block_detail::pc_input_buffers_full_var(size_t which)
+ {
+ if(which < d_avg_input_buffers_full.size())
+ return d_var_input_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_input_buffers_full_var()
+ {
+ std::vector<float> var(d_avg_input_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_input_buffers_full.size(); i++)
+ var[i] = d_avg_input_buffers_full[i]/(d_pc_counter-1);
+ return var;
+ }
+
+ float
+ block_detail::pc_output_buffers_full_var(size_t which)
+ {
+ if(which < d_avg_output_buffers_full.size())
+ return d_var_output_buffers_full[which]/(d_pc_counter-1);
+ else
+ return 0;
+ }
+
+ std::vector<float>
+ block_detail::pc_output_buffers_full_var()
+ {
+ std::vector<float> var(d_avg_output_buffers_full.size(), 0);
+ for(size_t i = 0; i < d_avg_output_buffers_full.size(); i++)
+ var[i] = d_avg_output_buffers_full[i]/(d_pc_counter-1);
+ return var;
+ }
+
+ float
+ block_detail::pc_work_time_var()
+ {
+ return d_var_work_time/(d_pc_counter-1);
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/block_executor.cc b/gnuradio-runtime/lib/block_executor.cc
new file mode 100644
index 0000000000..8059ea2d5a
--- /dev/null
+++ b/gnuradio-runtime/lib/block_executor.cc
@@ -0,0 +1,489 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2008-2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <block_executor.h>
+#include <gnuradio/block.h>
+#include <gnuradio/block_detail.h>
+#include <gnuradio/buffer.h>
+#include <gnuradio/prefs.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;
+
+ 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_noutput_items)
+ {
+ int min_space = std::numeric_limits<int>::max();
+ if(min_noutput_items == 0)
+ min_noutput_items = 1;
+ for(int i = 0; i < d->noutputs (); i++) {
+ gr::thread::scoped_lock guard(*d->output(i)->mutex());
+ int avail_n = round_down(d->output(i)->space_available(), output_multiple);
+ int best_n = round_down(d->output(i)->bufsize()/2, output_multiple);
+ if(best_n < min_noutput_items)
+ throw std::runtime_error("Buffer too small for min_noutput_items");
+ int n = std::min(avail_n, best_n);
+ if(n < min_noutput_items){ // We're blocked on output.
+ if(d->output(i)->done()){ // Downstream is done, therefore we're done.
+ return -1;
+ }
+ return 0;
+ }
+ min_space = std::min(min_space, n);
+ }
+ return min_space;
+ }
+
+ static bool
+ propagate_tags(block::tag_propagation_policy_t policy, block_detail *d,
+ const std::vector<uint64_t> &start_nitems_read, double rrate,
+ std::vector<tag_t> &rtags)
+ {
+ // Move tags downstream
+ // if a sink, we don't need to move downstream
+ if(d->sink_p()) {
+ return true;
+ }
+
+ switch(policy) {
+ case block::TPP_DONT:
+ return true;
+ break;
+ case block::TPP_ALL_TO_ALL:
+ // every tag on every input propogates to everyone downstream
+ for(int i = 0; i < d->ninputs(); i++) {
+ d->get_tags_in_range(rtags, i, start_nitems_read[i],
+ d->nitems_read(i));
+
+ std::vector<tag_t>::iterator t;
+ if(rrate == 1.0) {
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ for(int o = 0; o < d->noutputs(); o++)
+ d->output(o)->add_item_tag(*t);
+ }
+ }
+ else {
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ tag_t new_tag = *t;
+ new_tag.offset *= rrate;
+ for(int o = 0; o < d->noutputs(); o++)
+ d->output(o)->add_item_tag(new_tag);
+ }
+ }
+ }
+ break;
+ case block::TPP_ONE_TO_ONE:
+ // tags from input i only go to output i
+ // this requires d->ninputs() == d->noutputs; this is checked when this
+ // type of tag-propagation system is selected in block_detail
+ if(d->ninputs() == d->noutputs()) {
+ for(int i = 0; i < d->ninputs(); i++) {
+ d->get_tags_in_range(rtags, i, start_nitems_read[i],
+ d->nitems_read(i));
+
+ std::vector<tag_t>::iterator t;
+ for(t = rtags.begin(); t != rtags.end(); t++) {
+ tag_t new_tag = *t;
+ new_tag.offset *= rrate;
+ d->output(i)->add_item_tag(new_tag);
+ }
+ }
+ }
+ else {
+ std::cerr << "Error: block_executor: propagation_policy 'ONE-TO-ONE' requires ninputs == noutputs" << std::endl;
+ return false;
+ }
+
+ break;
+ default:
+ return true;
+ }
+ return true;
+ }
+
+ block_executor::block_executor(block_sptr block, int max_noutput_items)
+ : d_block(block), d_log(0), d_max_noutput_items(max_noutput_items)
+ {
+ if(ENABLE_LOGGING) {
+ std::string name = str(boost::format("sst-%03d.log") % which_scheduler++);
+ d_log = new std::ofstream(name.c_str());
+ std::unitbuf(*d_log); // make it unbuffered...
+ *d_log << "block_executor: "
+ << d_block << std::endl;
+ }
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ prefs *prefs = prefs::singleton();
+ d_use_pc = prefs->get_bool("PerfCounters", "on", false);
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ d_block->start(); // enable any drivers, etc.
+ }
+
+ block_executor::~block_executor()
+ {
+ if(ENABLE_LOGGING)
+ delete d_log;
+
+ d_block->stop(); // stop any drivers, etc.
+ }
+
+ block_executor::state
+ block_executor::run_one_iteration()
+ {
+ int noutput_items;
+ int max_items_avail;
+ int max_noutput_items = d_max_noutput_items;
+ int new_alignment = 0;
+ int alignment_state = -1;
+
+ block *m = d_block.get();
+ block_detail *d = m->detail().get();
+
+ LOG(*d_log << std::endl << m);
+
+ if(d->done()){
+ assert(0);
+ return DONE;
+ }
+
+ if(d->source_p ()) {
+ d_ninput_items_required.resize(0);
+ d_ninput_items.resize(0);
+ d_input_items.resize(0);
+ d_input_done.resize(0);
+ d_output_items.resize(d->noutputs());
+ d_start_nitems_read.resize(0);
+
+ // determine the minimum available output space
+ noutput_items = min_available_space(d, m->output_multiple (), m->min_noutput_items ());
+ noutput_items = std::min(noutput_items, max_noutput_items);
+ 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");
+ return BLKD_OUT;
+ }
+
+ goto setup_call_to_work; // jump to common code
+ }
+
+ else if(d->sink_p ()) {
+ d_ninput_items_required.resize(d->ninputs ());
+ d_ninput_items.resize(d->ninputs ());
+ d_input_items.resize(d->ninputs ());
+ d_input_done.resize(d->ninputs());
+ d_output_items.resize (0);
+ d_start_nitems_read.resize(d->ninputs());
+ LOG(*d_log << " sink\n");
+
+ max_items_avail = 0;
+ for(int i = 0; i < d->ninputs (); i++) {
+ {
+ /*
+ * Acquire the mutex and grab local copies of items_available and done.
+ */
+ gr::thread::scoped_lock guard(*d->input(i)->mutex());
+ d_ninput_items[i] = d->input(i)->items_available();
+ d_input_done[i] = d->input(i)->done();
+ }
+
+ LOG(*d_log << " d_ninput_items[" << i << "] = " << d_ninput_items[i] << std::endl);
+ LOG(*d_log << " d_input_done[" << i << "] = " << d_input_done[i] << std::endl);
+
+ if (d_ninput_items[i] < m->output_multiple() && d_input_done[i])
+ goto were_done;
+
+ max_items_avail = std::max (max_items_avail, d_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 ());
+ noutput_items = std::min(noutput_items, max_noutput_items);
+ 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");
+ return BLKD_IN;
+ }
+
+ goto try_again; // Jump to code shared with regular case.
+ }
+
+ else {
+ // do the regular thing
+ d_ninput_items_required.resize (d->ninputs ());
+ d_ninput_items.resize (d->ninputs ());
+ d_input_items.resize (d->ninputs ());
+ d_input_done.resize(d->ninputs());
+ d_output_items.resize (d->noutputs ());
+ d_start_nitems_read.resize(d->ninputs());
+
+ max_items_avail = 0;
+ for(int i = 0; i < d->ninputs (); i++) {
+ {
+ /*
+ * Acquire the mutex and grab local copies of items_available and done.
+ */
+ gr::thread::scoped_lock guard(*d->input(i)->mutex());
+ d_ninput_items[i] = d->input(i)->items_available ();
+ d_input_done[i] = d->input(i)->done();
+ }
+ max_items_avail = std::max(max_items_avail, d_ninput_items[i]);
+ }
+
+ // determine the minimum available output space
+ noutput_items = min_available_space(d, m->output_multiple(), m->min_noutput_items());
+ 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");
+ return BLKD_OUT;
+ }
+
+ 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);
+
+ // only test this if we specifically set the output_multiple
+ if(m->output_multiple_set())
+ reqd_noutput_items = round_down(reqd_noutput_items, m->output_multiple());
+
+ if(reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
+ noutput_items = reqd_noutput_items;
+
+ // if we need this many outputs, overrule the max_noutput_items setting
+ max_noutput_items = std::max(m->output_multiple(), max_noutput_items);
+ }
+ noutput_items = std::min(noutput_items, max_noutput_items);
+
+ // Check if we're still unaligned; use up items until we're
+ // aligned again. Otherwise, make sure we set the alignment
+ // requirement.
+ if(!m->output_multiple_set()) {
+ if(m->is_unaligned()) {
+ // When unaligned, don't just set noutput_items to the remaining
+ // samples to meet alignment; this causes too much overhead in
+ // requiring a premature call back here. Set the maximum amount
+ // of samples to handle unalignment and get us back aligned.
+ if(noutput_items >= m->unaligned()) {
+ noutput_items = round_up(noutput_items, m->alignment()) \
+ - (m->alignment() - m->unaligned());
+ new_alignment = 0;
+ }
+ else {
+ new_alignment = m->unaligned() - noutput_items;
+ }
+ alignment_state = 0;
+ }
+ else if(noutput_items < m->alignment()) {
+ // if we don't have enough for an aligned call, keep track of
+ // misalignment, set unaligned flag, and proceed.
+ new_alignment = m->alignment() - noutput_items;
+ m->set_unaligned(new_alignment);
+ m->set_is_unaligned(true);
+ alignment_state = 1;
+ }
+ else {
+ // enough to round down to the nearest alignment and process.
+ noutput_items = round_down(noutput_items, m->alignment());
+ m->set_is_unaligned(false);
+ alignment_state = 2;
+ }
+ }
+
+ // ask the block how much input they need to produce noutput_items
+ m->forecast (noutput_items, d_ninput_items_required);
+
+ // See if we've got sufficient input available
+ int i;
+ for(i = 0; i < d->ninputs (); i++)
+ if(d_ninput_items_required[i] > d_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
+ LOG(*d_log << " BLKD_IN\n");
+ if(d_input_done[i]) // If the upstream block is done, we're done
+ goto were_done;
+
+ // Is it possible to ever fulfill this request?
+ if(d_ninput_items_required[i] > d->input(i)->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 = "
+ << d_ninput_items_required[i] << "\n"
+ << " max_possible_items_available = "
+ << d->input(i)->max_possible_items_available() << "\n"
+ << " If this is a filter, consider reducing the number of taps.\n";
+ goto were_done;
+ }
+
+ // If we were made unaligned in this round but return here without
+ // processing; reset the unalignment claim before next entry.
+ if(alignment_state == 1) {
+ m->set_unaligned(0);
+ m->set_is_unaligned(false);
+ }
+ return BLKD_IN;
+ }
+
+ // 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++)
+ d_input_items[i] = d->input(i)->read_pointer();
+
+ setup_call_to_work:
+
+ d->d_produce_or = 0;
+ for(int i = 0; i < d->noutputs (); i++)
+ d_output_items[i] = d->output(i)->write_pointer();
+
+ // determine where to start looking for new tags
+ for(int i = 0; i < d->ninputs(); i++)
+ d_start_nitems_read[i] = d->nitems_read(i);
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ if(d_use_pc)
+ d->start_perf_counters();
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ // Do the actual work of the block
+ int n = m->general_work(noutput_items, d_ninput_items,
+ d_input_items, d_output_items);
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ if(d_use_pc)
+ d->stop_perf_counters(noutput_items, n);
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ LOG(*d_log << " general_work: noutput_items = " << noutput_items
+ << " result = " << n << std::endl);
+
+ // Adjust number of unaligned items left to process
+ if(m->is_unaligned()) {
+ m->set_unaligned(new_alignment);
+ m->set_is_unaligned(m->unaligned() != 0);
+ }
+
+ if(!propagate_tags(m->tag_propagation_policy(), d,
+ d_start_nitems_read, m->relative_rate(),
+ d_returned_tags))
+ goto were_done;
+
+ if(n == block::WORK_DONE)
+ goto were_done;
+
+ if(n != block::WORK_CALLED_PRODUCE)
+ d->produce_each (n); // advance write pointers
+
+ if(d->d_produce_or > 0) // block produced something
+ return READY;
+
+ // We didn't produce any output even though we called general_work.
+ // We have (most likely) consumed some input.
+
+ /*
+ // If this is a source, it's broken.
+ if(d->source_p()) {
+ std::cerr << "block_executor: source " << m
+ << " produced no output. We're marking it DONE.\n";
+ // FIXME maybe we ought to raise an exception...
+ goto were_done;
+ }
+ */
+
+ // Have the caller try again...
+ return READY_NO_OUTPUT;
+ }
+ assert(0);
+
+ were_done:
+ LOG(*d_log << " were_done\n");
+ d->set_done (true);
+ return DONE;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/block_executor.h b/gnuradio-runtime/lib/block_executor.h
new file mode 100644
index 0000000000..4e1d2f1602
--- /dev/null
+++ b/gnuradio-runtime/lib/block_executor.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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 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_RUNTIME_BLOCK_EXECUTOR_H
+#define INCLUDED_GR_RUNTIME_BLOCK_EXECUTOR_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/runtime_types.h>
+#include <gnuradio/tags.h>
+#include <fstream>
+
+namespace gr {
+
+ /*!
+ * \brief Manage the execution of a single block.
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API block_executor
+ {
+ protected:
+ block_sptr d_block; // The block we're trying to run
+ std::ofstream *d_log;
+
+ // These are allocated here so we don't have to on each iteration
+
+ gr_vector_int d_ninput_items_required;
+ gr_vector_int d_ninput_items;
+ gr_vector_const_void_star d_input_items;
+ std::vector<bool> d_input_done;
+ gr_vector_void_star d_output_items;
+ std::vector<uint64_t> d_start_nitems_read; //stores where tag counts are before work
+ std::vector<tag_t> d_returned_tags;
+ int d_max_noutput_items;
+
+#ifdef GR_PERFORMANCE_COUNTERS
+ bool d_use_pc;
+#endif /* GR_PERFORMANCE_COUNTERS */
+
+ public:
+ block_executor(block_sptr block, int max_noutput_items=100000);
+ ~block_executor();
+
+ enum state {
+ READY, // We made progress; everything's cool.
+ READY_NO_OUTPUT, // We consumed some input, but produced no output.
+ BLKD_IN, // no progress; we're blocked waiting for input data.
+ BLKD_OUT, // no progress; we're blocked waiting for output buffer space.
+ DONE, // we're done; don't call me again.
+ };
+
+ /*
+ * \brief Run one iteration.
+ */
+ state run_one_iteration();
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_RUNTIME_BLOCK_EXECUTOR_H */
diff --git a/gnuradio-runtime/lib/block_gateway_impl.cc b/gnuradio-runtime/lib/block_gateway_impl.cc
new file mode 100644
index 0000000000..13f4326d7e
--- /dev/null
+++ b/gnuradio-runtime/lib/block_gateway_impl.cc
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2011-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 "block_gateway_impl.h"
+#include <gnuradio/io_signature.h>
+#include <iostream>
+#include <boost/bind.hpp>
+
+namespace gr {
+
+ /***********************************************************************
+ * Helper routines
+ **********************************************************************/
+ template <typename OutType, typename InType>
+ void
+ copy_pointers(OutType &out, const InType &in)
+ {
+ out.resize(in.size());
+ for(size_t i = 0; i < in.size(); i++) {
+ out[i] = (void *)(in[i]);
+ }
+ }
+
+
+ block_gateway::sptr
+ block_gateway::make(feval_ll *handler,
+ const std::string &name,
+ gr::io_signature::sptr in_sig,
+ gr::io_signature::sptr out_sig,
+ const block_gw_work_type work_type,
+ const unsigned factor)
+ {
+ return block_gateway::sptr
+ (new block_gateway_impl(handler, name, in_sig, out_sig,
+ work_type, factor));
+ }
+
+ block_gateway_impl::block_gateway_impl(feval_ll *handler,
+ const std::string &name,
+ gr::io_signature::sptr in_sig,
+ gr::io_signature::sptr out_sig,
+ const block_gw_work_type work_type,
+ const unsigned factor)
+ : block(name, in_sig, out_sig),
+ _handler(handler),
+ _work_type(work_type)
+ {
+ switch(_work_type) {
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _decim = 1; //not relevant, but set anyway
+ _interp = 1; //not relevant, but set anyway
+ break;
+
+ case GR_BLOCK_GW_WORK_SYNC:
+ _decim = 1;
+ _interp = 1;
+ this->set_fixed_rate(true);
+ break;
+
+ case GR_BLOCK_GW_WORK_DECIM:
+ _decim = factor;
+ _interp = 1;
+ break;
+
+ case GR_BLOCK_GW_WORK_INTERP:
+ _decim = 1;
+ _interp = factor;
+ this->set_output_multiple(_interp);
+ break;
+ }
+ }
+
+ void
+ block_gateway_impl::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ switch(_work_type) {
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _message.action = block_gw_message_type::ACTION_FORECAST;
+ _message.forecast_args_noutput_items = noutput_items;
+ _message.forecast_args_ninput_items_required = ninput_items_required;
+ _handler->calleval(0);
+ ninput_items_required = _message.forecast_args_ninput_items_required;
+ return;
+
+ default:
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ return;
+ }
+ }
+
+ int
+ block_gateway_impl::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ switch(_work_type) {
+ case GR_BLOCK_GW_WORK_GENERAL:
+ _message.action = block_gw_message_type::ACTION_GENERAL_WORK;
+ _message.general_work_args_noutput_items = noutput_items;
+ _message.general_work_args_ninput_items = ninput_items;
+ copy_pointers(_message.general_work_args_input_items, input_items);
+ _message.general_work_args_output_items = output_items;
+ _handler->calleval(0);
+ return _message.general_work_args_return_value;
+
+ default:
+ int r = work (noutput_items, input_items, output_items);
+ if(r > 0)
+ consume_each(r*_decim/_interp);
+ return r;
+ }
+ }
+
+ int
+ block_gateway_impl::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ _message.action = block_gw_message_type::ACTION_WORK;
+ _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items);
+ if(_message.work_args_ninput_items == 0)
+ return -1;
+ _message.work_args_noutput_items = noutput_items;
+ copy_pointers(_message.work_args_input_items, input_items);
+ _message.work_args_output_items = output_items;
+ _handler->calleval(0);
+ return _message.work_args_return_value;
+ }
+
+ int
+ block_gateway_impl::fixed_rate_noutput_to_ninput(int noutput_items)
+ {
+ return (noutput_items*_decim/_interp) + history() - 1;
+ }
+
+ int
+ block_gateway_impl::fixed_rate_ninput_to_noutput(int ninput_items)
+ {
+ return std::max(0, ninput_items - (int)history() + 1)*_interp/_decim;
+ }
+
+ bool
+ block_gateway_impl::start(void)
+ {
+ _message.action = block_gw_message_type::ACTION_START;
+ _handler->calleval(0);
+ return _message.start_args_return_value;
+ }
+
+ bool
+ block_gateway_impl::stop(void)
+ {
+ _message.action = block_gw_message_type::ACTION_STOP;
+ _handler->calleval(0);
+ return _message.stop_args_return_value;
+ }
+
+ block_gw_message_type&
+ block_gateway_impl::block_message(void)
+ {
+ return _message;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/block_gateway_impl.h b/gnuradio-runtime/lib/block_gateway_impl.h
new file mode 100644
index 0000000000..1707ecf1c8
--- /dev/null
+++ b/gnuradio-runtime/lib/block_gateway_impl.h
@@ -0,0 +1,75 @@
+/* -*- 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.
+ */
+
+#ifndef INCLUDED_RUNTIME_BLOCK_GATEWAY_IMPL_H
+#define INCLUDED_RUNTIME_BLOCK_GATEWAY_IMPL_H
+
+#include <gnuradio/block_gateway.h>
+
+namespace gr {
+
+ /***********************************************************************
+ * The gr::block gateway implementation class
+ **********************************************************************/
+ class block_gateway_impl : public block_gateway
+ {
+ public:
+ block_gateway_impl(feval_ll *handler,
+ const std::string &name,
+ gr::io_signature::sptr in_sig,
+ gr::io_signature::sptr out_sig,
+ const block_gw_work_type work_type,
+ const unsigned factor);
+
+ /*******************************************************************
+ * Overloads for various scheduler-called functions
+ ******************************************************************/
+ void forecast(int noutput_items,
+ gr_vector_int &ninput_items_required);
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ int work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ int fixed_rate_noutput_to_ninput(int noutput_items);
+ int fixed_rate_ninput_to_noutput(int ninput_items);
+
+ bool start(void);
+ bool stop(void);
+
+ block_gw_message_type& block_message(void);
+
+ private:
+ feval_ll *_handler;
+ block_gw_message_type _message;
+ const block_gw_work_type _work_type;
+ unsigned _decim, _interp;
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_RUNTIME_BLOCK_GATEWAY_H */
diff --git a/gnuradio-runtime/lib/block_registry.cc b/gnuradio-runtime/lib/block_registry.cc
new file mode 100644
index 0000000000..f17e3e4af9
--- /dev/null
+++ b/gnuradio-runtime/lib/block_registry.cc
@@ -0,0 +1,120 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012-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/basic_block.h>
+#include <gnuradio/block.h>
+#include <gnuradio/block_detail.h>
+#include <gnuradio/block_registry.h>
+#include <gnuradio/tpb_detail.h>
+#include <stdio.h>
+
+gr::block_registry global_block_registry;
+
+namespace gr {
+
+ block_registry::block_registry()
+ {
+ d_ref_map = pmt::make_dict();
+ }
+
+ long
+ block_registry::block_register(basic_block* block)
+ {
+ if(d_map.find(block->name()) == d_map.end()) {
+ d_map[block->name()] = blocksubmap_t();
+ d_map[block->name()][0] = block;
+ return 0;
+ }
+ else {
+ for(size_t i=0; i<=d_map[block->name()].size(); i++){
+ if(d_map[block->name()].find(i) == d_map[block->name()].end()){
+ d_map[block->name()][i] = block;
+ return i;
+ }
+ }
+ }
+ throw std::runtime_error("should not reach this");
+ }
+
+ void
+ block_registry::block_unregister(basic_block* block)
+ {
+ d_map[block->name()].erase( d_map[block->name()].find(block->symbolic_id()));
+ d_ref_map = pmt::dict_delete(d_ref_map, pmt::intern(block->symbol_name()));
+ if(block->alias_set()) {
+ d_ref_map = pmt::dict_delete(d_ref_map, pmt::intern(block->alias()));
+ }
+ }
+
+ std::string
+ block_registry::register_symbolic_name(basic_block* block)
+ {
+ std::stringstream ss;
+ ss << block->name() << block->symbolic_id();
+ //std::cout << "register_symbolic_name: " << ss.str() << std::endl;
+ register_symbolic_name(block, ss.str());
+ return ss.str();
+ }
+
+ void
+ block_registry::register_symbolic_name(basic_block* block, std::string name)
+ {
+ if(pmt::dict_has_key(d_ref_map, pmt::intern(name))) {
+ throw std::runtime_error("symbol already exists, can not re-use!");
+ }
+ d_ref_map = pmt::dict_add(d_ref_map, pmt::intern(name), pmt::make_any(block));
+ }
+
+ basic_block_sptr
+ block_registry::block_lookup(pmt::pmt_t symbol)
+ {
+ pmt::pmt_t ref = pmt::dict_ref(d_ref_map, symbol, pmt::PMT_NIL);
+ if(pmt::eq(ref, pmt::PMT_NIL)) {
+ throw std::runtime_error("block lookup failed! block not found!");
+ }
+ basic_block* blk = boost::any_cast<basic_block*>(pmt::any_ref(ref));
+ return blk->shared_from_this();
+ }
+
+ void
+ block_registry::register_primitive(std::string blk, block* ref)
+ {
+ primitive_map[blk] = ref;
+ }
+
+ void
+ block_registry::unregister_primitive(std::string blk)
+ {
+ primitive_map.erase(primitive_map.find(blk));
+ }
+
+ void
+ block_registry::notify_blk(std::string blk)
+ {
+ if(primitive_map.find(blk) == primitive_map.end()) {
+ return;
+ }
+ if(primitive_map[blk]->detail().get())
+ primitive_map[blk]->detail()->d_tpb.notify_msg();
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/buffer.cc b/gnuradio-runtime/lib/buffer.cc
new file mode 100644
index 0000000000..1bcfc2a6e4
--- /dev/null
+++ b/gnuradio-runtime/lib/buffer.cc
@@ -0,0 +1,343 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2009,2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/buffer.h>
+#include <gnuradio/math.h>
+#include "vmcircbuf.h"
+#include <stdexcept>
+#include <iostream>
+#include <assert.h>
+#include <algorithm>
+#include <boost/math/common_factor_rt.hpp>
+
+namespace gr {
+
+ static long s_buffer_count = 0; // counts for debugging storage mgmt
+ static long s_buffer_reader_count = 0;
+
+ /* ----------------------------------------------------------------------------
+ Notes on storage management
+
+ Pretty much all the fundamental classes are now using the
+ shared_ptr stuff for automatic reference counting. To ensure that
+ no mistakes are made, we make the constructors for classes private,
+ and then provide a free factory function that returns a smart
+ pointer to the desired class.
+
+ gr::buffer and gr::buffer_reader are no exceptions. However, they
+ both want pointers to each other, and unless we do something, we'll
+ never delete any of them because of the circular structure.
+ They'll always have a reference count of at least one. We could
+ use boost::weak_ptr's from gr::buffer to gr::buffer_reader but that
+ introduces it's own problems. (gr::buffer_reader's destructor needs
+ to call gr::buffer::drop_reader, but has no easy way to get a
+ shared_ptr to itself.)
+
+ Instead, we solve this problem by having gr::buffer hold a raw
+ pointer to gr::buffer_reader in its d_reader vector.
+ gr::buffer_reader's destructor calls gr::buffer::drop_reader, so
+ we're never left with an dangling pointer. gr::buffer_reader still
+ has a shared_ptr to the buffer ensuring that the buffer doesn't go
+ away under it. However, when the reference count of a
+ gr::buffer_reader goes to zero, we can successfully reclaim it.
+ ---------------------------------------------------------------------------- */
+
+ /*
+ * Compute the minimum number of buffer items that work (i.e.,
+ * address space wrap-around works). To work is to satisfy this
+ * contraint for integer buffer_size and k:
+ *
+ * type_size * nitems == k * page_size
+ */
+ static long
+ minimum_buffer_items(long type_size, long page_size)
+ {
+ return page_size / boost::math::gcd (type_size, page_size);
+ }
+
+
+ buffer::buffer(int nitems, size_t sizeof_item, block_sptr link)
+ : d_base(0), d_bufsize(0), d_vmcircbuf(0),
+ d_sizeof_item(sizeof_item), d_link(link),
+ d_write_index(0), d_abs_write_offset(0), d_done(false),
+ d_last_min_items_read(0)
+ {
+ if(!allocate_buffer (nitems, sizeof_item))
+ throw std::bad_alloc ();
+
+ s_buffer_count++;
+ }
+
+ buffer_sptr
+ make_buffer(int nitems, size_t sizeof_item, block_sptr link)
+ {
+ return buffer_sptr(new buffer(nitems, sizeof_item, link));
+ }
+
+ buffer::~buffer()
+ {
+ delete d_vmcircbuf;
+ assert(d_readers.size() == 0);
+ s_buffer_count--;
+ }
+
+ /*!
+ * sets d_vmcircbuf, d_base, d_bufsize.
+ * returns true iff successful.
+ */
+ bool
+ buffer::allocate_buffer(int nitems, size_t sizeof_item)
+ {
+ int orig_nitems = nitems;
+
+ // Any buffersize we come up with must be a multiple of min_nitems.
+ int granularity = gr::vmcircbuf_sysconfig::granularity();
+ int min_nitems = minimum_buffer_items(sizeof_item, granularity);
+
+ // Round-up nitems to a multiple of min_nitems.
+ if(nitems % min_nitems != 0)
+ nitems = ((nitems / min_nitems) + 1) * min_nitems;
+
+ // If we rounded-up a whole bunch, give the user a heads up.
+ // This only happens if sizeof_item is not a power of two.
+
+ if(nitems > 2 * orig_nitems && nitems * (int) sizeof_item > granularity){
+ std::cerr << "gr::buffer::allocate_buffer: warning: tried to allocate\n"
+ << " " << orig_nitems << " items of size "
+ << sizeof_item << ". Due to alignment requirements\n"
+ << " " << nitems << " were allocated. If this isn't OK, consider padding\n"
+ << " your structure to a power-of-two bytes.\n"
+ << " On this platform, our allocation granularity is " << granularity << " bytes.\n";
+ }
+
+ d_bufsize = nitems;
+ d_vmcircbuf = gr::vmcircbuf_sysconfig::make(d_bufsize * d_sizeof_item);
+ if(d_vmcircbuf == 0){
+ std::cerr << "gr::buffer::allocate_buffer: failed to allocate buffer of size "
+ << d_bufsize * d_sizeof_item / 1024 << " KB\n";
+ return false;
+ }
+
+ d_base = (char*)d_vmcircbuf->pointer_to_first_copy();
+ return true;
+ }
+
+ int
+ buffer::space_available()
+ {
+ if(d_readers.empty())
+ return d_bufsize - 1; // See comment below
+
+ else {
+ // Find out the maximum amount of data available to our readers
+
+ int most_data = d_readers[0]->items_available();
+ uint64_t min_items_read = d_readers[0]->nitems_read();
+ for(size_t i = 1; i < d_readers.size (); i++) {
+ most_data = std::max(most_data, d_readers[i]->items_available());
+ min_items_read = std::min(min_items_read, d_readers[i]->nitems_read());
+ }
+
+ if(min_items_read != d_last_min_items_read) {
+ prune_tags(d_last_min_items_read);
+ d_last_min_items_read = min_items_read;
+ }
+
+ // The -1 ensures that the case d_write_index == d_read_index is
+ // unambiguous. It indicates that there is no data for the reader
+ return d_bufsize - most_data - 1;
+ }
+ }
+
+ void *
+ buffer::write_pointer()
+ {
+ return &d_base[d_write_index * d_sizeof_item];
+ }
+
+ void
+ buffer::update_write_pointer(int nitems)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+ d_write_index = index_add(d_write_index, nitems);
+ d_abs_write_offset += nitems;
+ }
+
+ void
+ buffer::set_done(bool done)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+ d_done = done;
+ }
+
+ buffer_reader_sptr
+ buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link)
+ {
+ if(nzero_preload < 0)
+ throw std::invalid_argument("buffer_add_reader: nzero_preload must be >= 0");
+
+ buffer_reader_sptr r(new buffer_reader(buf,
+ buf->index_sub(buf->d_write_index,
+ nzero_preload),
+ link));
+ buf->d_readers.push_back(r.get ());
+
+ return r;
+ }
+
+ void
+ buffer::drop_reader(buffer_reader *reader)
+ {
+ std::vector<buffer_reader *>::iterator result =
+ std::find(d_readers.begin(), d_readers.end(), reader);
+
+ if(result == d_readers.end())
+ throw std::invalid_argument("buffer::drop_reader"); // we didn't find it...
+
+ d_readers.erase(result);
+ }
+
+ void
+ buffer::add_item_tag(const tag_t &tag)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+ d_item_tags.push_back(tag);
+ }
+
+ void
+ buffer::remove_item_tag(const tag_t &tag)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+ for(std::deque<tag_t>::iterator it = d_item_tags.begin(); it != d_item_tags.end(); ++it) {
+ if(*it == tag) {
+ d_item_tags.erase(it);
+ break;
+ }
+ }
+ }
+
+ void
+ buffer::prune_tags(uint64_t max_time)
+ {
+ /* NOTE: this function _should_ lock the mutex before editing
+ d_item_tags. In practice, this function is only called at
+ runtime by min_available_space in block_executor.cc, which
+ locks the mutex itself.
+
+ If this function is used elsewhere, remember to lock the
+ buffer's mutex al la the scoped_lock line below.
+ */
+ //gr::thread::scoped_lock guard(*mutex());
+ std::deque<tag_t>::iterator itr = d_item_tags.begin();
+
+ uint64_t item_time;
+
+ // Since tags are not guarenteed to be in any particular order, we
+ // need to erase here instead of pop_front. An erase in the middle
+ // invalidates all iterators; so this resets the iterator to find
+ // more. Mostly, we wil be erasing from the front and
+ // therefore lose little time this way.
+ while(itr != d_item_tags.end()) {
+ item_time = (*itr).offset;
+ if(item_time < max_time) {
+ d_item_tags.erase(itr);
+ itr = d_item_tags.begin();
+ }
+ else
+ itr++;
+ }
+ }
+
+ long
+ buffer_ncurrently_allocated()
+ {
+ return s_buffer_count;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ buffer_reader::buffer_reader(buffer_sptr buffer, unsigned int read_index,
+ block_sptr link)
+ : d_buffer(buffer), d_read_index(read_index), d_abs_read_offset(0), d_link(link)
+ {
+ s_buffer_reader_count++;
+ }
+
+ buffer_reader::~buffer_reader()
+ {
+ d_buffer->drop_reader(this);
+ s_buffer_reader_count--;
+ }
+
+ int
+ buffer_reader::items_available() const
+ {
+ return d_buffer->index_sub(d_buffer->d_write_index, d_read_index);
+ }
+
+ const void *
+ buffer_reader::read_pointer()
+ {
+ return &d_buffer->d_base[d_read_index * d_buffer->d_sizeof_item];
+ }
+
+ void
+ buffer_reader::update_read_pointer(int nitems)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+ d_read_index = d_buffer->index_add (d_read_index, nitems);
+ d_abs_read_offset += nitems;
+ }
+
+ void
+ buffer_reader::get_tags_in_range(std::vector<tag_t> &v,
+ uint64_t abs_start,
+ uint64_t abs_end)
+ {
+ gr::thread::scoped_lock guard(*mutex());
+
+ v.resize(0);
+ std::deque<tag_t>::iterator itr = d_buffer->get_tags_begin();
+
+ uint64_t item_time;
+ while(itr != d_buffer->get_tags_end()) {
+ item_time = (*itr).offset;
+
+ if((item_time >= abs_start) && (item_time < abs_end)) {
+ v.push_back(*itr);
+ }
+
+ itr++;
+ }
+ }
+
+ long
+ buffer_reader_ncurrently_allocated()
+ {
+ return s_buffer_reader_count;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/circular_file.cc b/gnuradio-runtime/lib/circular_file.cc
new file mode 100644
index 0000000000..4d7d06082a
--- /dev/null
+++ b/gnuradio-runtime/lib/circular_file.cc
@@ -0,0 +1,208 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "circular_file.h"
+
+#include <unistd.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include <algorithm>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+namespace gr {
+
+ static const int HEADER_SIZE = 4096;
+ static const int HEADER_MAGIC = 0xEB021026;
+
+ static const int HD_MAGIC = 0;
+ static const int HD_HEADER_SIZE = 1; // integer offsets into header
+ static const int HD_BUFFER_SIZE = 2;
+ static const int HD_BUFFER_BASE = 3;
+ static const int HD_BUFFER_CURRENT = 4;
+
+ circular_file::circular_file(const char *filename,
+ bool writable, int size)
+ : d_fd(-1), d_header(0), d_buffer(0), d_mapped_size(0), d_bytes_read(0)
+ {
+ int mm_prot;
+ if(writable) {
+#ifdef HAVE_MMAP
+ mm_prot = PROT_READ | PROT_WRITE;
+#endif
+ d_fd = open(filename, O_CREAT | O_RDWR | O_TRUNC, 0664);
+ if(d_fd < 0) {
+ perror(filename);
+ exit(1);
+ }
+#ifdef HAVE_MMAP /* FIXME */
+ if(ftruncate(d_fd, size + HEADER_SIZE) != 0) {
+ perror(filename);
+ exit(1);
+ }
+#endif
+ }
+ else {
+#ifdef HAVE_MMAP
+ mm_prot = PROT_READ;
+#endif
+ d_fd = open (filename, O_RDONLY);
+ if(d_fd < 0) {
+ perror(filename);
+ exit(1);
+ }
+ }
+
+ struct stat statbuf;
+ if(fstat (d_fd, &statbuf) < 0) {
+ perror(filename);
+ exit(1);
+ }
+
+ if(statbuf.st_size < HEADER_SIZE) {
+ fprintf(stderr, "%s: file too small to be circular buffer\n", filename);
+ exit(1);
+ }
+
+ d_mapped_size = statbuf.st_size;
+#ifdef HAVE_MMAP
+ void *p = mmap (0, d_mapped_size, mm_prot, MAP_SHARED, d_fd, 0);
+ if(p == MAP_FAILED) {
+ perror("gr::circular_file: mmap failed");
+ exit(1);
+ }
+
+ d_header = (int*)p;
+#else
+ perror("gr::circular_file: mmap unsupported by this system");
+ exit(1);
+#endif
+
+ if(writable) { // init header
+
+ if(size < 0) {
+ fprintf(stderr, "gr::circular_buffer: size must be > 0 when writable\n");
+ exit(1);
+ }
+
+ d_header[HD_MAGIC] = HEADER_MAGIC;
+ d_header[HD_HEADER_SIZE] = HEADER_SIZE;
+ d_header[HD_BUFFER_SIZE] = size;
+ d_header[HD_BUFFER_BASE] = HEADER_SIZE; // right after header
+ d_header[HD_BUFFER_CURRENT] = 0;
+ }
+
+ // sanity check (the asserts are a bit unforgiving...)
+
+ assert(d_header[HD_MAGIC] == HEADER_MAGIC);
+ assert(d_header[HD_HEADER_SIZE] == HEADER_SIZE);
+ assert(d_header[HD_BUFFER_SIZE] > 0);
+ assert(d_header[HD_BUFFER_BASE] >= d_header[HD_HEADER_SIZE]);
+ assert(d_header[HD_BUFFER_BASE] + d_header[HD_BUFFER_SIZE] <= d_mapped_size);
+ assert(d_header[HD_BUFFER_CURRENT] >= 0 &&
+ d_header[HD_BUFFER_CURRENT] < d_header[HD_BUFFER_SIZE]);
+
+ d_bytes_read = 0;
+ d_buffer = (unsigned char*)d_header + d_header[HD_BUFFER_BASE];
+ }
+
+ circular_file::~circular_file()
+ {
+#ifdef HAVE_MMAP
+ if(munmap ((char *) d_header, d_mapped_size) < 0) {
+ perror("gr::circular_file: munmap");
+ exit(1);
+ }
+#endif
+ close(d_fd);
+ }
+
+ bool
+ circular_file::write(void *vdata, int nbytes)
+ {
+ unsigned char *data = (unsigned char*)vdata;
+ int buffer_size = d_header[HD_BUFFER_SIZE];
+ int buffer_current = d_header[HD_BUFFER_CURRENT];
+
+ while(nbytes > 0) {
+ int n = std::min(nbytes, buffer_size - buffer_current);
+ memcpy(d_buffer + buffer_current, data, n);
+
+ buffer_current += n;
+ if(buffer_current >= buffer_size)
+ buffer_current = 0;
+
+ data += n;
+ nbytes -= n;
+ }
+
+ d_header[HD_BUFFER_CURRENT] = buffer_current;
+ return true;
+ }
+
+ int
+ circular_file::read(void *vdata, int nbytes)
+ {
+ unsigned char *data = (unsigned char *) vdata;
+ int buffer_current = d_header[HD_BUFFER_CURRENT];
+ int buffer_size = d_header[HD_BUFFER_SIZE];
+ int total = 0;
+
+ nbytes = std::min(nbytes, buffer_size - d_bytes_read);
+
+ while(nbytes > 0) {
+ int offset = (buffer_current + d_bytes_read) % buffer_size;
+ int n = std::min (nbytes, buffer_size - offset);
+ memcpy(data, d_buffer + offset, n);
+ data += n;
+ d_bytes_read += n;
+ total += n;
+ nbytes -= n;
+ }
+ return total;
+ }
+
+ void
+ circular_file::reset_read_pointer()
+ {
+ d_bytes_read = 0;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/circular_file.h b/gnuradio-runtime/lib/circular_file.h
new file mode 100644
index 0000000000..1dc431d69a
--- /dev/null
+++ b/gnuradio-runtime/lib/circular_file.h
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,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.
+ */
+
+#ifndef GR_CIRCULAR_FILE_H
+#define GR_CIRCULAR_FILE_H
+
+#include <gnuradio/api.h>
+
+namespace gr {
+
+ /*
+ * writes input data into a circular buffer on disk.
+ *
+ * the file contains a fixed header:
+ * 0x0000: int32 magic (0xEB021026)
+ * 0x0004: int32 size in bytes of header (constant 4096)
+ * 0x0008: int32 size in bytes of circular buffer (not including header)
+ * 0x000C: int32 file offset to beginning of circular buffer
+ * 0x0010: int32 byte offset from beginning of circular buffer to
+ * current start of data
+ */
+ class GR_RUNTIME_API circular_file
+ {
+ private:
+ int d_fd;
+ int *d_header;
+ unsigned char *d_buffer;
+ int d_mapped_size;
+ int d_bytes_read;
+
+ public:
+ circular_file(const char *filename, bool writable = false, int size = 0);
+ ~circular_file();
+
+ bool write(void *data, int nbytes);
+
+ // returns # of bytes actually read or 0 if end of buffer, or -1 on error.
+ int read(void *data, int nbytes);
+
+ // reset read pointer to beginning of buffer.
+ void reset_read_pointer();
+ };
+
+} /* namespace gr */
+
+#endif /* GR_CIRCULAR_FILE_H */
diff --git a/gnuradio-runtime/lib/complex_vec_test.h b/gnuradio-runtime/lib/complex_vec_test.h
index bcfa732f41..d69d523374 100644
--- a/gnuradio-runtime/lib/complex_vec_test.h
+++ b/gnuradio-runtime/lib/complex_vec_test.h
@@ -1,4 +1,26 @@
-#include <gr_runtime_api.h>
+/* -*- 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>
diff --git a/gnuradio-runtime/lib/gr_constants.cc.in b/gnuradio-runtime/lib/constants.cc.in
index b94f254d66..828c4397f7 100644
--- a/gnuradio-runtime/lib/gr_constants.cc.in
+++ b/gnuradio-runtime/lib/constants.cc.in
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006,2009 Free Software Foundation, Inc.
+ * Copyright 2006,2009,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,34 +24,38 @@
#include <config.h>
#endif
-#include <gr_constants.h>
-
-const std::string
-gr_prefix()
-{
- return "@prefix@";
-}
-
-const std::string
-gr_sysconfdir()
-{
- return "@SYSCONFDIR@";
-}
-
-const std::string
-gr_prefsdir()
-{
- return "@GR_PREFSDIR@";
-}
-
-const std::string
-gr_build_date()
-{
- return "@BUILD_DATE@";
-}
-
-const std::string
-gr_version()
-{
- return "@VERSION@";
-}
+#include <gnuradio/constants.h>
+
+namespace gr {
+
+ const std::string
+ prefix()
+ {
+ return "@prefix@";
+ }
+
+ const std::string
+ sysconfdir()
+ {
+ return "@SYSCONFDIR@";
+ }
+
+ const std::string
+ prefsdir()
+ {
+ return "@GR_PREFSDIR@";
+ }
+
+ const std::string
+ build_date()
+ {
+ return "@BUILD_DATE@";
+ }
+
+ const std::string
+ version()
+ {
+ return "@VERSION@";
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/controlport/CMakeLists.txt b/gnuradio-runtime/lib/controlport/CMakeLists.txt
new file mode 100644
index 0000000000..c05a82bf4f
--- /dev/null
+++ b/gnuradio-runtime/lib/controlport/CMakeLists.txt
@@ -0,0 +1,62 @@
+# 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.
+
+if(ENABLE_GR_CTRLPORT)
+
+include_directories(${ICE_INCLUDE_DIR})
+
+# Add definition so we can compile in ControlPort to the blocks.
+ADD_DEFINITIONS(-DGR_CTRLPORT)
+
+########################################################################
+# Run ICE To compile Slice files
+########################################################################
+EXECUTE_PROCESS(
+ COMMAND "${ICE_SLICE2CPP}" "-I${CMAKE_CURRENT_SOURCE_DIR}"
+ "--output-dir=${CMAKE_CURRENT_BINARY_DIR}/"
+ "${CMAKE_CURRENT_SOURCE_DIR}/gnuradio.ice"
+ )
+
+list(APPEND gnuradio_runtime_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/ice_application_base.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcmanager.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcpmtconverters_ice.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_aggregator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_booter_aggregator.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_booter_ice.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_ice.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/rpcserver_selector.cc
+)
+
+# Append generated file in build directory
+list(APPEND gnuradio_runtime_sources
+ ${CMAKE_CURRENT_BINARY_DIR}/gnuradio.cpp
+)
+
+########################################################################
+# Add controlport stuff to gnuradio-runtime
+########################################################################
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+list(APPEND gnuradio_runtime_libs
+ ${ICE_LIBRARIES}
+)
+
+endif(ENABLE_GR_CTRLPORT)
diff --git a/gnuradio-runtime/lib/ICE_LICENSE b/gnuradio-runtime/lib/controlport/ICE_LICENSE
index 43ea7572d9..43ea7572d9 100644
--- a/gnuradio-runtime/lib/ICE_LICENSE
+++ b/gnuradio-runtime/lib/controlport/ICE_LICENSE
diff --git a/gnuradio-runtime/lib/frontend.ice b/gnuradio-runtime/lib/controlport/frontend.ice
index b7474f37bf..b7474f37bf 100644
--- a/gnuradio-runtime/lib/frontend.ice
+++ b/gnuradio-runtime/lib/controlport/frontend.ice
diff --git a/gnuradio-runtime/lib/gnuradio.ice b/gnuradio-runtime/lib/controlport/gnuradio.ice
index 731cbea956..731cbea956 100644
--- a/gnuradio-runtime/lib/gnuradio.ice
+++ b/gnuradio-runtime/lib/controlport/gnuradio.ice
diff --git a/gnuradio-runtime/lib/ice_application_base.cc b/gnuradio-runtime/lib/controlport/ice_application_base.cc
index 88db6056c1..b390c77c84 100644
--- a/gnuradio-runtime/lib/ice_application_base.cc
+++ b/gnuradio-runtime/lib/controlport/ice_application_base.cc
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <ice_application_base.h>
+#include <gnuradio/ice_application_base.h>
int ice_application_common::d_reacquire_attributes(0);
bool ice_application_common::d_main_called(false);
diff --git a/gnuradio-runtime/lib/rpcmanager.cc b/gnuradio-runtime/lib/controlport/rpcmanager.cc
index 4d164b63f3..59ec518960 100644
--- a/gnuradio-runtime/lib/rpcmanager.cc
+++ b/gnuradio-runtime/lib/controlport/rpcmanager.cc
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcmanager.h>
+#include <gnuradio/rpcmanager.h>
#include <iostream>
#include <stdexcept>
diff --git a/gnuradio-runtime/lib/rpcpmtconverters_ice.cc b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc
index 7c8b6041e9..18b73faeba 100644
--- a/gnuradio-runtime/lib/rpcpmtconverters_ice.cc
+++ b/gnuradio-runtime/lib/controlport/rpcpmtconverters_ice.cc
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcpmtconverters_ice.h>
+#include <gnuradio/rpcpmtconverters_ice.h>
#include <Ice/Ice.h>
#include <gnuradio.h>
diff --git a/gnuradio-runtime/lib/rpcserver_aggregator.cc b/gnuradio-runtime/lib/controlport/rpcserver_aggregator.cc
index d750d64905..3ff553af69 100644
--- a/gnuradio-runtime/lib/rpcserver_aggregator.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_aggregator.cc
@@ -20,8 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcserver_aggregator.h>
-#include <rpcserver_booter_base.h>
+#include <gnuradio/rpcserver_aggregator.h>
+#include <gnuradio/rpcserver_booter_base.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
diff --git a/gnuradio-runtime/lib/rpcserver_booter_aggregator.cc b/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc
index c4c1b03c15..e86306910d 100644
--- a/gnuradio-runtime/lib/rpcserver_booter_aggregator.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_booter_aggregator.cc
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcserver_booter_aggregator.h>
+#include <gnuradio/rpcserver_booter_aggregator.h>
rpcserver_booter_aggregator::rpcserver_booter_aggregator() :
d_type(std::string("aggregator")), server(new rpcserver_aggregator())
diff --git a/gnuradio-runtime/lib/rpcserver_booter_ice.cc b/gnuradio-runtime/lib/controlport/rpcserver_booter_ice.cc
index 7cc8cc8938..cffa268a6d 100644
--- a/gnuradio-runtime/lib/rpcserver_booter_ice.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_booter_ice.cc
@@ -20,8 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcserver_ice.h>
-#include <rpcserver_booter_ice.h>
+#include <gnuradio/rpcserver_ice.h>
+#include <gnuradio/rpcserver_booter_ice.h>
namespace {
static const char* const CONTROL_PORT_CLASS("ice");
diff --git a/gnuradio-runtime/lib/rpcserver_ice.cc b/gnuradio-runtime/lib/controlport/rpcserver_ice.cc
index 2454bf2580..045d7ba4f1 100644
--- a/gnuradio-runtime/lib/rpcserver_ice.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_ice.cc
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcserver_ice.h>
+#include <gnuradio/rpcserver_ice.h>
#include <IceUtil/IceUtil.h>
#include <Ice/Ice.h>
#include <iostream>
diff --git a/gnuradio-runtime/lib/rpcserver_selector.cc b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
index 362d5f060a..697ec497b1 100644
--- a/gnuradio-runtime/lib/rpcserver_selector.cc
+++ b/gnuradio-runtime/lib/controlport/rpcserver_selector.cc
@@ -20,14 +20,14 @@
* Boston, MA 02110-1301, USA.
*/
-#include <rpcserver_booter_aggregator.h>
-#include <rpcmanager.h>
-#include <rpcserver_selector.h>
+#include <gnuradio/rpcserver_booter_aggregator.h>
+#include <gnuradio/rpcmanager.h>
+#include <gnuradio/rpcserver_selector.h>
bool rpcmanager::make_aggregator(false);
#ifdef RPCSERVER_ICE
- #include <rpcserver_booter_ice.h>
+ #include <gnuradio/rpcserver_booter_ice.h>
rpcmanager::rpcserver_booter_register_helper<rpcserver_booter_ice> boot_ice;
#endif
diff --git a/gnuradio-runtime/lib/dispatcher.cc b/gnuradio-runtime/lib/dispatcher.cc
new file mode 100644
index 0000000000..7c9e13c5a6
--- /dev/null
+++ b/gnuradio-runtime/lib/dispatcher.cc
@@ -0,0 +1,195 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/dispatcher.h>
+#include <math.h>
+#include <errno.h>
+#include <stdio.h>
+
+#ifdef HAVE_SELECT
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
+# ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+# endif
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# endif
+#endif
+
+namespace gr {
+
+ static dispatcher_sptr s_singleton;
+
+ dispatcher_sptr
+ make_dispatcher()
+ {
+ return dispatcher_sptr(new dispatcher());
+ }
+
+ dispatcher_sptr
+ dispatcher_singleton()
+ {
+ if(s_singleton)
+ return s_singleton;
+
+ s_singleton = make_dispatcher();
+ return s_singleton;
+ }
+
+#if !defined(HAVE_SELECT) // Stub it out
+
+ dispatcher::dispatcher()
+ {
+ }
+
+ dispatcher::~dispatcher()
+ {
+ }
+
+ bool
+ dispatcher::add_handler(select_handler_sptr handler)
+ {
+ return true;
+ }
+
+ bool
+ dispatcher::del_handler(select_handler_sptr handler)
+ {
+ return true;
+ }
+
+ bool
+ dispatcher::del_handler(select_handler *handler)
+ {
+ return true;
+ }
+
+ void
+ dispatcher::loop(double timeout)
+ {
+ }
+
+#else // defined(HAVE_SELECT)
+
+ dispatcher::dispatcher()
+ : d_handler(FD_SETSIZE), d_max_index(-1)
+ {
+ }
+
+ dispatcher::~dispatcher()
+ {
+ }
+
+ bool
+ dispatcher::add_handler(select_handler_sptr handler)
+ {
+ int fd = handler->fd();
+ if(fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_max_index = std::max(d_max_index, fd);
+ d_handler[fd] = handler;
+ return true;
+ }
+
+ bool
+ dispatcher::del_handler(select_handler_sptr handler)
+ {
+ return del_handler(handler.get());
+ }
+
+ bool
+ dispatcher::del_handler(select_handler *handler)
+ {
+ int fd = handler->fd();
+ if(fd < 0 || fd >= FD_SETSIZE)
+ return false;
+
+ d_handler[fd].reset();
+
+ if(fd == d_max_index) {
+ int i;
+ for(i = fd - 1; i >= 0 && !d_handler[i]; i--)
+ ;
+ d_max_index = i;
+ }
+ return true;
+ }
+
+ void
+ dispatcher::loop(double timeout)
+ {
+ struct timeval master;
+ struct timeval tmp;
+ fd_set rd_set;
+ fd_set wr_set;
+
+ double secs = floor (timeout);
+ master.tv_sec = (long) secs;
+ master.tv_usec = (long) ((timeout - secs) * 1e6);
+
+ while(d_max_index >= 0) {
+ FD_ZERO(&rd_set);
+ FD_ZERO(&wr_set);
+
+ for(int i = 0; i <= d_max_index; i++) {
+ if(d_handler[i] && d_handler[i]->readable())
+ FD_SET(i, &rd_set);
+ if(d_handler[i] && d_handler[i]->writable())
+ FD_SET(i, &wr_set);
+ }
+
+ tmp = master;
+ int retval = select(d_max_index+1, &rd_set, &wr_set, 0, &tmp);
+ if(retval == 0) // timed out with nothing ready
+ continue;
+ if(retval < 0) {
+ if(errno == EINTR)
+ continue;
+ perror("gr_dispatcher/select");
+ return;
+ }
+
+ for(int i = 0; i <= d_max_index; i++) {
+ if(FD_ISSET(i, &rd_set))
+ if(d_handler[i])
+ d_handler[i]->handle_read();
+ if(FD_ISSET(i, &wr_set))
+ if(d_handler[i])
+ d_handler[i]->handle_write();
+ }
+ }
+ }
+
+} /* namespace gr */
+
+#endif /* HAVE_SELECT */
diff --git a/gnuradio-runtime/lib/error_handler.cc b/gnuradio-runtime/lib/error_handler.cc
new file mode 100644
index 0000000000..50db15d049
--- /dev/null
+++ b/gnuradio-runtime/lib/error_handler.cc
@@ -0,0 +1,249 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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.
+ */
+/*
+ * This code is based on error.cc from the "Click Modular Router".
+ * Original copyright follows:
+ */
+/*
+ * error.{cc,hh} -- flexible classes for error reporting
+ * Eddie Kohler
+ *
+ * Copyright (c) 1999-2000 Massachusetts Institute of Technology
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, subject to the conditions
+ * listed in the Click LICENSE file. These conditions include: you must
+ * preserve this copyright notice, and you cannot mention the copyright
+ * holders in advertising related to the Software without their permission.
+ * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
+ * notice is a summary of the Click LICENSE file; the license in that file is
+ * legally binding.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/error_handler.h>
+#include <assert.h>
+#include <stdexcept>
+#include <unistd.h>
+
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+namespace gr {
+
+ static error_handler *s_default_handler = 0;
+ static error_handler *s_silent_handler = 0;
+
+ bool
+ error_handler::has_default_handler()
+ {
+ return s_default_handler != 0;
+ }
+
+ void
+ error_handler::set_default_handler(error_handler *errh)
+ {
+ s_default_handler = errh;
+ }
+
+ error_handler *
+ error_handler::default_handler()
+ {
+ assert(s_default_handler != 0);
+ return s_default_handler;
+ }
+
+ error_handler *
+ error_handler::silent_handler()
+ {
+ assert(s_silent_handler != 0);
+ return s_silent_handler;
+ }
+
+ // ----------------------------------------------------------------
+
+ error_handler::~error_handler()
+ {
+ // nop
+ }
+
+ void
+ error_handler::debug(const char *format, ...)
+ {
+ va_list val;
+ va_start(val, format);
+ verror(ERR_DEBUG, format, val);
+ va_end(val);
+ }
+
+ void
+ error_handler::message(const char *format, ...)
+ {
+ va_list val;
+ va_start(val, format);
+ verror(ERR_MESSAGE, format, val);
+ va_end(val);
+ }
+
+ void
+ error_handler::warning(const char *format, ...)
+ {
+ va_list val;
+ va_start(val, format);
+ verror(ERR_WARNING, format, val);
+ va_end(val);
+ }
+
+ void
+ error_handler::error(const char *format, ...)
+ {
+ va_list val;
+ va_start(val, format);
+ verror(ERR_ERROR, format, val);
+ va_end(val);
+ }
+
+ void
+ error_handler::fatal(const char *format, ...)
+ {
+ va_list val;
+ va_start(val, format);
+ verror(ERR_FATAL, format, val);
+ va_end(val);
+ }
+
+ void
+ error_handler::verror(seriousness s, const char *format, va_list val)
+ {
+ std::string text = make_text(s, format, val);
+ handle_text(s, text);
+ count_error(s);
+ }
+
+ void
+ error_handler::verror_text(seriousness s, const std::string &text)
+ {
+ // text is already made
+ handle_text(s, text);
+ count_error(s);
+ }
+
+ std::string
+ error_handler::make_text(seriousness s, const char *format, va_list val)
+ {
+ char text_buf[4096];
+ vsnprintf(text_buf, sizeof(text_buf), format, val);
+ text_buf[sizeof(text_buf)-1] = 0;
+ return text_buf;
+ }
+
+ // ----------------------------------------------------------------
+
+ void
+ base_error_handler::count_error(seriousness s)
+ {
+ if(s < ERR_WARNING)
+ /* do nothing */;
+ else if(s < ERR_ERROR)
+ d_nwarnings++;
+ else
+ d_nerrors++;
+ }
+
+ // ----------------------------------------------------------------
+
+ file_error_handler::file_error_handler(FILE *file)
+ : d_file(file), d_fd(-1)
+ {
+ }
+
+ file_error_handler::file_error_handler(int file_descriptor)
+ {
+ d_fd = dup(file_descriptor); // so we can fclose it
+ if(d_fd == -1){
+ perror("gr::file_error_handler:dup");
+ throw std::invalid_argument("gr::file_error_handler:dup");
+ }
+ d_file = fdopen(d_fd, "w");
+ if(d_file == 0){
+ perror("gr::file_error_handler:fdopen");
+ throw std::invalid_argument("gr::file_error_handler:fdopen");
+ }
+ }
+
+ file_error_handler::~file_error_handler()
+ {
+ if(d_fd != -1){
+ fclose(d_file);
+ }
+ }
+
+ void
+ file_error_handler::handle_text(seriousness s, const std::string &text)
+ {
+ if(text.length() <= 0)
+ return;
+
+ fwrite(text.data(), 1, text.length(), d_file);
+ if(text[text.length()-1] != '\n')
+ fwrite("\n", 1, 1, d_file);
+
+ if(d_fd != -1)
+ fflush(d_file); // keep synced with any other users of fd
+ }
+
+
+ // ----------------------------------------------------------------
+ // static error handlers
+ //
+
+ class silent_error_handler : public base_error_handler
+ {
+ public:
+ silent_error_handler() {}
+ void handle_text(seriousness s, const std::string &str);
+ };
+
+ void
+ silent_error_handler::handle_text(seriousness s, const std::string &str)
+ {
+ // nop
+ }
+
+ class force_init
+ {
+ public:
+ force_init()
+ {
+ s_default_handler = new file_error_handler(stdout);
+ s_silent_handler = new silent_error_handler();
+ }
+ };
+
+ static force_init kludge;
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/feval.cc b/gnuradio-runtime/lib/feval.cc
new file mode 100644
index 0000000000..93976c8ac7
--- /dev/null
+++ b/gnuradio-runtime/lib/feval.cc
@@ -0,0 +1,136 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnuradio/feval.h>
+
+namespace gr {
+
+ feval_dd::~feval_dd(){}
+
+ double
+ feval_dd::eval(double x)
+ {
+ return 0;
+ }
+
+ double
+ feval_dd::calleval(double x)
+ {
+ return eval(x);
+ }
+
+ // ----------------------------------------------------------------
+
+ feval_cc::~feval_cc(){}
+
+ gr_complex
+ feval_cc::eval(gr_complex x)
+ {
+ return 0;
+ }
+
+ gr_complex
+ feval_cc::calleval(gr_complex x)
+ {
+ return eval(x);
+ }
+
+ // ----------------------------------------------------------------
+
+ feval_ll::~feval_ll(){}
+
+ long
+ feval_ll::eval(long x)
+ {
+ return 0;
+ }
+
+ long
+ feval_ll::calleval(long x)
+ {
+ return eval(x);
+ }
+
+ // ----------------------------------------------------------------
+
+ feval::~feval(){}
+
+ void
+ feval::eval(void)
+ {
+ // nop
+ }
+
+ void
+ feval::calleval(void)
+ {
+ eval();
+ }
+
+ // ----------------------------------------------------------------
+
+ feval_p::~feval_p(){}
+
+ void
+ feval_p::eval(pmt::pmt_t x)
+ {
+ // nop
+ }
+
+ void
+ feval_p::calleval(pmt::pmt_t x)
+ {
+ eval(x);
+ }
+
+ /*
+ * Trivial examples showing C++ (transparently) calling Python
+ */
+ double
+ feval_dd_example(feval_dd *f, double x)
+ {
+ return f->calleval(x);
+ }
+
+ gr_complex
+ feval_cc_example(feval_cc *f, gr_complex x)
+ {
+ return f->calleval(x);
+ }
+
+ long
+ feval_ll_example(feval_ll *f, long x)
+ {
+ return f->calleval(x);
+ }
+
+ void
+ feval_example(feval *f)
+ {
+ f->calleval();
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/flat_flowgraph.cc b/gnuradio-runtime/lib/flat_flowgraph.cc
new file mode 100644
index 0000000000..8b188799a5
--- /dev/null
+++ b/gnuradio-runtime/lib/flat_flowgraph.cc
@@ -0,0 +1,436 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "flat_flowgraph.h"
+#include <gnuradio/block_detail.h>
+#include <gnuradio/buffer.h>
+#include <gnuradio/prefs.h>
+#include <volk/volk.h>
+#include <iostream>
+#include <map>
+#include <boost/format.hpp>
+
+namespace gr {
+
+#define FLAT_FLOWGRAPH_DEBUG 0
+
+// 32Kbyte buffer size between blocks
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+ static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+
+ flat_flowgraph_sptr
+ make_flat_flowgraph()
+ {
+ return flat_flowgraph_sptr(new flat_flowgraph());
+ }
+
+ flat_flowgraph::flat_flowgraph()
+ {
+ }
+
+ flat_flowgraph::~flat_flowgraph()
+ {
+ }
+
+ void
+ flat_flowgraph::setup_connections()
+ {
+ basic_block_vector_t blocks = calc_used_blocks();
+
+ // Assign block details to blocks
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ cast_to_block_sptr(*p)->set_detail(allocate_block_detail(*p));
+
+ // Connect inputs to outputs for each block
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ connect_block_inputs(*p);
+
+ block_sptr block = cast_to_block_sptr(*p);
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+
+ // 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()));
+ }
+ }
+
+ block_detail_sptr
+ flat_flowgraph::allocate_block_detail(basic_block_sptr block)
+ {
+ int ninputs = calc_used_ports(block, true).size();
+ int noutputs = calc_used_ports(block, false).size();
+ block_detail_sptr detail = make_block_detail(ninputs, noutputs);
+
+ block_sptr grblock = cast_to_block_sptr(block);
+ if(!grblock)
+ throw std::runtime_error("allocate_block_detail found non-gr::block");
+
+ if(FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "Creating block detail for " << block << std::endl;
+
+ 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;
+ detail->set_output(i, buffer);
+
+ // Update the block's max_output_buffer based on what was actually allocated.
+ grblock->set_max_output_buffer(i, buffer->bufsize());
+ }
+
+ return detail;
+ }
+
+ buffer_sptr
+ flat_flowgraph::allocate_buffer(basic_block_sptr block, int port)
+ {
+ block_sptr grblock = cast_to_block_sptr(block);
+ if(!grblock)
+ throw std::runtime_error("allocate_buffer found non-gr::block");
+ int item_size = block->output_signature()->sizeof_stream_item(port);
+
+ // *2 because we're now only filling them 1/2 way in order to
+ // increase the available parallelism when using the TPB scheduler.
+ // (We're double buffering, where we used to single buffer)
+ int nitems = s_fixed_buffer_size * 2 / item_size;
+
+ // Make sure there are at least twice the output_multiple no. of items
+ if(nitems < 2*grblock->output_multiple()) // Note: this means output_multiple()
+ nitems = 2*grblock->output_multiple(); // can't be changed by block dynamically
+
+ // If any downstream blocks are decimators and/or have a large output_multiple,
+ // ensure we have a buffer at least twice their decimation factor*output_multiple
+ basic_block_vector_t blocks = calc_downstream_blocks(block, port);
+
+ // limit buffer size if indicated
+ if(grblock->max_output_buffer(port) > 0) {
+ //std::cout << "constraining output items to " << block->max_output_buffer(port) << "\n";
+ nitems = std::min((long)nitems, (long)grblock->max_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if(nitems < 1)
+ throw std::runtime_error("problems allocating a buffer with the given max output buffer constraint!");
+ }
+ else if(grblock->min_output_buffer(port) > 0) {
+ nitems = std::max((long)nitems, (long)grblock->min_output_buffer(port));
+ nitems -= nitems%grblock->output_multiple();
+ if(nitems < 1)
+ throw std::runtime_error("problems allocating a buffer with the given min output buffer constraint!");
+ }
+
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ block_sptr dgrblock = cast_to_block_sptr(*p);
+ if(!dgrblock)
+ throw std::runtime_error("allocate_buffer found non-gr::block");
+
+ double decimation = (1.0/dgrblock->relative_rate());
+ int multiple = dgrblock->output_multiple();
+ int history = dgrblock->history();
+ nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history)));
+ }
+
+ // std::cout << "make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n";
+ return make_buffer(nitems, item_size, grblock);
+ }
+
+ void
+ flat_flowgraph::connect_block_inputs(basic_block_sptr block)
+ {
+ block_sptr grblock = cast_to_block_sptr(block);
+ if (!grblock)
+ throw std::runtime_error("connect_block_inputs found non-gr::block");
+
+ // Get its detail and edges that feed into it
+ block_detail_sptr detail = grblock->detail();
+ edge_vector_t in_edges = calc_upstream_edges(block);
+
+ // For each edge that feeds into it
+ for(edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+ // Set the buffer reader on the destination port to the output
+ // buffer on the source port
+ int dst_port = e->dst().port();
+ int src_port = e->src().port();
+ basic_block_sptr src_block = e->src().block();
+ block_sptr src_grblock = cast_to_block_sptr(src_block);
+ if(!src_grblock)
+ 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;
+
+ detail->set_input(dst_port, buffer_add_reader(src_buffer, grblock->history()-1, grblock));
+ }
+ }
+
+ void
+ flat_flowgraph::merge_connections(flat_flowgraph_sptr old_ffg)
+ {
+ // Allocate block details if needed. Only new blocks that aren't pruned out
+ // by flattening will need one; existing blocks still in the new flowgraph will
+ // already have one.
+ 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;
+ }
+
+ // 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;
+ }
+ }
+
+ // 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));
+ }
+ }
+ }
+ else {
+ // Block is new, it just needs buffer readers at this point
+ if(FLAT_FLOWGRAPH_DEBUG)
+ std::cout << "new block" << std::endl;
+ connect_block_inputs(block);
+
+ // Make sure all buffers are aligned
+ setup_buffer_alignment(block);
+ }
+
+ // Now deal with the fact that the block details might have
+ // changed numbers of inputs and outputs vs. in the old
+ // flowgraph.
+ }
+ }
+
+ void
+ flat_flowgraph::setup_buffer_alignment(block_sptr block)
+ {
+ const int alignment = volk_get_alignment();
+ for(int i = 0; i < block->detail()->ninputs(); i++) {
+ void *r = (void*)block->detail()->input(i)->read_pointer();
+ unsigned long int ri = (unsigned long int)r % alignment;
+ //std::cerr << "reader: " << r << " alignment: " << ri << std::endl;
+ if(ri != 0) {
+ size_t itemsize = block->detail()->input(i)->get_sizeof_item();
+ block->detail()->input(i)->update_read_pointer(alignment-ri/itemsize);
+ }
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+
+ for(int i = 0; i < block->detail()->noutputs(); i++) {
+ void *w = (void*)block->detail()->output(i)->write_pointer();
+ unsigned long int wi = (unsigned long int)w % alignment;
+ //std::cerr << "writer: " << w << " alignment: " << wi << std::endl;
+ if(wi != 0) {
+ size_t itemsize = block->detail()->output(i)->get_sizeof_item();
+ block->detail()->output(i)->update_write_pointer(alignment-wi/itemsize);
+ }
+ block->set_unaligned(0);
+ block->set_is_unaligned(false);
+ }
+ }
+
+ std::string
+ flat_flowgraph::edge_list()
+ {
+ std::stringstream s;
+ for(edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++)
+ s << (*e) << std::endl;
+ return s.str();
+ }
+
+ void flat_flowgraph::dump()
+ {
+ for(edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++)
+ std::cout << " edge: " << (*e) << std::endl;
+
+ for(basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ std::cout << " block: " << (*p) << std::endl;
+ block_detail_sptr detail = cast_to_block_sptr(*p)->detail();
+ std::cout << " detail @" << detail << ":" << std::endl;
+
+ int ni = detail->ninputs();
+ int no = detail->noutputs();
+ for(int i = 0; i < no; i++) {
+ buffer_sptr buffer = detail->output(i);
+ std::cout << " output " << i << ": " << buffer << std::endl;
+ }
+
+ for(int i = 0; i < ni; i++) {
+ buffer_reader_sptr reader = detail->input(i);
+ std::cout << " reader " << i << ": " << reader
+ << " reading from buffer=" << reader->buffer() << std::endl;
+ }
+ }
+ }
+
+ block_vector_t
+ flat_flowgraph::make_block_vector(basic_block_vector_t &blocks)
+ {
+ block_vector_t result;
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ result.push_back(cast_to_block_sptr(*p));
+ }
+
+ return result;
+ }
+
+ void
+ flat_flowgraph::clear_endpoint(const msg_endpoint &e, bool is_src)
+ {
+ for(size_t i=0; i<d_msg_edges.size(); i++) {
+ if(is_src) {
+ if(d_msg_edges[i].src() == e) {
+ d_msg_edges.erase(d_msg_edges.begin() + i);
+ i--;
+ }
+ }
+ else {
+ if(d_msg_edges[i].dst() == e) {
+ 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.block()% d_msg_edges[i].dst().block();
+ 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.block()% d_msg_edges[i].dst().block();
+ d_msg_edges.push_back( msg_edge(d_msg_edges[i].src(), r ) );
+ n_replr++;
+ }
+ }
+ }
+ }
+
+ void
+ flat_flowgraph::enable_pc_rpc()
+ {
+#ifdef GR_PERFORMANCE_COUNTERS
+ if(prefs::singleton()->get_bool("PerfCounters", "on", false)) {
+ basic_block_viter_t p;
+ for(p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ block_sptr block = cast_to_block_sptr(*p);
+ if(!block->is_pc_rpc_set())
+ block->setup_pc_rpc();
+ }
+ }
+#endif /* GR_PERFORMANCE_COUNTERS */
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/flat_flowgraph.h b/gnuradio-runtime/lib/flat_flowgraph.h
new file mode 100644
index 0000000000..fe43969b6f
--- /dev/null
+++ b/gnuradio-runtime/lib/flat_flowgraph.h
@@ -0,0 +1,93 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,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.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_FLAT_FLOWGRAPH_H
+#define INCLUDED_GR_RUNTIME_FLAT_FLOWGRAPH_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/flowgraph.h>
+#include <gnuradio/block.h>
+
+namespace gr {
+
+ // Create a shared pointer to a heap allocated gr::flat_flowgraph
+ // (types defined in gr_runtime_types.h)
+ GR_RUNTIME_API flat_flowgraph_sptr make_flat_flowgraph();
+
+ /*!
+ *\brief Class specializing gr_flat_flowgraph that has all nodes
+ * as blocks, with no hierarchy
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API flat_flowgraph : public flowgraph
+ {
+ public:
+ friend GR_RUNTIME_API flat_flowgraph_sptr make_flat_flowgraph();
+
+ // Destruct an arbitrary gr::flat_flowgraph
+ ~flat_flowgraph();
+
+ // Wire list of gr::block together in new flat_flowgraph
+ void setup_connections();
+
+ // Merge applicable connections from existing flat flowgraph
+ void merge_connections(flat_flowgraph_sptr sfg);
+
+ // Return a string list of edges
+ std::string edge_list();
+
+ void dump();
+
+ /*!
+ * Make a vector of gr::block from a vector of gr::basic_block
+ */
+ static block_vector_t make_block_vector(basic_block_vector_t &blocks);
+
+ void replace_endpoint(const msg_endpoint &e, const msg_endpoint &r, bool is_src);
+ void clear_endpoint(const msg_endpoint &e, bool is_src);
+
+ /*!
+ * Enables export of perf. counters to ControlPort on all blocks in
+ * the flowgraph.
+ */
+ void enable_pc_rpc();
+
+ private:
+ flat_flowgraph();
+
+ block_detail_sptr allocate_block_detail(basic_block_sptr block);
+ buffer_sptr allocate_buffer(basic_block_sptr block, int port);
+ void connect_block_inputs(basic_block_sptr block);
+
+ /* When reusing a flowgraph's blocks, this call makes sure all of
+ * the buffer's are aligned at the machine's alignment boundary
+ * and tells the blocks that they are aligned.
+ *
+ * Called from both setup_connections and merge_connections for
+ * start and restarts.
+ */
+ void setup_buffer_alignment(block_sptr block);
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_RUNTIME_FLAT_FLOWGRAPH_H */
diff --git a/gnuradio-runtime/lib/flowgraph.cc b/gnuradio-runtime/lib/flowgraph.cc
new file mode 100644
index 0000000000..0b0285088b
--- /dev/null
+++ b/gnuradio-runtime/lib/flowgraph.cc
@@ -0,0 +1,519 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/flowgraph.h>
+#include <stdexcept>
+#include <sstream>
+#include <iterator>
+
+namespace gr {
+
+#define FLOWGRAPH_DEBUG 0
+
+ edge::~edge()
+ {
+ }
+
+ flowgraph_sptr make_flowgraph()
+ {
+ return flowgraph_sptr(new flowgraph());
+ }
+
+ flowgraph::flowgraph()
+ {
+ }
+
+ flowgraph::~flowgraph()
+ {
+ }
+
+ template<class T>
+ static
+ std::vector<T>
+ unique_vector(std::vector<T> v)
+ {
+ std::vector<T> result;
+ std::insert_iterator<std::vector<T> > inserter(result, result.begin());
+
+ sort(v.begin(), v.end());
+ unique_copy(v.begin(), v.end(), inserter);
+ return result;
+ }
+
+ void
+ flowgraph::connect(const endpoint &src, const endpoint &dst)
+ {
+ check_valid_port(src.block()->output_signature(), src.port());
+ check_valid_port(dst.block()->input_signature(), dst.port());
+ check_dst_not_used(dst);
+ check_type_match(src, dst);
+
+ // All ist klar, Herr Kommisar
+ d_edges.push_back(edge(src,dst));
+ }
+
+ void
+ flowgraph::disconnect(const endpoint &src, const endpoint &dst)
+ {
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if(src == p->src() && dst == p->dst()) {
+ d_edges.erase(p);
+ return;
+ }
+ }
+
+ std::stringstream msg;
+ msg << "cannot disconnect edge " << edge(src, dst) << ", not found";
+ throw std::invalid_argument(msg.str());
+ }
+
+ void
+ flowgraph::validate()
+ {
+ d_blocks = calc_used_blocks();
+
+ for(basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ std::vector<int> used_ports;
+ int ninputs, noutputs;
+
+ if(FLOWGRAPH_DEBUG)
+ std::cout << "Validating block: " << (*p) << std::endl;
+
+ used_ports = calc_used_ports(*p, true); // inputs
+ ninputs = used_ports.size();
+ check_contiguity(*p, used_ports, true); // inputs
+
+ used_ports = calc_used_ports(*p, false); // outputs
+ noutputs = used_ports.size();
+ check_contiguity(*p, used_ports, false); // outputs
+
+ if(!((*p)->check_topology(ninputs, noutputs))) {
+ std::stringstream msg;
+ msg << "check topology failed on " << (*p)
+ << " using ninputs=" << ninputs
+ << ", noutputs=" << noutputs;
+ throw std::runtime_error(msg.str());
+ }
+ }
+ }
+
+ void
+ flowgraph::clear()
+ {
+ // Boost shared pointers will deallocate as needed
+ d_blocks.clear();
+ d_edges.clear();
+ }
+
+ void
+ flowgraph::check_valid_port(gr::io_signature::sptr sig, int port)
+ {
+ std::stringstream msg;
+
+ if(port < 0) {
+ msg << "negative port number " << port << " is invalid";
+ throw std::invalid_argument(msg.str());
+ }
+
+ int max = sig->max_streams();
+ if(max != io_signature::IO_INFINITE && port >= max) {
+ msg << "port number " << port << " exceeds max of ";
+ if(max == 0)
+ msg << "(none)";
+ else
+ msg << max-1;
+ throw std::invalid_argument(msg.str());
+ }
+ }
+
+ void
+ flowgraph::check_valid_port(const msg_endpoint &e)
+ {
+ if(FLOWGRAPH_DEBUG)
+ std::cout << "check_valid_port( " << e.block() << ", " << e.port() << ")\n";
+
+ if(!e.block()->has_msg_port(e.port()))
+ throw std::invalid_argument("invalid msg port in connect() or disconnect()");
+ }
+
+ void
+ flowgraph::check_dst_not_used(const endpoint &dst)
+ {
+ // A destination is in use if it is already on the edge list
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if(p->dst() == dst) {
+ std::stringstream msg;
+ msg << "destination already in use by edge " << (*p);
+ throw std::invalid_argument(msg.str());
+ }
+ }
+
+ void
+ flowgraph::check_type_match(const endpoint &src, const endpoint &dst)
+ {
+ int src_size = src.block()->output_signature()->sizeof_stream_item(src.port());
+ int dst_size = dst.block()->input_signature()->sizeof_stream_item(dst.port());
+
+ if(src_size != dst_size) {
+ std::stringstream msg;
+ msg << "itemsize mismatch: " << src << " using " << src_size
+ << ", " << dst << " using " << dst_size;
+ throw std::invalid_argument(msg.str());
+ }
+ }
+
+ basic_block_vector_t
+ flowgraph::calc_used_blocks()
+ {
+ basic_block_vector_t tmp;
+
+ // make sure free standing message blocks are included
+ for(msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+ //for now only blocks receiving messages get a thread context - uncomment to allow senders to also obtain one
+ // tmp.push_back(p->src().block());
+ tmp.push_back(p->dst().block());
+ }
+
+ // Collect all blocks in the edge list
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ tmp.push_back(p->src().block());
+ tmp.push_back(p->dst().block());
+ }
+
+ return unique_vector<basic_block_sptr>(tmp);
+ }
+
+ std::vector<int>
+ flowgraph::calc_used_ports(basic_block_sptr block, bool check_inputs)
+ {
+ std::vector<int> tmp;
+
+ // Collect all seen ports
+ edge_vector_t edges = calc_connections(block, check_inputs);
+ for(edge_viter_t p = edges.begin(); p != edges.end(); p++) {
+ if(check_inputs == true)
+ tmp.push_back(p->dst().port());
+ else
+ tmp.push_back(p->src().port());
+ }
+
+ return unique_vector<int>(tmp);
+ }
+
+ edge_vector_t
+ flowgraph::calc_connections(basic_block_sptr block, bool check_inputs)
+ {
+ edge_vector_t result;
+
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if(check_inputs) {
+ if(p->dst().block() == block)
+ result.push_back(*p);
+ }
+ else {
+ if(p->src().block() == block)
+ result.push_back(*p);
+ }
+ }
+
+ return result; // assumes no duplicates
+ }
+
+ void
+ flowgraph::check_contiguity(basic_block_sptr block,
+ const std::vector<int> &used_ports,
+ bool check_inputs)
+ {
+ std::stringstream msg;
+
+ gr::io_signature::sptr sig =
+ check_inputs ? block->input_signature() : block->output_signature();
+
+ int nports = used_ports.size();
+ int min_ports = sig->min_streams();
+ int max_ports = sig->max_streams();
+
+ if(nports == 0 && min_ports == 0)
+ return;
+
+ if(nports < min_ports) {
+ msg << block << ": insufficient connected "
+ << (check_inputs ? "input ports " : "output ports ")
+ << "(" << min_ports << " needed, " << nports << " connected)";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(nports > max_ports && max_ports != io_signature::IO_INFINITE) {
+ msg << block << ": too many connected "
+ << (check_inputs ? "input ports " : "output ports ")
+ << "(" << max_ports << " allowed, " << nports << " connected)";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(used_ports[nports-1]+1 != nports) {
+ for(int i = 0; i < nports; i++) {
+ if(used_ports[i] != i) {
+ msg << block << ": missing connection "
+ << (check_inputs ? "to input port " : "from output port ")
+ << i;
+ throw std::runtime_error(msg.str());
+ }
+ }
+ }
+ }
+
+ basic_block_vector_t
+ flowgraph::calc_downstream_blocks(basic_block_sptr block, int port)
+ {
+ basic_block_vector_t tmp;
+
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if(p->src() == endpoint(block, port))
+ tmp.push_back(p->dst().block());
+
+ return unique_vector<basic_block_sptr>(tmp);
+ }
+
+ basic_block_vector_t
+ flowgraph::calc_downstream_blocks(basic_block_sptr block)
+ {
+ basic_block_vector_t tmp;
+
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if(p->src().block() == block)
+ tmp.push_back(p->dst().block());
+
+ return unique_vector<basic_block_sptr>(tmp);
+ }
+
+ edge_vector_t
+ flowgraph::calc_upstream_edges(basic_block_sptr block)
+ {
+ edge_vector_t result;
+
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if(p->dst().block() == block)
+ result.push_back(*p);
+
+ return result; // Assume no duplicates
+ }
+
+ bool
+ flowgraph::has_block_p(basic_block_sptr block)
+ {
+ basic_block_viter_t result;
+ result = std::find(d_blocks.begin(), d_blocks.end(), block);
+ return (result != d_blocks.end());
+ }
+
+ edge
+ flowgraph::calc_upstream_edge(basic_block_sptr block, int port)
+ {
+ edge result;
+
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if(p->dst() == endpoint(block, port)) {
+ result = (*p);
+ break;
+ }
+ }
+
+ return result;
+ }
+
+ std::vector<basic_block_vector_t>
+ flowgraph::partition()
+ {
+ std::vector<basic_block_vector_t> result;
+ basic_block_vector_t blocks = calc_used_blocks();
+ basic_block_vector_t graph;
+
+ while(blocks.size() > 0) {
+ graph = calc_reachable_blocks(blocks[0], blocks);
+ assert(graph.size());
+ result.push_back(topological_sort(graph));
+
+ for(basic_block_viter_t p = graph.begin(); p != graph.end(); p++)
+ blocks.erase(find(blocks.begin(), blocks.end(), *p));
+ }
+
+ return result;
+ }
+
+ basic_block_vector_t
+ flowgraph::calc_reachable_blocks(basic_block_sptr block, basic_block_vector_t &blocks)
+ {
+ basic_block_vector_t result;
+
+ // Mark all blocks as unvisited
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ (*p)->set_color(basic_block::WHITE);
+
+ // Recursively mark all reachable blocks
+ reachable_dfs_visit(block, blocks);
+
+ // Collect all the blocks that have been visited
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ if((*p)->color() == basic_block::BLACK)
+ result.push_back(*p);
+
+ return result;
+ }
+
+ // Recursively mark all reachable blocks from given block and block list
+ void
+ flowgraph::reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t &blocks)
+ {
+ // Mark the current one as visited
+ block->set_color(basic_block::BLACK);
+
+ // Recurse into adjacent vertices
+ basic_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+ for(basic_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
+ if((*p)->color() == basic_block::WHITE)
+ reachable_dfs_visit(*p, blocks);
+ }
+
+ // Return a list of block adjacent to a given block along any edge
+ basic_block_vector_t
+ flowgraph::calc_adjacent_blocks(basic_block_sptr block, basic_block_vector_t &blocks)
+ {
+ basic_block_vector_t tmp;
+
+ // Find any blocks that are inputs or outputs
+ for(edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if(p->src().block() == block)
+ tmp.push_back(p->dst().block());
+ if(p->dst().block() == block)
+ tmp.push_back(p->src().block());
+ }
+
+ return unique_vector<basic_block_sptr>(tmp);
+ }
+
+ basic_block_vector_t
+ flowgraph::topological_sort(basic_block_vector_t &blocks)
+ {
+ basic_block_vector_t tmp;
+ basic_block_vector_t result;
+ tmp = sort_sources_first(blocks);
+
+ // Start 'em all white
+ for(basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++)
+ (*p)->set_color(basic_block::WHITE);
+
+ for(basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
+ if((*p)->color() == basic_block::WHITE)
+ topological_dfs_visit(*p, result);
+ }
+
+ reverse(result.begin(), result.end());
+ return result;
+ }
+
+ basic_block_vector_t
+ flowgraph::sort_sources_first(basic_block_vector_t &blocks)
+ {
+ basic_block_vector_t sources, nonsources, result;
+
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ if(source_p(*p))
+ sources.push_back(*p);
+ else
+ nonsources.push_back(*p);
+ }
+
+ for(basic_block_viter_t p = sources.begin(); p != sources.end(); p++)
+ result.push_back(*p);
+
+ for(basic_block_viter_t p = nonsources.begin(); p != nonsources.end(); p++)
+ result.push_back(*p);
+
+ return result;
+ }
+
+ bool
+ flowgraph::source_p(basic_block_sptr block)
+ {
+ return (calc_upstream_edges(block).size() == 0);
+ }
+
+ void
+ flowgraph::topological_dfs_visit(basic_block_sptr block, basic_block_vector_t &output)
+ {
+ block->set_color(basic_block::GREY);
+ basic_block_vector_t blocks(calc_downstream_blocks(block));
+
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ switch((*p)->color()) {
+ case basic_block::WHITE:
+ topological_dfs_visit(*p, output);
+ break;
+
+ case basic_block::GREY:
+ throw std::runtime_error("flow graph has loops!");
+
+ case basic_block::BLACK:
+ continue;
+
+ default:
+ throw std::runtime_error("invalid color on block!");
+ }
+ }
+
+ block->set_color(basic_block::BLACK);
+ output.push_back(block);
+ }
+
+ void
+ flowgraph::connect(const msg_endpoint &src, const msg_endpoint &dst)
+ {
+ check_valid_port(src);
+ check_valid_port(dst);
+ for(msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+ if(p->src() == src && p->dst() == dst){
+ throw std::runtime_error("connect called on already connected edge!");
+ }
+ }
+ d_msg_edges.push_back(msg_edge(src,dst));
+ }
+
+ void
+ flowgraph::disconnect(const msg_endpoint &src, const msg_endpoint &dst)
+ {
+ check_valid_port(src);
+ check_valid_port(dst);
+ for(msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
+ if(p->src() == src && p->dst() == dst){
+ d_msg_edges.erase(p);
+ return;
+ }
+ }
+ throw std::runtime_error("disconnect called on non-connected edge!");
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_basic_block.cc b/gnuradio-runtime/lib/gr_basic_block.cc
deleted file mode 100644
index 83f6c07c87..0000000000
--- a/gnuradio-runtime/lib/gr_basic_block.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2012 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 <gr_basic_block.h>
-#include <gr_block_registry.h>
-#include <stdexcept>
-#include <sstream>
-#include <iostream>
-
-static long s_next_id = 0;
-static long s_ncurrently_allocated = 0;
-
-long
-gr_basic_block_ncurrently_allocated()
-{
- return s_ncurrently_allocated;
-}
-
-gr_basic_block::gr_basic_block(const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature)
- : d_name(name),
- d_input_signature(input_signature),
- d_output_signature(output_signature),
- d_unique_id(s_next_id++),
- d_symbolic_id(global_block_registry.block_register(this)),
- d_symbol_name(global_block_registry.register_symbolic_name(this)),
- d_color(WHITE),
- d_rpc_set(false),
- message_subscribers(pmt::make_dict())
-{
- s_ncurrently_allocated++;
-}
-
-gr_basic_block::~gr_basic_block()
-{
- s_ncurrently_allocated--;
- global_block_registry.block_unregister(this);
-}
-
-gr_basic_block_sptr
-gr_basic_block::to_basic_block()
-{
- return shared_from_this();
-}
-
-void
-gr_basic_block::set_block_alias(std::string name)
-{
- global_block_registry.register_symbolic_name(this, name);
-}
-
-// ** Message passing interface **
-
-// - register a new input message port
-void
-gr_basic_block::message_port_register_in(pmt::pmt_t port_id)
-{
- if(!pmt::is_symbol(port_id)) {
- throw std::runtime_error("message_port_register_in: bad port id");
- }
- msg_queue[port_id] = msg_queue_t();
- msg_queue_ready[port_id] = boost::shared_ptr<boost::condition_variable>(new boost::condition_variable());
-}
-
-pmt::pmt_t
-gr_basic_block::message_ports_in()
-{
- pmt::pmt_t port_names = pmt::make_vector(msg_queue.size(), pmt::PMT_NIL);
- msg_queue_map_itr itr = msg_queue.begin();
- for(size_t i = 0; i < msg_queue.size(); i++) {
- pmt::vector_set(port_names, i, (*itr).first);
- itr++;
- }
- return port_names;
-}
-
-// - register a new output message port
-void
-gr_basic_block::message_port_register_out(pmt::pmt_t port_id)
-{
- if(!pmt::is_symbol(port_id)) {
- throw std::runtime_error("message_port_register_out: bad port id");
- }
- if(pmt::dict_has_key(message_subscribers, port_id)) {
- throw std::runtime_error("message_port_register_out: port already in use");
- }
- message_subscribers = pmt::dict_add(message_subscribers, port_id, pmt::PMT_NIL);
-}
-
-pmt::pmt_t
-gr_basic_block::message_ports_out()
-{
- size_t len = pmt::length(message_subscribers);
- pmt::pmt_t port_names = pmt::make_vector(len, pmt::PMT_NIL);
- pmt::pmt_t keys = pmt::dict_keys(message_subscribers);
- for(size_t i = 0; i < len; i++) {
- pmt::vector_set(port_names, i, pmt::nth(i, keys));
- }
- return port_names;
-}
-
-// - publish a message on a message port
-void gr_basic_block::message_port_pub(pmt::pmt_t port_id, pmt::pmt_t msg)
-{
- if(!pmt::dict_has_key(message_subscribers, port_id)) {
- throw std::runtime_error("port does not exist");
- }
-
- pmt::pmt_t currlist = pmt::dict_ref(message_subscribers, port_id, pmt::PMT_NIL);
- // iterate through subscribers on port
- while(pmt::is_pair(currlist)) {
- pmt::pmt_t target = pmt::car(currlist);
-
- pmt::pmt_t block = pmt::car(target);
- pmt::pmt_t port = pmt::cdr(target);
-
- currlist = pmt::cdr(currlist);
- gr_basic_block_sptr blk = global_block_registry.block_lookup(block);
- //blk->post(msg);
- blk->post(port, msg);
- }
-}
-
-// - subscribe to a message port
-void
-gr_basic_block::message_port_sub(pmt::pmt_t port_id, pmt::pmt_t target){
- if(!pmt::dict_has_key(message_subscribers, port_id)){
- std::stringstream ss;
- ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: " << pmt::write_string(target) << std::endl;
- throw std::runtime_error(ss.str());
- }
- pmt::pmt_t currlist = pmt::dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
-
- // ignore re-adds of the same target
- if(!pmt::list_has(currlist, target))
- message_subscribers = pmt::dict_add(message_subscribers,port_id,pmt::list_add(currlist,target));
-}
-
-void
-gr_basic_block::message_port_unsub(pmt::pmt_t port_id, pmt::pmt_t target){
- if(!pmt::dict_has_key(message_subscribers, port_id)){
- std::stringstream ss;
- ss << "Port does not exist: \"" << pmt::write_string(port_id) << "\" on block: " << pmt::write_string(target) << std::endl;
- throw std::runtime_error(ss.str());
- }
-
- // ignore unsubs of unknown targets
- pmt::pmt_t currlist = pmt::dict_ref(message_subscribers,port_id,pmt::PMT_NIL);
- message_subscribers = pmt::dict_add(message_subscribers,port_id,pmt::list_rm(currlist,target));
-}
-
-void
-gr_basic_block::_post(pmt::pmt_t which_port, pmt::pmt_t msg)
-{
- insert_tail(which_port, msg);
-}
-
-void
-gr_basic_block::insert_tail(pmt::pmt_t which_port, pmt::pmt_t msg)
-{
- gr::thread::scoped_lock guard(mutex);
-
- if( (msg_queue.find(which_port) == msg_queue.end()) || (msg_queue_ready.find(which_port) == msg_queue_ready.end())){
- std::cout << "target port = " << pmt::symbol_to_string(which_port) << std::endl;
- throw std::runtime_error("attempted to insert_tail on invalid queue!");
- }
-
- msg_queue[which_port].push_back(msg);
- msg_queue_ready[which_port]->notify_one();
-
- // wake up thread if BLKD_IN or BLKD_OUT
- global_block_registry.notify_blk(alias());
-}
-
-pmt::pmt_t
-gr_basic_block::delete_head_nowait(pmt::pmt_t which_port)
-{
- gr::thread::scoped_lock guard(mutex);
-
- if (empty_p(which_port)){
- return pmt::pmt_t();
- }
-
- pmt::pmt_t m(msg_queue[which_port].front());
- msg_queue[which_port].pop_front();
-
- return m;
-}
-
-pmt::pmt_t
-gr_basic_block::delete_head_blocking(pmt::pmt_t which_port)
-{
- gr::thread::scoped_lock guard(mutex);
-
- 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;
-}
diff --git a/gnuradio-runtime/lib/gr_block.cc b/gnuradio-runtime/lib/gr_block.cc
deleted file mode 100644
index 2830a999ea..0000000000
--- a/gnuradio-runtime/lib/gr_block.cc
+++ /dev/null
@@ -1,687 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2009,2010,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_block.h>
-#include <gr_block_detail.h>
-#include <stdexcept>
-#include <iostream>
-#include <gr_block_registry.h>
-#include <gr_prefs.h>
-
-gr_block::gr_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature)
- : gr_basic_block(name, input_signature, output_signature),
- d_output_multiple (1),
- d_output_multiple_set(false),
- d_unaligned(0),
- d_is_unaligned(false),
- d_relative_rate (1.0),
- d_history(1),
- d_fixed_rate(false),
- d_max_noutput_items_set(false),
- d_max_noutput_items(0),
- d_min_noutput_items(0),
- d_tag_propagation_policy(TPP_ALL_TO_ALL),
- d_pc_rpc_set(false),
- d_max_output_buffer(std::max(output_signature->max_streams(),1), -1),
- d_min_output_buffer(std::max(output_signature->max_streams(),1), -1)
-{
- global_block_registry.register_primitive(alias(), this);
-
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
- gr_prefs *p = gr_prefs::singleton();
- std::string config_file = p->get_string("LOG", "log_config", "");
- std::string log_level = p->get_string("LOG", "log_level", "off");
- std::string log_file = p->get_string("LOG", "log_file", "");
- std::string debug_level = p->get_string("LOG", "debug_level", "off");
- std::string debug_file = p->get_string("LOG", "debug_file", "");
-
- GR_CONFIG_LOGGER(config_file);
-
- GR_LOG_GETLOGGER(LOG, "gr_log." + alias());
- GR_LOG_SET_LEVEL(LOG, log_level);
- if(log_file.size() > 0) {
- if(log_file == "stdout") {
- GR_LOG_ADD_CONSOLE_APPENDER(LOG, "cout","gr::log :%p: %c{1} - %m%n");
- }
- else if(log_file == "stderr") {
- GR_LOG_ADD_CONSOLE_APPENDER(LOG, "cerr","gr::log :%p: %c{1} - %m%n");
- }
- else {
- GR_LOG_ADD_FILE_APPENDER(LOG, log_file , true,"%r :%p: %c{1} - %m%n");
- }
- }
- d_logger = LOG;
-
- GR_LOG_GETLOGGER(DLOG, "gr_log_debug." + alias());
- GR_LOG_SET_LEVEL(DLOG, debug_level);
- if(debug_file.size() > 0) {
- if(debug_file == "stdout") {
- GR_LOG_ADD_CONSOLE_APPENDER(DLOG, "cout","gr::debug :%p: %c{1} - %m%n");
- }
- else if(debug_file == "stderr") {
- GR_LOG_ADD_CONSOLE_APPENDER(DLOG, "cerr", "gr::debug :%p: %c{1} - %m%n");
- }
- else {
- GR_LOG_ADD_FILE_APPENDER(DLOG, debug_file, true, "%r :%p: %c{1} - %m%n");
- }
- }
- d_debug_logger = DLOG;
-#endif /* HAVE_LOG4CPP */
-#else /* ENABLE_GR_LOG */
- d_logger = NULL;
- d_debug_logger = NULL;
-#endif /* ENABLE_GR_LOG */
-}
-
-gr_block::~gr_block ()
-{
- global_block_registry.unregister_primitive(alias());
-}
-
-// stub implementation: 1:1
-
-void
-gr_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = noutput_items + history() - 1;
-}
-
-// default implementation
-
-bool
-gr_block::start()
-{
- return true;
-}
-
-bool
-gr_block::stop()
-{
- return true;
-}
-
-void
-gr_block::set_output_multiple (int multiple)
-{
- if (multiple < 1)
- throw std::invalid_argument ("gr_block::set_output_multiple");
-
- d_output_multiple_set = true;
- d_output_multiple = multiple;
-}
-
-void
-gr_block::set_alignment (int multiple)
-{
- if (multiple < 1)
- throw std::invalid_argument ("gr_block::set_alignment_multiple");
-
- d_output_multiple = multiple;
-}
-
-void
-gr_block::set_unaligned (int na)
-{
- // unaligned value must be less than 0 and it doesn't make sense
- // that it's larger than the alignment value.
- if ((na < 0) || (na > d_output_multiple))
- throw std::invalid_argument ("gr_block::set_unaligned");
-
- d_unaligned = na;
-}
-
-void
-gr_block::set_is_unaligned (bool u)
-{
- d_is_unaligned = u;
-}
-
-void
-gr_block::set_relative_rate (double relative_rate)
-{
- if (relative_rate < 0.0)
- throw std::invalid_argument ("gr_block::set_relative_rate");
-
- d_relative_rate = relative_rate;
-}
-
-
-void
-gr_block::consume (int which_input, int how_many_items)
-{
- d_detail->consume (which_input, how_many_items);
-}
-
-void
-gr_block::consume_each (int how_many_items)
-{
- d_detail->consume_each (how_many_items);
-}
-
-void
-gr_block::produce (int which_output, int how_many_items)
-{
- d_detail->produce (which_output, how_many_items);
-}
-
-int
-gr_block::fixed_rate_ninput_to_noutput(int ninput)
-{
- throw std::runtime_error("Unimplemented");
-}
-
-int
-gr_block::fixed_rate_noutput_to_ninput(int noutput)
-{
- throw std::runtime_error("Unimplemented");
-}
-
-uint64_t
-gr_block::nitems_read(unsigned int which_input)
-{
- if(d_detail) {
- return d_detail->nitems_read(which_input);
- }
- else {
- //throw std::runtime_error("No block_detail associated with block yet");
- return 0;
- }
-}
-
-uint64_t
-gr_block::nitems_written(unsigned int which_output)
-{
- if(d_detail) {
- return d_detail->nitems_written(which_output);
- }
- else {
- //throw std::runtime_error("No block_detail associated with block yet");
- return 0;
- }
-}
-
-void
-gr_block::add_item_tag(unsigned int which_output,
- const gr_tag_t &tag)
-{
- d_detail->add_item_tag(which_output, tag);
-}
-
-void
-gr_block::remove_item_tag(unsigned int which_input,
- const gr_tag_t &tag)
-{
- d_detail->remove_item_tag(which_input, tag);
-}
-
-void
-gr_block::get_tags_in_range(std::vector<gr_tag_t> &v,
- unsigned int which_output,
- uint64_t start, uint64_t end)
-{
- d_detail->get_tags_in_range(v, which_output, start, end);
-}
-
-void
-gr_block::get_tags_in_range(std::vector<gr_tag_t> &v,
- unsigned int which_output,
- uint64_t start, uint64_t end,
- const pmt::pmt_t &key)
-{
- d_detail->get_tags_in_range(v, which_output, start, end, key);
-}
-
-gr_block::tag_propagation_policy_t
-gr_block::tag_propagation_policy()
-{
- return d_tag_propagation_policy;
-}
-
-void
-gr_block::set_tag_propagation_policy(tag_propagation_policy_t p)
-{
- d_tag_propagation_policy = p;
-}
-
-
-int
-gr_block::max_noutput_items()
-{
- return d_max_noutput_items;
-}
-
-void
-gr_block::set_max_noutput_items(int m)
-{
- if(m <= 0)
- throw std::runtime_error("gr_block::set_max_noutput_items: value for max_noutput_items must be greater than 0.\n");
-
- d_max_noutput_items = m;
- d_max_noutput_items_set = true;
-}
-
-void
-gr_block::unset_max_noutput_items()
-{
- d_max_noutput_items_set = false;
-}
-
-bool
-gr_block::is_set_max_noutput_items()
-{
- return d_max_noutput_items_set;
-}
-
-void
-gr_block::set_processor_affinity(const std::vector<int> &mask)
-{
- d_affinity = mask;
- if(d_detail) {
- d_detail->set_processor_affinity(d_affinity);
- }
-}
-
-void
-gr_block::unset_processor_affinity()
-{
- d_affinity.clear();
- if(d_detail) {
- d_detail->unset_processor_affinity();
- }
-}
-
-float
-gr_block::pc_noutput_items()
-{
- if(d_detail) {
- return d_detail->pc_noutput_items();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_noutput_items_avg()
-{
- if(d_detail) {
- return d_detail->pc_noutput_items_avg();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_noutput_items_var()
-{
- if(d_detail) {
- return d_detail->pc_noutput_items_var();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_nproduced()
-{
- if(d_detail) {
- return d_detail->pc_nproduced();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_nproduced_avg()
-{
- if(d_detail) {
- return d_detail->pc_nproduced_avg();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_nproduced_var()
-{
- if(d_detail) {
- return d_detail->pc_nproduced_var();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_input_buffers_full(int which)
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_input_buffers_full_avg(int which)
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full_avg(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_input_buffers_full_var(int which)
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full_var(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-std::vector<float>
-gr_block::pc_input_buffers_full()
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-std::vector<float>
-gr_block::pc_input_buffers_full_avg()
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full_avg();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-std::vector<float>
-gr_block::pc_input_buffers_full_var()
-{
- if(d_detail) {
- return d_detail->pc_input_buffers_full_var();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-float
-gr_block::pc_output_buffers_full(int which)
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_output_buffers_full_avg(int which)
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full_avg(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_output_buffers_full_var(int which)
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full_var(static_cast<size_t>(which));
- }
- else {
- return 0;
- }
-}
-
-std::vector<float>
-gr_block::pc_output_buffers_full()
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-std::vector<float>
-gr_block::pc_output_buffers_full_avg()
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full_avg();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-std::vector<float>
-gr_block::pc_output_buffers_full_var()
-{
- if(d_detail) {
- return d_detail->pc_output_buffers_full_var();
- }
- else {
- return std::vector<float>(1,0);
- }
-}
-
-float
-gr_block::pc_work_time()
-{
- if(d_detail) {
- return d_detail->pc_work_time();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_work_time_avg()
-{
- if(d_detail) {
- return d_detail->pc_work_time_avg();
- }
- else {
- return 0;
- }
-}
-
-float
-gr_block::pc_work_time_var()
-{
- if(d_detail) {
- return d_detail->pc_work_time_var();
- }
- else {
- return 0;
- }
-}
-
-void
-gr_block::reset_perf_counters()
-{
- if(d_detail) {
- d_detail->reset_perf_counters();
- }
-}
-
-void
-gr_block::setup_pc_rpc()
-{
- d_pc_rpc_set = true;
-#ifdef GR_CTRLPORT
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "noutput_items", &gr_block::pc_noutput_items,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "noutput items", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg noutput_items", &gr_block::pc_noutput_items_avg,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "Average noutput items", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "var noutput_items", &gr_block::pc_noutput_items_var,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "Var. noutput items", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "nproduced", &gr_block::pc_nproduced,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "items produced", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg nproduced", &gr_block::pc_nproduced_avg,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "Average items produced", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "var nproduced", &gr_block::pc_nproduced_var,
- pmt::mp(0), pmt::mp(32768), pmt::mp(0),
- "", "Var. items produced", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "work time", &gr_block::pc_work_time,
- pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
- "", "clock cycles in call to work", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "avg work time", &gr_block::pc_work_time_avg,
- pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
- "", "Average clock cycles in call to work", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, float>(
- alias(), "var work time", &gr_block::pc_work_time_var,
- pmt::mp(0), pmt::mp(1e9), pmt::mp(0),
- "", "Var. clock cycles in call to work", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "input \% full", &gr_block::pc_input_buffers_full,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "how full input buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "avg input \% full", &gr_block::pc_input_buffers_full_avg,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "Average of how full input buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "var input \% full", &gr_block::pc_input_buffers_full_var,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "Var. of how full input buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "output \% full", &gr_block::pc_output_buffers_full,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "how full output buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "avg output \% full", &gr_block::pc_output_buffers_full_avg,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "Average of how full output buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-
- d_rpc_vars.push_back(
- rpcbasic_sptr(new rpcbasic_register_get<gr_block, std::vector<float> >(
- alias(), "var output \% full", &gr_block::pc_output_buffers_full_var,
- pmt::make_c32vector(0,0), pmt::make_c32vector(0,1), pmt::make_c32vector(0,0),
- "", "Var. of how full output buffers are", RPC_PRIVLVL_MIN,
- DISPTIME | DISPOPTSTRIP)));
-#endif /* GR_CTRLPORT */
-}
-
-std::ostream&
-operator << (std::ostream& os, const gr_block *m)
-{
- os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>";
- return os;
-}
-
-int
-gr_block::general_work(int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- throw std::runtime_error("gr_block::general_work() not implemented");
- return 0;
-}
diff --git a/gnuradio-runtime/lib/gr_block_detail.cc b/gnuradio-runtime/lib/gr_block_detail.cc
deleted file mode 100644
index 7098113301..0000000000
--- a/gnuradio-runtime/lib/gr_block_detail.cc
+++ /dev/null
@@ -1,473 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2009,2010,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_block_detail.h>
-#include <gr_buffer.h>
-#include <iostream>
-
-static long s_ncurrently_allocated = 0;
-
-long
-gr_block_detail_ncurrently_allocated ()
-{
- return s_ncurrently_allocated;
-}
-
-gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
- : d_produce_or(0),
- d_ninputs (ninputs), d_noutputs (noutputs),
- d_input (ninputs), d_output (noutputs),
- d_done (false),
- d_ins_noutput_items(0),
- d_avg_noutput_items(0),
- d_var_noutput_items(0),
- d_ins_nproduced(0),
- d_avg_nproduced(0),
- d_var_nproduced(0),
- d_ins_input_buffers_full(ninputs, 0),
- d_avg_input_buffers_full(ninputs, 0),
- d_var_input_buffers_full(ninputs, 0),
- d_ins_output_buffers_full(noutputs, 0),
- d_avg_output_buffers_full(noutputs, 0),
- d_var_output_buffers_full(noutputs, 0),
- d_ins_work_time(0),
- d_avg_work_time(0),
- d_var_work_time(0),
- d_pc_counter(0)
-{
- s_ncurrently_allocated++;
-}
-
-gr_block_detail::~gr_block_detail ()
-{
- // should take care of itself
- s_ncurrently_allocated--;
-}
-
-void
-gr_block_detail::set_input (unsigned int which, gr_buffer_reader_sptr reader)
-{
- if (which >= d_ninputs)
- throw std::invalid_argument ("gr_block_detail::set_input");
-
- d_input[which] = reader;
-}
-
-void
-gr_block_detail::set_output (unsigned int which, gr_buffer_sptr buffer)
-{
- if (which >= d_noutputs)
- throw std::invalid_argument ("gr_block_detail::set_output");
-
- d_output[which] = buffer;
-}
-
-gr_block_detail_sptr
-gr_make_block_detail (unsigned int ninputs, unsigned int noutputs)
-{
- return gr_block_detail_sptr (new gr_block_detail (ninputs, noutputs));
-}
-
-void
-gr_block_detail::set_done (bool done)
-{
- d_done = done;
- for (unsigned int i = 0; i < d_noutputs; i++)
- d_output[i]->set_done (done);
-
- for (unsigned int i = 0; i < d_ninputs; i++)
- d_input[i]->set_done (done);
-}
-
-void
-gr_block_detail::consume (int which_input, int how_many_items)
-{
- if (how_many_items > 0) {
- input (which_input)->update_read_pointer (how_many_items);
- }
-}
-
-
-void
-gr_block_detail::consume_each (int how_many_items)
-{
- if (how_many_items > 0) {
- for (int i = 0; i < ninputs (); i++) {
- d_input[i]->update_read_pointer (how_many_items);
- }
- }
-}
-
-void
-gr_block_detail::produce (int which_output, int how_many_items)
-{
- if (how_many_items > 0){
- d_output[which_output]->update_write_pointer (how_many_items);
- d_produce_or |= how_many_items;
- }
-}
-
-void
-gr_block_detail::produce_each (int how_many_items)
-{
- if (how_many_items > 0) {
- for (int i = 0; i < noutputs (); i++) {
- d_output[i]->update_write_pointer (how_many_items);
- }
- d_produce_or |= how_many_items;
- }
-}
-
-
-uint64_t
-gr_block_detail::nitems_read(unsigned int which_input)
-{
- if(which_input >= d_ninputs)
- throw std::invalid_argument ("gr_block_detail::n_input_items");
- return d_input[which_input]->nitems_read();
-}
-
-uint64_t
-gr_block_detail::nitems_written(unsigned int which_output)
-{
- if(which_output >= d_noutputs)
- throw std::invalid_argument ("gr_block_detail::n_output_items");
- return d_output[which_output]->nitems_written();
-}
-
-void
-gr_block_detail::add_item_tag(unsigned int which_output, const gr_tag_t &tag)
-{
- if(!pmt::is_symbol(tag.key)) {
- throw pmt::wrong_type("gr_block_detail::add_item_tag key", tag.key);
- }
- else {
- // Add tag to gr_buffer's deque tags
- d_output[which_output]->add_item_tag(tag);
- }
-}
-
-void
-gr_block_detail::remove_item_tag(unsigned int which_input, const gr_tag_t &tag)
-{
- if(!pmt::is_symbol(tag.key)) {
- throw pmt::wrong_type("gr_block_detail::add_item_tag key", tag.key);
- }
- else {
- // Add tag to gr_buffer's deque tags
- d_input[which_input]->buffer()->remove_item_tag(tag);
- }
-}
-
-void
-gr_block_detail::get_tags_in_range(std::vector<gr_tag_t> &v,
- unsigned int which_input,
- uint64_t abs_start,
- uint64_t abs_end)
-{
- // get from gr_buffer_reader's deque of tags
- d_input[which_input]->get_tags_in_range(v, abs_start, abs_end);
-}
-
-void
-gr_block_detail::get_tags_in_range(std::vector<gr_tag_t> &v,
- unsigned int which_input,
- uint64_t abs_start,
- uint64_t abs_end,
- const pmt::pmt_t &key)
-{
- std::vector<gr_tag_t> found_items;
-
- v.resize(0);
-
- // get from gr_buffer_reader's deque of tags
- d_input[which_input]->get_tags_in_range(found_items, abs_start, abs_end);
-
- // Filter further by key name
- pmt::pmt_t itemkey;
- std::vector<gr_tag_t>::iterator itr;
- for(itr = found_items.begin(); itr != found_items.end(); itr++) {
- itemkey = (*itr).key;
- if(pmt::eqv(key, itemkey)) {
- v.push_back(*itr);
- }
- }
-}
-
-void
-gr_block_detail::set_processor_affinity(const std::vector<int> &mask)
-{
- if(threaded) {
- try {
- gr::thread::thread_bind_to_processor(thread, mask);
- }
- catch (std::runtime_error e) {
- std::cerr << "set_processor_affinity: invalid mask." << std::endl;;
- }
- }
-}
-
-void
-gr_block_detail::unset_processor_affinity()
-{
- if(threaded) {
- gr::thread::thread_unbind(thread);
- }
-}
-
-void
-gr_block_detail::start_perf_counters()
-{
- d_start_of_work = gr::high_res_timer_now();
-}
-
-void
-gr_block_detail::stop_perf_counters(int noutput_items, int nproduced)
-{
- d_end_of_work = gr::high_res_timer_now();
- gr::high_res_timer_type diff = d_end_of_work - d_start_of_work;
-
- if(d_pc_counter == 0) {
- d_ins_work_time = diff;
- d_avg_work_time = diff;
- d_var_work_time = 0;
- d_ins_nproduced = nproduced;
- d_avg_nproduced = nproduced;
- d_var_nproduced = 0;
- d_ins_noutput_items = noutput_items;
- d_avg_noutput_items = noutput_items;
- d_var_noutput_items = 0;
- for(size_t i=0; i < d_input.size(); i++) {
- float pfull = static_cast<float>(d_input[i]->items_available()) /
- static_cast<float>(d_input[i]->max_possible_items_available());
- d_ins_input_buffers_full[i] = pfull;
- d_avg_input_buffers_full[i] = pfull;
- d_var_input_buffers_full[i] = 0;
- }
- for(size_t i=0; i < d_output.size(); i++) {
- float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
- static_cast<float>(d_output[i]->bufsize());
- d_ins_output_buffers_full[i] = pfull;
- d_avg_output_buffers_full[i] = pfull;
- d_var_output_buffers_full[i] = 0;
- }
- }
- else {
- float d = diff - d_avg_work_time;
- d_ins_work_time = diff;
- d_avg_work_time = d_avg_work_time + d/d_pc_counter;
- d_var_work_time = d_var_work_time + d*d;
-
- d = nproduced - d_avg_nproduced;
- d_ins_nproduced = nproduced;
- d_avg_nproduced = d_avg_nproduced + d/d_pc_counter;
- d_var_nproduced = d_var_nproduced + d*d;
-
- d = noutput_items - d_avg_noutput_items;
- d_ins_noutput_items = noutput_items;
- d_avg_noutput_items = d_avg_noutput_items + d/d_pc_counter;
- d_var_noutput_items = d_var_noutput_items + d*d;
-
- for(size_t i=0; i < d_input.size(); i++) {
- float pfull = static_cast<float>(d_input[i]->items_available()) /
- static_cast<float>(d_input[i]->max_possible_items_available());
-
- d = pfull - d_avg_input_buffers_full[i];
- d_ins_input_buffers_full[i] = pfull;
- d_avg_input_buffers_full[i] = d_avg_input_buffers_full[i] + d/d_pc_counter;
- d_var_input_buffers_full[i] = d_var_input_buffers_full[i] + d*d;
- }
-
- for(size_t i=0; i < d_output.size(); i++) {
- float pfull = 1.0f - static_cast<float>(d_output[i]->space_available()) /
- static_cast<float>(d_output[i]->bufsize());
-
- d = pfull - d_avg_output_buffers_full[i];
- d_ins_output_buffers_full[i] = pfull;
- d_avg_output_buffers_full[i] = d_avg_output_buffers_full[i] + d/d_pc_counter;
- d_var_output_buffers_full[i] = d_var_output_buffers_full[i] + d*d;
- }
- }
-
- d_pc_counter++;
-}
-
-void
-gr_block_detail::reset_perf_counters()
-{
- d_pc_counter = 0;
-}
-
-float
-gr_block_detail::pc_noutput_items()
-{
- return d_ins_noutput_items;
-}
-
-float
-gr_block_detail::pc_nproduced()
-{
- return d_ins_nproduced;
-}
-
-float
-gr_block_detail::pc_input_buffers_full(size_t which)
-{
- if(which < d_ins_input_buffers_full.size())
- return d_ins_input_buffers_full[which];
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_input_buffers_full()
-{
- return d_ins_input_buffers_full;
-}
-
-float
-gr_block_detail::pc_output_buffers_full(size_t which)
-{
- if(which < d_ins_output_buffers_full.size())
- return d_ins_output_buffers_full[which];
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_output_buffers_full()
-{
- return d_ins_output_buffers_full;
-}
-
-float
-gr_block_detail::pc_work_time()
-{
- return d_ins_work_time;
-}
-
-float
-gr_block_detail::pc_noutput_items_avg()
-{
- return d_avg_noutput_items;
-}
-
-float
-gr_block_detail::pc_nproduced_avg()
-{
- return d_avg_nproduced;
-}
-
-float
-gr_block_detail::pc_input_buffers_full_avg(size_t which)
-{
- if(which < d_avg_input_buffers_full.size())
- return d_avg_input_buffers_full[which];
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_input_buffers_full_avg()
-{
- return d_avg_input_buffers_full;
-}
-
-float
-gr_block_detail::pc_output_buffers_full_avg(size_t which)
-{
- if(which < d_avg_output_buffers_full.size())
- return d_avg_output_buffers_full[which];
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_output_buffers_full_avg()
-{
- return d_avg_output_buffers_full;
-}
-
-float
-gr_block_detail::pc_work_time_avg()
-{
- return d_avg_work_time;
-}
-
-
-float
-gr_block_detail::pc_noutput_items_var()
-{
- return d_var_noutput_items/(d_pc_counter-1);
-}
-
-float
-gr_block_detail::pc_nproduced_var()
-{
- return d_var_nproduced/(d_pc_counter-1);
-}
-
-float
-gr_block_detail::pc_input_buffers_full_var(size_t which)
-{
- if(which < d_avg_input_buffers_full.size())
- return d_var_input_buffers_full[which]/(d_pc_counter-1);
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_input_buffers_full_var()
-{
- std::vector<float> var(d_avg_input_buffers_full.size(), 0);
- for(size_t i = 0; i < d_avg_input_buffers_full.size(); i++)
- var[i] = d_avg_input_buffers_full[i]/(d_pc_counter-1);
- return var;
-}
-
-float
-gr_block_detail::pc_output_buffers_full_var(size_t which)
-{
- if(which < d_avg_output_buffers_full.size())
- return d_var_output_buffers_full[which]/(d_pc_counter-1);
- else
- return 0;
-}
-
-std::vector<float>
-gr_block_detail::pc_output_buffers_full_var()
-{
- std::vector<float> var(d_avg_output_buffers_full.size(), 0);
- for(size_t i = 0; i < d_avg_output_buffers_full.size(); i++)
- var[i] = d_avg_output_buffers_full[i]/(d_pc_counter-1);
- return var;
-}
-
-float
-gr_block_detail::pc_work_time_var()
-{
- return d_var_work_time/(d_pc_counter-1);
-}
diff --git a/gnuradio-runtime/lib/gr_block_executor.cc b/gnuradio-runtime/lib/gr_block_executor.cc
deleted file mode 100644
index cfef406412..0000000000
--- a/gnuradio-runtime/lib/gr_block_executor.cc
+++ /dev/null
@@ -1,487 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2008,2009,2010 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 <gr_block_executor.h>
-#include <gr_block.h>
-#include <gr_block_detail.h>
-#include <gr_buffer.h>
-#include <gr_prefs.h>
-#include <boost/thread.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-#include <limits>
-#include <assert.h>
-#include <stdio.h>
-
-// 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;
-
-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 (gr_block_detail *d, int output_multiple, int min_noutput_items)
-{
- int min_space = std::numeric_limits<int>::max();
- if (min_noutput_items == 0)
- min_noutput_items = 1;
- for (int i = 0; i < d->noutputs (); i++){
- gr::thread::scoped_lock guard(*d->output(i)->mutex());
- int avail_n = round_down(d->output(i)->space_available(), output_multiple);
- int best_n = round_down(d->output(i)->bufsize()/2, output_multiple);
- if (best_n < min_noutput_items)
- throw std::runtime_error("Buffer too small for min_noutput_items");
- int n = std::min(avail_n, best_n);
- if (n < min_noutput_items){ // We're blocked on output.
- if (d->output(i)->done()){ // Downstream is done, therefore we're done.
- return -1;
- }
- return 0;
- }
- min_space = std::min (min_space, n);
- }
- return min_space;
-}
-
-static bool
-propagate_tags(gr_block::tag_propagation_policy_t policy, gr_block_detail *d,
- const std::vector<uint64_t> &start_nitems_read, double rrate,
- std::vector<gr_tag_t> &rtags)
-{
- // Move tags downstream
- // if a sink, we don't need to move downstream
- if(d->sink_p()) {
- return true;
- }
-
- switch(policy) {
- case gr_block::TPP_DONT:
- return true;
- break;
- case gr_block::TPP_ALL_TO_ALL:
- // every tag on every input propogates to everyone downstream
- for(int i = 0; i < d->ninputs(); i++) {
- d->get_tags_in_range(rtags, i, start_nitems_read[i],
- d->nitems_read(i));
-
- std::vector<gr_tag_t>::iterator t;
- if(rrate == 1.0) {
- for(t = rtags.begin(); t != rtags.end(); t++) {
- for(int o = 0; o < d->noutputs(); o++)
- d->output(o)->add_item_tag(*t);
- }
- }
- else {
- for(t = rtags.begin(); t != rtags.end(); t++) {
- gr_tag_t new_tag = *t;
- new_tag.offset *= rrate;
- for(int o = 0; o < d->noutputs(); o++)
- d->output(o)->add_item_tag(new_tag);
- }
- }
- }
- break;
- case gr_block::TPP_ONE_TO_ONE:
- // tags from input i only go to output i
- // this requires d->ninputs() == d->noutputs; this is checked when this
- // type of tag-propagation system is selected in gr_block_detail
- if(d->ninputs() == d->noutputs()) {
- for(int i = 0; i < d->ninputs(); i++) {
- d->get_tags_in_range(rtags, i, start_nitems_read[i],
- d->nitems_read(i));
-
- std::vector<gr_tag_t>::iterator t;
- for(t = rtags.begin(); t != rtags.end(); t++) {
- gr_tag_t new_tag = *t;
- new_tag.offset *= rrate;
- d->output(i)->add_item_tag(new_tag);
- }
- }
- }
- else {
- std::cerr << "Error: gr_block_executor: propagation_policy 'ONE-TO-ONE' requires ninputs == noutputs" << std::endl;
- return false;
- }
-
- break;
- default:
- return true;
- }
- return true;
-}
-
-gr_block_executor::gr_block_executor (gr_block_sptr block, int max_noutput_items)
- : d_block(block), d_log(0), d_max_noutput_items(max_noutput_items)
-{
- if (ENABLE_LOGGING){
- std::string name = str(boost::format("sst-%03d.log") % which_scheduler++);
- d_log = new std::ofstream(name.c_str());
- std::unitbuf(*d_log); // make it unbuffered...
- *d_log << "gr_block_executor: "
- << d_block << std::endl;
- }
-
-#ifdef GR_PERFORMANCE_COUNTERS
- gr_prefs *prefs = gr_prefs::singleton();
- d_use_pc = prefs->get_bool("PerfCounters", "on", false);
-#endif /* GR_PERFORMANCE_COUNTERS */
-
- d_block->start(); // enable any drivers, etc.
-}
-
-gr_block_executor::~gr_block_executor ()
-{
- if (ENABLE_LOGGING)
- delete d_log;
-
- d_block->stop(); // stop any drivers, etc.
-}
-
-gr_block_executor::state
-gr_block_executor::run_one_iteration()
-{
- int noutput_items;
- int max_items_avail;
- int max_noutput_items = d_max_noutput_items;
- int new_alignment=0;
- int alignment_state=-1;
-
- gr_block *m = d_block.get();
- gr_block_detail *d = m->detail().get();
-
- LOG(*d_log << std::endl << m);
-
- if (d->done()){
- assert(0);
- return DONE;
- }
-
- if (d->source_p ()){
- d_ninput_items_required.resize (0);
- d_ninput_items.resize (0);
- d_input_items.resize (0);
- d_input_done.resize(0);
- d_output_items.resize (d->noutputs ());
- d_start_nitems_read.resize(0);
-
- // determine the minimum available output space
- noutput_items = min_available_space (d, m->output_multiple (), m->min_noutput_items ());
- noutput_items = std::min(noutput_items, max_noutput_items);
- 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");
- return BLKD_OUT;
- }
-
- goto setup_call_to_work; // jump to common code
- }
-
- else if (d->sink_p ()){
- d_ninput_items_required.resize (d->ninputs ());
- d_ninput_items.resize (d->ninputs ());
- d_input_items.resize (d->ninputs ());
- d_input_done.resize(d->ninputs());
- d_output_items.resize (0);
- d_start_nitems_read.resize(d->ninputs());
- LOG(*d_log << " sink\n");
-
- max_items_avail = 0;
- for (int i = 0; i < d->ninputs (); i++){
- {
- /*
- * Acquire the mutex and grab local copies of items_available and done.
- */
- gr::thread::scoped_lock guard(*d->input(i)->mutex());
- d_ninput_items[i] = d->input(i)->items_available();
- d_input_done[i] = d->input(i)->done();
- }
-
- LOG(*d_log << " d_ninput_items[" << i << "] = " << d_ninput_items[i] << std::endl);
- LOG(*d_log << " d_input_done[" << i << "] = " << d_input_done[i] << std::endl);
-
- if (d_ninput_items[i] < m->output_multiple() && d_input_done[i])
- goto were_done;
-
- max_items_avail = std::max (max_items_avail, d_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 ());
- noutput_items = std::min(noutput_items, max_noutput_items);
- 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");
- return BLKD_IN;
- }
-
- goto try_again; // Jump to code shared with regular case.
- }
-
- else {
- // do the regular thing
- d_ninput_items_required.resize (d->ninputs ());
- d_ninput_items.resize (d->ninputs ());
- d_input_items.resize (d->ninputs ());
- d_input_done.resize(d->ninputs());
- d_output_items.resize (d->noutputs ());
- d_start_nitems_read.resize(d->ninputs());
-
- max_items_avail = 0;
- for (int i = 0; i < d->ninputs (); i++){
- {
- /*
- * Acquire the mutex and grab local copies of items_available and done.
- */
- gr::thread::scoped_lock guard(*d->input(i)->mutex());
- d_ninput_items[i] = d->input(i)->items_available ();
- d_input_done[i] = d->input(i)->done();
- }
- max_items_avail = std::max (max_items_avail, d_ninput_items[i]);
- }
-
- // determine the minimum available output space
- noutput_items = min_available_space (d, m->output_multiple (), m->min_noutput_items ());
- 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");
- return BLKD_OUT;
- }
-
- 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);
-
- // only test this if we specifically set the output_multiple
- if(m->output_multiple_set())
- reqd_noutput_items = round_down(reqd_noutput_items, m->output_multiple());
-
- if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items)
- noutput_items = reqd_noutput_items;
-
- // if we need this many outputs, overrule the max_noutput_items setting
- max_noutput_items = std::max(m->output_multiple(), max_noutput_items);
- }
- noutput_items = std::min(noutput_items, max_noutput_items);
-
- // Check if we're still unaligned; use up items until we're
- // aligned again. Otherwise, make sure we set the alignment
- // requirement.
- if(!m->output_multiple_set()) {
- if(m->is_unaligned()) {
- // When unaligned, don't just set noutput_items to the remaining
- // samples to meet alignment; this causes too much overhead in
- // requiring a premature call back here. Set the maximum amount
- // of samples to handle unalignment and get us back aligned.
- if(noutput_items >= m->unaligned()) {
- noutput_items = round_up(noutput_items, m->alignment()) \
- - (m->alignment() - m->unaligned());
- new_alignment = 0;
- }
- else {
- new_alignment = m->unaligned() - noutput_items;
- }
- alignment_state = 0;
- }
- else if(noutput_items < m->alignment()) {
- // if we don't have enough for an aligned call, keep track of
- // misalignment, set unaligned flag, and proceed.
- new_alignment = m->alignment() - noutput_items;
- m->set_unaligned(new_alignment);
- m->set_is_unaligned(true);
- alignment_state = 1;
- }
- else {
- // enough to round down to the nearest alignment and process.
- noutput_items = round_down(noutput_items, m->alignment());
- m->set_is_unaligned(false);
- alignment_state = 2;
- }
- }
-
- // ask the block how much input they need to produce noutput_items
- m->forecast (noutput_items, d_ninput_items_required);
-
- // See if we've got sufficient input available
-
- int i;
- for (i = 0; i < d->ninputs (); i++)
- if (d_ninput_items_required[i] > d_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
- LOG(*d_log << " BLKD_IN\n");
- if (d_input_done[i]) // If the upstream block is done, we're done
- goto were_done;
-
- // Is it possible to ever fulfill this request?
- if (d_ninput_items_required[i] > d->input(i)->max_possible_items_available ()){
- // Nope, never going to happen...
- std::cerr << "\nsched: <gr_block " << m->name()
- << " (" << m->unique_id() << ")>"
- << " is requesting more input data\n"
- << " than we can provide.\n"
- << " ninput_items_required = "
- << d_ninput_items_required[i] << "\n"
- << " max_possible_items_available = "
- << d->input(i)->max_possible_items_available() << "\n"
- << " If this is a filter, consider reducing the number of taps.\n";
- goto were_done;
- }
-
- // If we were made unaligned in this round but return here without
- // processing; reset the unalignment claim before next entry.
- if(alignment_state == 1) {
- m->set_unaligned(0);
- m->set_is_unaligned(false);
- }
- return BLKD_IN;
- }
-
- // 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++)
- d_input_items[i] = d->input(i)->read_pointer();
-
- setup_call_to_work:
-
- d->d_produce_or = 0;
- for (int i = 0; i < d->noutputs (); i++)
- d_output_items[i] = d->output(i)->write_pointer();
-
- // determine where to start looking for new tags
- for (int i = 0; i < d->ninputs(); i++)
- d_start_nitems_read[i] = d->nitems_read(i);
-
-#ifdef GR_PERFORMANCE_COUNTERS
- if(d_use_pc)
- d->start_perf_counters();
-#endif /* GR_PERFORMANCE_COUNTERS */
-
- // Do the actual work of the block
- int n = m->general_work (noutput_items, d_ninput_items,
- d_input_items, d_output_items);
-
-#ifdef GR_PERFORMANCE_COUNTERS
- if(d_use_pc)
- d->stop_perf_counters(noutput_items, n);
-#endif /* GR_PERFORMANCE_COUNTERS */
-
- LOG(*d_log << " general_work: noutput_items = " << noutput_items
- << " result = " << n << std::endl);
-
- // Adjust number of unaligned items left to process
- if(m->is_unaligned()) {
- m->set_unaligned(new_alignment);
- m->set_is_unaligned(m->unaligned() != 0);
- }
-
- if(!propagate_tags(m->tag_propagation_policy(), d,
- d_start_nitems_read, m->relative_rate(),
- d_returned_tags))
- goto were_done;
-
- if (n == gr_block::WORK_DONE)
- goto were_done;
-
- if (n != gr_block::WORK_CALLED_PRODUCE)
- d->produce_each (n); // advance write pointers
-
- if (d->d_produce_or > 0) // block produced something
- return READY;
-
- // We didn't produce any output even though we called general_work.
- // We have (most likely) consumed some input.
-
- /*
- // If this is a source, it's broken.
- if (d->source_p()){
- std::cerr << "gr_block_executor: source " << m
- << " produced no output. We're marking it DONE.\n";
- // FIXME maybe we ought to raise an exception...
- goto were_done;
- }
- */
-
- // Have the caller try again...
- return READY_NO_OUTPUT;
- }
- assert (0);
-
- were_done:
- LOG(*d_log << " were_done\n");
- d->set_done (true);
- return DONE;
-}
diff --git a/gnuradio-runtime/lib/gr_block_executor.h b/gnuradio-runtime/lib/gr_block_executor.h
deleted file mode 100644
index 7d5c4949a3..0000000000
--- a/gnuradio-runtime/lib/gr_block_executor.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,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 INCLUDED_GR_BLOCK_EXECUTOR_H
-#define INCLUDED_GR_BLOCK_EXECUTOR_H
-
-#include <gr_runtime_api.h>
-#include <gr_runtime_types.h>
-#include <fstream>
-#include <gr_tags.h>
-
-//class gr_block_executor;
-//typedef boost::shared_ptr<gr_block_executor> gr_block_executor_sptr;
-
-
-/*!
- * \brief Manage the execution of a single block.
- * \ingroup internal
- */
-
-class GR_RUNTIME_API gr_block_executor {
-protected:
- gr_block_sptr d_block; // The block we're trying to run
- std::ofstream *d_log;
-
- // These are allocated here so we don't have to on each iteration
-
- gr_vector_int d_ninput_items_required;
- gr_vector_int d_ninput_items;
- gr_vector_const_void_star d_input_items;
- std::vector<bool> d_input_done;
- gr_vector_void_star d_output_items;
- std::vector<uint64_t> d_start_nitems_read; //stores where tag counts are before work
- std::vector<gr_tag_t> d_returned_tags;
- int d_max_noutput_items;
-
-#ifdef GR_PERFORMANCE_COUNTERS
- bool d_use_pc;
-#endif /* GR_PERFORMANCE_COUNTERS */
-
- public:
- gr_block_executor(gr_block_sptr block, int max_noutput_items=100000);
- ~gr_block_executor ();
-
- enum state {
- READY, // We made progress; everything's cool.
- READY_NO_OUTPUT, // We consumed some input, but produced no output.
- BLKD_IN, // no progress; we're blocked waiting for input data.
- BLKD_OUT, // no progress; we're blocked waiting for output buffer space.
- DONE, // we're done; don't call me again.
- };
-
- /*
- * \brief Run one iteration.
- */
- state run_one_iteration();
-};
-
-#endif /* INCLUDED_GR_BLOCK_EXECUTOR_H */
diff --git a/gnuradio-runtime/lib/gr_block_registry.cc b/gnuradio-runtime/lib/gr_block_registry.cc
deleted file mode 100644
index a80673691a..0000000000
--- a/gnuradio-runtime/lib/gr_block_registry.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2012-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 <gr_basic_block.h>
-#include <gr_block_registry.h>
-#include <gr_tpb_detail.h>
-#include <gr_block_detail.h>
-#include <gr_block.h>
-#include <stdio.h>
-
-gr_block_registry global_block_registry;
-
-gr_block_registry::gr_block_registry(){
- d_ref_map = pmt::make_dict();
-}
-
-long gr_block_registry::block_register(gr_basic_block* block){
- if(d_map.find(block->name()) == d_map.end()){
- d_map[block->name()] = blocksubmap_t();
- d_map[block->name()][0] = block;
- return 0;
- } else {
- for(size_t i=0; i<=d_map[block->name()].size(); i++){
- if(d_map[block->name()].find(i) == d_map[block->name()].end()){
- d_map[block->name()][i] = block;
- return i;
- }
- }
- }
- throw std::runtime_error("should not reach this");
-}
-
-void gr_block_registry::block_unregister(gr_basic_block* block){
- d_map[block->name()].erase( d_map[block->name()].find(block->symbolic_id()));
- d_ref_map = pmt::dict_delete(d_ref_map, pmt::intern(block->symbol_name()));
- if(block->alias_set()){
- d_ref_map = pmt::dict_delete(d_ref_map, pmt::intern(block->alias()));
- }
-}
-
-std::string gr_block_registry::register_symbolic_name(gr_basic_block* block){
- std::stringstream ss;
- ss << block->name() << block->symbolic_id();
- //std::cout << "register_symbolic_name: " << ss.str() << std::endl;
- register_symbolic_name(block, ss.str());
- return ss.str();
-}
-
-void gr_block_registry::register_symbolic_name(gr_basic_block* block, std::string name){
- if(pmt::dict_has_key(d_ref_map, pmt::intern(name))){
- throw std::runtime_error("symbol already exists, can not re-use!");
- }
- d_ref_map = pmt::dict_add(d_ref_map, pmt::intern(name), pmt::make_any(block));
-}
-
-gr_basic_block_sptr gr_block_registry::block_lookup(pmt::pmt_t symbol){
- pmt::pmt_t ref = pmt::dict_ref(d_ref_map, symbol, pmt::PMT_NIL);
- if(pmt::eq(ref, pmt::PMT_NIL)){
- throw std::runtime_error("block lookup failed! block not found!");
- }
- gr_basic_block* blk = boost::any_cast<gr_basic_block*>( pmt::any_ref(ref) );
- return blk->shared_from_this();
-}
-
-
-void gr_block_registry::register_primitive(std::string blk, gr_block* ref){
- primitive_map[blk] = ref;
-}
-
-void gr_block_registry::unregister_primitive(std::string blk){
- primitive_map.erase(primitive_map.find(blk));
-}
-
-void gr_block_registry::notify_blk(std::string blk){
- if(primitive_map.find(blk) == primitive_map.end()){ return; }
- if(primitive_map[blk]->detail().get())
- primitive_map[blk]->detail()->d_tpb.notify_msg();
-}
-
diff --git a/gnuradio-runtime/lib/gr_buffer.cc b/gnuradio-runtime/lib/gr_buffer.cc
deleted file mode 100644
index bdce5b4036..0000000000
--- a/gnuradio-runtime/lib/gr_buffer.cc
+++ /dev/null
@@ -1,347 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,2009,2010 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 <gr_buffer.h>
-#include <gr_vmcircbuf.h>
-#include <gr_math.h>
-#include <stdexcept>
-#include <iostream>
-#include <assert.h>
-#include <algorithm>
-#include <boost/math/common_factor_rt.hpp>
-
-static long s_buffer_count = 0; // counts for debugging storage mgmt
-static long s_buffer_reader_count = 0;
-
-// ----------------------------------------------------------------------------
-// Notes on storage management
-//
-// Pretty much all the fundamental classes are now using the
-// shared_ptr stuff for automatic reference counting. To ensure that
-// no mistakes are made, we make the constructors for classes private,
-// and then provide a free factory function that returns a smart
-// pointer to the desired class.
-//
-// gr_buffer and gr_buffer_reader are no exceptions. However, they
-// both want pointers to each other, and unless we do something, we'll
-// never delete any of them because of the circular structure.
-// They'll always have a reference count of at least one. We could
-// use boost::weak_ptr's from gr_buffer to gr_buffer_reader but that
-// introduces it's own problems. (gr_buffer_reader's destructor needs
-// to call gr_buffer::drop_reader, but has no easy way to get a
-// shared_ptr to itself.)
-//
-// Instead, we solve this problem by having gr_buffer hold a raw
-// pointer to gr_buffer_reader in its d_reader vector.
-// gr_buffer_reader's destructor calls gr_buffer::drop_reader, so
-// we're never left with an dangling pointer. gr_buffer_reader still
-// has a shared_ptr to the buffer ensuring that the buffer doesn't go
-// away under it. However, when the reference count of a
-// gr_buffer_reader goes to zero, we can successfully reclaim it.
-// ----------------------------------------------------------------------------
-
-
-/*
- * Compute the minimum number of buffer items that work (i.e.,
- * address space wrap-around works). To work is to satisfy this
- * contraint for integer buffer_size and k:
- *
- * type_size * nitems == k * page_size
- */
-static long
-minimum_buffer_items (long type_size, long page_size)
-{
- return page_size / boost::math::gcd (type_size, page_size);
-}
-
-
-gr_buffer::gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link)
- : d_base (0), d_bufsize (0), d_vmcircbuf (0),
- d_sizeof_item (sizeof_item), d_link(link),
- d_write_index (0), d_abs_write_offset(0), d_done (false),
- d_last_min_items_read(0)
-{
- if (!allocate_buffer (nitems, sizeof_item))
- throw std::bad_alloc ();
-
- s_buffer_count++;
-}
-
-gr_buffer_sptr
-gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link)
-{
- return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item, link));
-}
-
-gr_buffer::~gr_buffer ()
-{
- delete d_vmcircbuf;
- assert (d_readers.size() == 0);
- s_buffer_count--;
-}
-
-/*!
- * sets d_vmcircbuf, d_base, d_bufsize.
- * returns true iff successful.
- */
-bool
-gr_buffer::allocate_buffer (int nitems, size_t sizeof_item)
-{
- int orig_nitems = nitems;
-
- // Any buffersize we come up with must be a multiple of min_nitems.
-
- int granularity = gr_vmcircbuf_sysconfig::granularity ();
- int min_nitems = minimum_buffer_items (sizeof_item, granularity);
-
- // Round-up nitems to a multiple of min_nitems.
-
- if (nitems % min_nitems != 0)
- nitems = ((nitems / min_nitems) + 1) * min_nitems;
-
- // If we rounded-up a whole bunch, give the user a heads up.
- // This only happens if sizeof_item is not a power of two.
-
- if (nitems > 2 * orig_nitems && nitems * (int) sizeof_item > granularity){
- std::cerr << "gr_buffer::allocate_buffer: warning: tried to allocate\n"
- << " " << orig_nitems << " items of size "
- << sizeof_item << ". Due to alignment requirements\n"
- << " " << nitems << " were allocated. If this isn't OK, consider padding\n"
- << " your structure to a power-of-two bytes.\n"
- << " On this platform, our allocation granularity is " << granularity << " bytes.\n";
- }
-
- d_bufsize = nitems;
- d_vmcircbuf = gr_vmcircbuf_sysconfig::make (d_bufsize * d_sizeof_item);
- if (d_vmcircbuf == 0){
- std::cerr << "gr_buffer::allocate_buffer: failed to allocate buffer of size "
- << d_bufsize * d_sizeof_item / 1024 << " KB\n";
- return false;
- }
-
- d_base = (char *) d_vmcircbuf->pointer_to_first_copy ();
- return true;
-}
-
-
-int
-gr_buffer::space_available ()
-{
- if (d_readers.empty ())
- return d_bufsize - 1; // See comment below
-
- else {
-
- // Find out the maximum amount of data available to our readers
-
- int most_data = d_readers[0]->items_available ();
- uint64_t min_items_read = d_readers[0]->nitems_read();
- for (size_t i = 1; i < d_readers.size (); i++) {
- most_data = std::max (most_data, d_readers[i]->items_available ());
- min_items_read = std::min(min_items_read, d_readers[i]->nitems_read());
- }
-
- if(min_items_read != d_last_min_items_read) {
- prune_tags(d_last_min_items_read);
- d_last_min_items_read = min_items_read;
- }
-
- // The -1 ensures that the case d_write_index == d_read_index is
- // unambiguous. It indicates that there is no data for the reader
-
- return d_bufsize - most_data - 1;
- }
-}
-
-void *
-gr_buffer::write_pointer ()
-{
- return &d_base[d_write_index * d_sizeof_item];
-}
-
-void
-gr_buffer::update_write_pointer (int nitems)
-{
- gr::thread::scoped_lock guard(*mutex());
- d_write_index = index_add (d_write_index, nitems);
- d_abs_write_offset += nitems;
-}
-
-void
-gr_buffer::set_done (bool done)
-{
- gr::thread::scoped_lock guard(*mutex());
- d_done = done;
-}
-
-gr_buffer_reader_sptr
-gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link)
-{
- if (nzero_preload < 0)
- throw std::invalid_argument("gr_buffer_add_reader: nzero_preload must be >= 0");
-
- gr_buffer_reader_sptr r (new gr_buffer_reader (buf,
- buf->index_sub(buf->d_write_index,
- nzero_preload),
- link));
- buf->d_readers.push_back (r.get ());
-
- return r;
-}
-
-void
-gr_buffer::drop_reader (gr_buffer_reader *reader)
-{
- // isn't C++ beautiful... GAG!
-
- std::vector<gr_buffer_reader *>::iterator result =
- std::find (d_readers.begin (), d_readers.end (), reader);
-
- if (result == d_readers.end ())
- throw std::invalid_argument ("gr_buffer::drop_reader"); // we didn't find it...
-
- d_readers.erase (result);
-}
-
-void
-gr_buffer::add_item_tag(const gr_tag_t &tag)
-{
- gr::thread::scoped_lock guard(*mutex());
- d_item_tags.push_back(tag);
-}
-
-void
-gr_buffer::remove_item_tag(const gr_tag_t &tag)
-{
- gr::thread::scoped_lock guard(*mutex());
- for (std::deque<gr_tag_t>::iterator it = d_item_tags.begin(); it != d_item_tags.end(); ++it) {
- if (*it == tag) {
- d_item_tags.erase(it);
- break;
- }
- }
-}
-
-void
-gr_buffer::prune_tags(uint64_t max_time)
-{
- /* NOTE: this function _should_ lock the mutex before editing
- d_item_tags. In practice, this function is only called at
- runtime by min_available_space in gr_block_executor.cc,
- which locks the mutex itself.
-
- If this function is used elsewhere, remember to lock the
- buffer's mutex al la the scoped_lock line below.
- */
- //gr::thread::scoped_lock guard(*mutex());
- std::deque<gr_tag_t>::iterator itr = d_item_tags.begin();
-
- uint64_t item_time;
-
- // Since tags are not guarenteed to be in any particular order,
- // we need to erase here instead of pop_front. An erase in the
- // middle invalidates all iterators; so this resets the iterator
- // to find more. Mostly, we wil be erasing from the front and
- // therefore lose little time this way.
- while(itr != d_item_tags.end()) {
- item_time = (*itr).offset;
- if(item_time < max_time) {
- d_item_tags.erase(itr);
- itr = d_item_tags.begin();
- }
- else
- itr++;
- }
-}
-
-long
-gr_buffer_ncurrently_allocated ()
-{
- return s_buffer_count;
-}
-
-// ----------------------------------------------------------------------------
-
-gr_buffer_reader::gr_buffer_reader(gr_buffer_sptr buffer, unsigned int read_index,
- gr_block_sptr link)
- : d_buffer(buffer), d_read_index(read_index), d_abs_read_offset(0), d_link(link)
-{
- s_buffer_reader_count++;
-}
-
-gr_buffer_reader::~gr_buffer_reader ()
-{
- d_buffer->drop_reader(this);
- s_buffer_reader_count--;
-}
-
-int
-gr_buffer_reader::items_available () const
-{
- return d_buffer->index_sub (d_buffer->d_write_index, d_read_index);
-}
-
-const void *
-gr_buffer_reader::read_pointer ()
-{
- return &d_buffer->d_base[d_read_index * d_buffer->d_sizeof_item];
-}
-
-void
-gr_buffer_reader::update_read_pointer (int nitems)
-{
- gr::thread::scoped_lock guard(*mutex());
- d_read_index = d_buffer->index_add (d_read_index, nitems);
- d_abs_read_offset += nitems;
-}
-
-void
-gr_buffer_reader::get_tags_in_range(std::vector<gr_tag_t> &v,
- uint64_t abs_start,
- uint64_t abs_end)
-{
- gr::thread::scoped_lock guard(*mutex());
-
- v.resize(0);
- std::deque<gr_tag_t>::iterator itr = d_buffer->get_tags_begin();
-
- uint64_t item_time;
- while(itr != d_buffer->get_tags_end()) {
- item_time = (*itr).offset;
-
- if((item_time >= abs_start) && (item_time < abs_end)) {
- v.push_back(*itr);
- }
-
- itr++;
- }
-}
-
-long
-gr_buffer_reader_ncurrently_allocated ()
-{
- return s_buffer_reader_count;
-}
diff --git a/gnuradio-runtime/lib/gr_circular_file.cc b/gnuradio-runtime/lib/gr_circular_file.cc
deleted file mode 100644
index 6f710c49b1..0000000000
--- a/gnuradio-runtime/lib/gr_circular_file.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2002,2010 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 <gr_circular_file.h>
-
-#include <unistd.h>
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-static const int HEADER_SIZE = 4096;
-static const int HEADER_MAGIC = 0xEB021026;
-
-static const int HD_MAGIC = 0;
-static const int HD_HEADER_SIZE = 1; // integer offsets into header
-static const int HD_BUFFER_SIZE = 2;
-static const int HD_BUFFER_BASE = 3;
-static const int HD_BUFFER_CURRENT = 4;
-
-gr_circular_file::gr_circular_file (const char *filename,
- bool writable, int size)
- : d_fd (-1), d_header (0), d_buffer (0), d_mapped_size (0), d_bytes_read (0)
-{
- int mm_prot;
- if (writable){
-#ifdef HAVE_MMAP
- mm_prot = PROT_READ | PROT_WRITE;
-#endif
- d_fd = open (filename, O_CREAT | O_RDWR | O_TRUNC, 0664);
- if (d_fd < 0){
- perror (filename);
- exit (1);
- }
-#ifdef HAVE_MMAP /* FIXME */
- if(ftruncate (d_fd, size + HEADER_SIZE) != 0) {
- perror (filename);
- exit (1);
- }
-#endif
- }
- else {
-#ifdef HAVE_MMAP
- mm_prot = PROT_READ;
-#endif
- d_fd = open (filename, O_RDONLY);
- if (d_fd < 0){
- perror (filename);
- exit (1);
- }
- }
-
- struct stat statbuf;
- if (fstat (d_fd, &statbuf) < 0){
- perror (filename);
- exit (1);
- }
-
- if (statbuf.st_size < HEADER_SIZE){
- fprintf (stderr, "%s: file too small to be circular buffer\n", filename);
- exit (1);
- }
-
- d_mapped_size = statbuf.st_size;
-#ifdef HAVE_MMAP
- void *p = mmap (0, d_mapped_size, mm_prot, MAP_SHARED, d_fd, 0);
- if (p == MAP_FAILED){
- perror ("gr_circular_file: mmap failed");
- exit (1);
- }
-
- d_header = (int *) p;
-#else
- perror ("gr_circular_file: mmap unsupported by this system");
- exit (1);
-#endif
-
- if (writable){ // init header
-
- if (size < 0){
- fprintf (stderr, "gr_circular_buffer: size must be > 0 when writable\n");
- exit (1);
- }
-
- d_header[HD_MAGIC] = HEADER_MAGIC;
- d_header[HD_HEADER_SIZE] = HEADER_SIZE;
- d_header[HD_BUFFER_SIZE] = size;
- d_header[HD_BUFFER_BASE] = HEADER_SIZE; // right after header
- d_header[HD_BUFFER_CURRENT] = 0;
- }
-
- // sanity check (the asserts are a bit unforgiving...)
-
- assert (d_header[HD_MAGIC] == HEADER_MAGIC);
- assert (d_header[HD_HEADER_SIZE] == HEADER_SIZE);
- assert (d_header[HD_BUFFER_SIZE] > 0);
- assert (d_header[HD_BUFFER_BASE] >= d_header[HD_HEADER_SIZE]);
- assert (d_header[HD_BUFFER_BASE] + d_header[HD_BUFFER_SIZE] <= d_mapped_size);
- assert (d_header[HD_BUFFER_CURRENT] >= 0 &&
- d_header[HD_BUFFER_CURRENT] < d_header[HD_BUFFER_SIZE]);
-
- d_bytes_read = 0;
- d_buffer = (unsigned char *) d_header + d_header[HD_BUFFER_BASE];
-}
-
-gr_circular_file::~gr_circular_file ()
-{
-#ifdef HAVE_MMAP
- if (munmap ((char *) d_header, d_mapped_size) < 0){
- perror ("gr_circular_file: munmap");
- exit (1);
- }
-#endif
- close (d_fd);
-}
-
-bool
-gr_circular_file::write (void *vdata, int nbytes)
-{
- unsigned char *data = (unsigned char *) vdata;
- int buffer_size = d_header[HD_BUFFER_SIZE];
- int buffer_current = d_header[HD_BUFFER_CURRENT];
-
- while (nbytes > 0){
- int n = std::min (nbytes, buffer_size - buffer_current);
- memcpy (d_buffer + buffer_current, data, n);
-
- buffer_current += n;
- if (buffer_current >= buffer_size)
- buffer_current = 0;
-
- data += n;
- nbytes -= n;
- }
-
- d_header[HD_BUFFER_CURRENT] = buffer_current;
- return true;
-}
-
-int
-gr_circular_file::read (void *vdata, int nbytes)
-{
- unsigned char *data = (unsigned char *) vdata;
- int buffer_current = d_header[HD_BUFFER_CURRENT];
- int buffer_size = d_header[HD_BUFFER_SIZE];
- int total = 0;
-
- nbytes = std::min (nbytes, buffer_size - d_bytes_read);
-
- while (nbytes > 0){
- int offset = (buffer_current + d_bytes_read) % buffer_size;
- int n = std::min (nbytes, buffer_size - offset);
- memcpy (data, d_buffer + offset, n);
- data += n;
- d_bytes_read += n;
- total += n;
- nbytes -= n;
- }
- return total;
-}
-
-void
-gr_circular_file::reset_read_pointer ()
-{
- d_bytes_read = 0;
-}
diff --git a/gnuradio-runtime/lib/gr_circular_file.h b/gnuradio-runtime/lib/gr_circular_file.h
deleted file mode 100644
index 2b61bf2711..0000000000
--- a/gnuradio-runtime/lib/gr_circular_file.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef _GR_CIRCULAR_FILE_H_
-#define _GR_CIRCULAR_FILE_H_
-
-#include <gr_runtime_api.h>
-
-/*
- * writes input data into a circular buffer on disk.
- *
- * the file contains a fixed header:
- * 0x0000: int32 magic (0xEB021026)
- * 0x0004: int32 size in bytes of header (constant 4096)
- * 0x0008: int32 size in bytes of circular buffer (not including header)
- * 0x000C: int32 file offset to beginning of circular buffer
- * 0x0010: int32 byte offset from beginning of circular buffer to
- * current start of data
- *
- */
-class GR_RUNTIME_API gr_circular_file {
- int d_fd;
- int *d_header;
- unsigned char *d_buffer;
- int d_mapped_size;
- int d_bytes_read;
-
-public:
- gr_circular_file (const char *filename, bool writable = false, int size = 0);
- ~gr_circular_file ();
-
- bool write (void *data, int nbytes);
-
- // returns # of bytes actually read or 0 if end of buffer, or -1 on error.
- int read (void *data, int nbytes);
-
- // reset read pointer to beginning of buffer.
- void reset_read_pointer ();
-};
-
-#endif /* _GR_CIRCULAR_FILE_H_ */ \ No newline at end of file
diff --git a/gnuradio-runtime/lib/gr_dispatcher.cc b/gnuradio-runtime/lib/gr_dispatcher.cc
deleted file mode 100644
index 96ebe9ad8b..0000000000
--- a/gnuradio-runtime/lib/gr_dispatcher.cc
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 <gr_dispatcher.h>
-#include <math.h>
-#include <errno.h>
-#include <stdio.h>
-
-#ifdef HAVE_SELECT
-# ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-# else
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-# endif
-# ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-# endif
-# ifdef HAVE_UNISTD_H
-# include <unistd.h>
-# endif
-# endif
-#endif
-
-
-static gr_dispatcher_sptr s_singleton;
-
-gr_dispatcher_sptr
-gr_make_dispatcher()
-{
- return gr_dispatcher_sptr(new gr_dispatcher());
-}
-
-gr_dispatcher_sptr
-gr_dispatcher_singleton()
-{
- if (s_singleton)
- return s_singleton;
-
- s_singleton = gr_make_dispatcher();
- return s_singleton;
-}
-
-#if !defined(HAVE_SELECT) // Stub it out
-
-gr_dispatcher::gr_dispatcher()
-{
-}
-
-gr_dispatcher::~gr_dispatcher()
-{
-}
-
-bool
-gr_dispatcher::add_handler(gr_select_handler_sptr handler)
-{
- return true;
-}
-
-bool
-gr_dispatcher::del_handler(gr_select_handler_sptr handler)
-{
- return true;
-}
-
-bool
-gr_dispatcher::del_handler(gr_select_handler *handler)
-{
- return true;
-}
-
-void
-gr_dispatcher::loop(double timeout)
-{
-}
-
-#else // defined(HAVE_SELECT)
-
-gr_dispatcher::gr_dispatcher()
- : d_handler(FD_SETSIZE), d_max_index(-1)
-{
-}
-
-gr_dispatcher::~gr_dispatcher()
-{
-}
-
-bool
-gr_dispatcher::add_handler(gr_select_handler_sptr handler)
-{
- int fd = handler->fd();
- if (fd < 0 || fd >= FD_SETSIZE)
- return false;
-
- d_max_index = std::max(d_max_index, fd);
- d_handler[fd] = handler;
- return true;
-}
-
-bool
-gr_dispatcher::del_handler(gr_select_handler_sptr handler)
-{
- return del_handler(handler.get());
-}
-
-bool
-gr_dispatcher::del_handler(gr_select_handler *handler)
-{
- int fd = handler->fd();
- if (fd < 0 || fd >= FD_SETSIZE)
- return false;
-
- d_handler[fd].reset();
-
- if (fd == d_max_index){
- int i;
- for (i = fd - 1; i >= 0 && !d_handler[i]; i--)
- ;
- d_max_index = i;
- }
- return true;
-}
-
-
-void
-gr_dispatcher::loop(double timeout)
-{
- struct timeval master;
- struct timeval tmp;
- fd_set rd_set;
- fd_set wr_set;
-
- double secs = floor (timeout);
- master.tv_sec = (long) secs;
- master.tv_usec = (long) ((timeout - secs) * 1e6);
-
- while (d_max_index >= 0){
- FD_ZERO(&rd_set);
- FD_ZERO(&wr_set);
-
- for (int i = 0; i <= d_max_index; i++){
- if (d_handler[i] && d_handler[i]->readable())
- FD_SET(i, &rd_set);
- if (d_handler[i] && d_handler[i]->writable())
- FD_SET(i, &wr_set);
- }
-
- tmp = master;
- int retval = select(d_max_index+1, &rd_set, &wr_set, 0, &tmp);
- if (retval == 0) // timed out with nothing ready
- continue;
- if (retval < 0){
- if (errno == EINTR)
- continue;
- perror ("gr_dispatcher/select");
- return;
- }
-
- for (int i = 0; i <= d_max_index; i++){
- if (FD_ISSET(i, &rd_set))
- if (d_handler[i])
- d_handler[i]->handle_read();
- if (FD_ISSET(i, &wr_set))
- if (d_handler[i])
- d_handler[i]->handle_write();
- }
- }
-}
-
-#endif
diff --git a/gnuradio-runtime/lib/gr_error_handler.cc b/gnuradio-runtime/lib/gr_error_handler.cc
deleted file mode 100644
index 448682966e..0000000000
--- a/gnuradio-runtime/lib/gr_error_handler.cc
+++ /dev/null
@@ -1,244 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 code is based on error.cc from the "Click Modular Router".
- * Original copyright follows:
- */
-/*
- * error.{cc,hh} -- flexible classes for error reporting
- * Eddie Kohler
- *
- * Copyright (c) 1999-2000 Massachusetts Institute of Technology
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, subject to the conditions
- * listed in the Click LICENSE file. These conditions include: you must
- * preserve this copyright notice, and you cannot mention the copyright
- * holders in advertising related to the Software without their permission.
- * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
- * notice is a summary of the Click LICENSE file; the license in that file is
- * legally binding.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_error_handler.h>
-#include <assert.h>
-#include <stdexcept>
-#include <unistd.h>
-
-#ifdef HAVE_IO_H
-#include <io.h>
-#endif
-
-static gr_error_handler *s_default_handler = 0;
-static gr_error_handler *s_silent_handler = 0;
-
-bool
-gr_error_handler::has_default_handler()
-{
- return s_default_handler != 0;
-}
-
-void
-gr_error_handler::set_default_handler(gr_error_handler *errh)
-{
- s_default_handler = errh;
-}
-
-gr_error_handler *
-gr_error_handler::default_handler()
-{
- assert (s_default_handler != 0);
- return s_default_handler;
-}
-
-gr_error_handler *
-gr_error_handler::silent_handler()
-{
- assert (s_silent_handler != 0);
- return s_silent_handler;
-}
-
-// ----------------------------------------------------------------
-
-gr_error_handler::~gr_error_handler()
-{
- // nop
-}
-
-void
-gr_error_handler::debug(const char *format, ...)
-{
- va_list val;
- va_start(val, format);
- verror(ERR_DEBUG, format, val);
- va_end(val);
-}
-
-void
-gr_error_handler::message(const char *format, ...)
-{
- va_list val;
- va_start(val, format);
- verror(ERR_MESSAGE, format, val);
- va_end(val);
-}
-
-void
-gr_error_handler::warning(const char *format, ...)
-{
- va_list val;
- va_start(val, format);
- verror(ERR_WARNING, format, val);
- va_end(val);
-}
-
-void
-gr_error_handler::error(const char *format, ...)
-{
- va_list val;
- va_start(val, format);
- verror(ERR_ERROR, format, val);
- va_end(val);
-}
-
-void
-gr_error_handler::fatal(const char *format, ...)
-{
- va_list val;
- va_start(val, format);
- verror(ERR_FATAL, format, val);
- va_end(val);
-}
-
-void
-gr_error_handler::verror(seriousness s, const char *format, va_list val)
-{
- std::string text = make_text(s, format, val);
- handle_text(s, text);
- count_error(s);
-}
-
-void
-gr_error_handler::verror_text(seriousness s, const std::string &text)
-{
- // text is already made
- handle_text(s, text);
- count_error(s);
-}
-
-std::string
-gr_error_handler::make_text(seriousness s, const char *format, va_list val)
-{
- char text_buf[4096];
- vsnprintf(text_buf, sizeof(text_buf), format, val);
- text_buf[sizeof(text_buf)-1] = 0;
- return text_buf;
-}
-
-// ----------------------------------------------------------------
-
-void
-gr_base_error_handler::count_error(seriousness s)
-{
- if (s < ERR_WARNING)
- /* do nothing */;
- else if (s < ERR_ERROR)
- d_nwarnings++;
- else
- d_nerrors++;
-}
-
-// ----------------------------------------------------------------
-
-gr_file_error_handler::gr_file_error_handler(FILE *file)
- : d_file(file), d_fd(-1)
-{
-}
-
-gr_file_error_handler::gr_file_error_handler(int file_descriptor)
-{
- d_fd = dup(file_descriptor); // so we can fclose it
- if (d_fd == -1){
- perror("gr_file_error_handler:dup");
- throw std::invalid_argument("gr_file_error_handler:dup");
- }
- d_file = fdopen(d_fd, "w");
- if (d_file == 0){
- perror("gr_file_error_handler:fdopen");
- throw std::invalid_argument("gr_file_error_handler:fdopen");
- }
-}
-
-gr_file_error_handler::~gr_file_error_handler()
-{
- if (d_fd != -1){
- fclose(d_file);
- }
-}
-
-void
-gr_file_error_handler::handle_text(seriousness s, const std::string &text)
-{
- if (text.length() <= 0)
- return;
-
- fwrite(text.data(), 1, text.length(), d_file);
- if (text[text.length()-1] != '\n')
- fwrite("\n", 1, 1, d_file);
-
- if (d_fd != -1)
- fflush(d_file); // keep synced with any other users of fd
-}
-
-
-// ----------------------------------------------------------------
-// static error handlers
-//
-
-class gr_silent_error_handler : public gr_base_error_handler
-{
-public:
- gr_silent_error_handler() {}
- void handle_text(seriousness s, const std::string &str);
-};
-
-void
-gr_silent_error_handler::handle_text(seriousness s, const std::string &str)
-{
- // nop
-}
-
-class force_init {
-public:
- force_init()
- {
- s_default_handler = new gr_file_error_handler(stdout);
- s_silent_handler = new gr_silent_error_handler();
- }
-};
-
-static force_init kludge;
diff --git a/gnuradio-runtime/lib/gr_fast_atan2f.cc b/gnuradio-runtime/lib/gr_fast_atan2f.cc
deleted file mode 100644
index 8b7bfea12e..0000000000
--- a/gnuradio-runtime/lib/gr_fast_atan2f.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 <gr_math.h> // declaration is in here
-#include <cmath>
-
-#define REAL float
-
-/***************************************************************************/
-/* Constant definitions */
-/***************************************************************************/
-
-#define TAN_MAP_RES 0.003921569 /* (smallest non-zero value in table) */
-#define RAD_PER_DEG 0.017453293
-#define TAN_MAP_SIZE 256
-
-/* arctangents from 0 to pi/4 radians */
-static REAL
-fast_atan_table[257] = {
- 0.000000e+00, 3.921549e-03, 7.842976e-03, 1.176416e-02,
- 1.568499e-02, 1.960533e-02, 2.352507e-02, 2.744409e-02,
- 3.136226e-02, 3.527947e-02, 3.919560e-02, 4.311053e-02,
- 4.702413e-02, 5.093629e-02, 5.484690e-02, 5.875582e-02,
- 6.266295e-02, 6.656816e-02, 7.047134e-02, 7.437238e-02,
- 7.827114e-02, 8.216752e-02, 8.606141e-02, 8.995267e-02,
- 9.384121e-02, 9.772691e-02, 1.016096e-01, 1.054893e-01,
- 1.093658e-01, 1.132390e-01, 1.171087e-01, 1.209750e-01,
- 1.248376e-01, 1.286965e-01, 1.325515e-01, 1.364026e-01,
- 1.402496e-01, 1.440924e-01, 1.479310e-01, 1.517652e-01,
- 1.555948e-01, 1.594199e-01, 1.632403e-01, 1.670559e-01,
- 1.708665e-01, 1.746722e-01, 1.784728e-01, 1.822681e-01,
- 1.860582e-01, 1.898428e-01, 1.936220e-01, 1.973956e-01,
- 2.011634e-01, 2.049255e-01, 2.086818e-01, 2.124320e-01,
- 2.161762e-01, 2.199143e-01, 2.236461e-01, 2.273716e-01,
- 2.310907e-01, 2.348033e-01, 2.385093e-01, 2.422086e-01,
- 2.459012e-01, 2.495869e-01, 2.532658e-01, 2.569376e-01,
- 2.606024e-01, 2.642600e-01, 2.679104e-01, 2.715535e-01,
- 2.751892e-01, 2.788175e-01, 2.824383e-01, 2.860514e-01,
- 2.896569e-01, 2.932547e-01, 2.968447e-01, 3.004268e-01,
- 3.040009e-01, 3.075671e-01, 3.111252e-01, 3.146752e-01,
- 3.182170e-01, 3.217506e-01, 3.252758e-01, 3.287927e-01,
- 3.323012e-01, 3.358012e-01, 3.392926e-01, 3.427755e-01,
- 3.462497e-01, 3.497153e-01, 3.531721e-01, 3.566201e-01,
- 3.600593e-01, 3.634896e-01, 3.669110e-01, 3.703234e-01,
- 3.737268e-01, 3.771211e-01, 3.805064e-01, 3.838825e-01,
- 3.872494e-01, 3.906070e-01, 3.939555e-01, 3.972946e-01,
- 4.006244e-01, 4.039448e-01, 4.072558e-01, 4.105574e-01,
- 4.138496e-01, 4.171322e-01, 4.204054e-01, 4.236689e-01,
- 4.269229e-01, 4.301673e-01, 4.334021e-01, 4.366272e-01,
- 4.398426e-01, 4.430483e-01, 4.462443e-01, 4.494306e-01,
- 4.526070e-01, 4.557738e-01, 4.589307e-01, 4.620778e-01,
- 4.652150e-01, 4.683424e-01, 4.714600e-01, 4.745676e-01,
- 4.776654e-01, 4.807532e-01, 4.838312e-01, 4.868992e-01,
- 4.899573e-01, 4.930055e-01, 4.960437e-01, 4.990719e-01,
- 5.020902e-01, 5.050985e-01, 5.080968e-01, 5.110852e-01,
- 5.140636e-01, 5.170320e-01, 5.199904e-01, 5.229388e-01,
- 5.258772e-01, 5.288056e-01, 5.317241e-01, 5.346325e-01,
- 5.375310e-01, 5.404195e-01, 5.432980e-01, 5.461666e-01,
- 5.490251e-01, 5.518738e-01, 5.547124e-01, 5.575411e-01,
- 5.603599e-01, 5.631687e-01, 5.659676e-01, 5.687566e-01,
- 5.715357e-01, 5.743048e-01, 5.770641e-01, 5.798135e-01,
- 5.825531e-01, 5.852828e-01, 5.880026e-01, 5.907126e-01,
- 5.934128e-01, 5.961032e-01, 5.987839e-01, 6.014547e-01,
- 6.041158e-01, 6.067672e-01, 6.094088e-01, 6.120407e-01,
- 6.146630e-01, 6.172755e-01, 6.198784e-01, 6.224717e-01,
- 6.250554e-01, 6.276294e-01, 6.301939e-01, 6.327488e-01,
- 6.352942e-01, 6.378301e-01, 6.403565e-01, 6.428734e-01,
- 6.453808e-01, 6.478788e-01, 6.503674e-01, 6.528466e-01,
- 6.553165e-01, 6.577770e-01, 6.602282e-01, 6.626701e-01,
- 6.651027e-01, 6.675261e-01, 6.699402e-01, 6.723452e-01,
- 6.747409e-01, 6.771276e-01, 6.795051e-01, 6.818735e-01,
- 6.842328e-01, 6.865831e-01, 6.889244e-01, 6.912567e-01,
- 6.935800e-01, 6.958943e-01, 6.981998e-01, 7.004964e-01,
- 7.027841e-01, 7.050630e-01, 7.073330e-01, 7.095943e-01,
- 7.118469e-01, 7.140907e-01, 7.163258e-01, 7.185523e-01,
- 7.207701e-01, 7.229794e-01, 7.251800e-01, 7.273721e-01,
- 7.295557e-01, 7.317307e-01, 7.338974e-01, 7.360555e-01,
- 7.382053e-01, 7.403467e-01, 7.424797e-01, 7.446045e-01,
- 7.467209e-01, 7.488291e-01, 7.509291e-01, 7.530208e-01,
- 7.551044e-01, 7.571798e-01, 7.592472e-01, 7.613064e-01,
- 7.633576e-01, 7.654008e-01, 7.674360e-01, 7.694633e-01,
- 7.714826e-01, 7.734940e-01, 7.754975e-01, 7.774932e-01,
- 7.794811e-01, 7.814612e-01, 7.834335e-01, 7.853983e-01,
- 7.853983e-01
- };
-
-
-/*****************************************************************************
-Function: Arc tangent
-
-Syntax: angle = fast_atan2(y, x);
-REAL y y component of input vector
-REAL x x component of input vector
-REAL angle angle of vector (x, y) in radians
-
-Description: This function calculates the angle of the vector (x,y) based
-on a table lookup and linear interpolation. The table uses
-a 256 point table covering -45 to +45 degrees and uses
-symetry to determine the final angle value in the range of
--180 to 180 degrees. Note that this function uses the small
-angle approximation for values close to zero. This routine
-calculates the arc tangent with an average error of
-+/- 0.045 degrees.
-*****************************************************************************/
-
-REAL
-gr_fast_atan2f(REAL y, REAL x)
-{
- REAL x_abs, y_abs, z;
- REAL alpha, angle, base_angle;
- int index;
-
- /* don't divide by zero! */ // FIXME could get hosed with -0.0
- if ((y == 0.0) && (x == 0.0))
- return 0.0;
-
- /* normalize to +/- 45 degree range */
- y_abs = fabs(y);
- x_abs = fabs(x);
- //z = (y_abs < x_abs ? y_abs / x_abs : x_abs / y_abs);
- if (y_abs < x_abs)
- z = y_abs / x_abs;
- else
- z = x_abs / y_abs;
-
- /* when ratio approaches the table resolution, the angle is */
- /* best approximated with the argument itself... */
- if (z < TAN_MAP_RES)
- base_angle = z;
- else {
- /* find index and interpolation value */
- alpha = z * (REAL) TAN_MAP_SIZE - .5;
- index = (int) alpha;
- alpha -= (REAL) index;
- /* determine base angle based on quadrant and */
- /* add or subtract table value from base angle based on quadrant */
- base_angle = fast_atan_table[index];
- base_angle +=
- (fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;
- }
-
- if (x_abs > y_abs) { /* -45 -> 45 or 135 -> 225 */
- if (x >= 0.0) { /* -45 -> 45 */
- if (y >= 0.0)
- angle = base_angle; /* 0 -> 45, angle OK */
- else
- angle = -base_angle; /* -45 -> 0, angle = -angle */
- } else { /* 135 -> 180 or 180 -> -135 */
- angle = 3.14159265358979323846;
- if (y >= 0.0)
- angle -= base_angle; /* 135 -> 180, angle = 180 - angle */
- else
- angle = base_angle - angle; /* 180 -> -135, angle = angle - 180 */
- }
- } else { /* 45 -> 135 or -135 -> -45 */
- if (y >= 0.0) { /* 45 -> 135 */
- angle = 1.57079632679489661923;
- if (x >= 0.0)
- angle -= base_angle; /* 45 -> 90, angle = 90 - angle */
- else
- angle += base_angle; /* 90 -> 135, angle = 90 + angle */
- } else { /* -135 -> -45 */
- angle = -1.57079632679489661923;
- if (x >= 0.0)
- angle += base_angle; /* -90 -> -45, angle = -90 + angle */
- else
- angle -= base_angle; /* -135 -> -90, angle = -90 - angle */
- }
- }
-
-#ifdef ZERO_TO_TWOPI
- if (angle < 0)
- return (angle + TWOPI);
- else
- return (angle);
-#else
- return (angle);
-#endif
-}
-
diff --git a/gnuradio-runtime/lib/gr_feval.cc b/gnuradio-runtime/lib/gr_feval.cc
deleted file mode 100644
index 89f09984cf..0000000000
--- a/gnuradio-runtime/lib/gr_feval.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 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 <gr_feval.h>
-
-gr_feval_dd::~gr_feval_dd(){}
-
-double
-gr_feval_dd::eval(double x)
-{
- return 0;
-}
-
-double
-gr_feval_dd::calleval(double x)
-{
- return eval(x);
-}
-
-// ----------------------------------------------------------------
-
-gr_feval_cc::~gr_feval_cc(){}
-
-gr_complex
-gr_feval_cc::eval(gr_complex x)
-{
- return 0;
-}
-
-gr_complex
-gr_feval_cc::calleval(gr_complex x)
-{
- return eval(x);
-}
-
-// ----------------------------------------------------------------
-
-gr_feval_ll::~gr_feval_ll(){}
-
-long
-gr_feval_ll::eval(long x)
-{
- return 0;
-}
-
-long
-gr_feval_ll::calleval(long x)
-{
- return eval(x);
-}
-
-// ----------------------------------------------------------------
-
-gr_feval::~gr_feval(){}
-
-void
-gr_feval::eval(void)
-{
- // nop
-}
-
-void
-gr_feval::calleval(void)
-{
- eval();
-}
-
-// ----------------------------------------------------------------
-
-gr_feval_p::~gr_feval_p(){}
-
-void
-gr_feval_p::eval(pmt::pmt_t x)
-{
- // nop
-}
-
-void
-gr_feval_p::calleval(pmt::pmt_t x)
-{
- eval(x);
-}
-
-/*
- * Trivial examples showing C++ (transparently) calling Python
- */
-double
-gr_feval_dd_example(gr_feval_dd *f, double x)
-{
- return f->calleval(x);
-}
-
-gr_complex
-gr_feval_cc_example(gr_feval_cc *f, gr_complex x)
-{
- return f->calleval(x);
-}
-
-long
-gr_feval_ll_example(gr_feval_ll *f, long x)
-{
- return f->calleval(x);
-}
-
-void
-gr_feval_example(gr_feval *f)
-{
- f->calleval();
-}
diff --git a/gnuradio-runtime/lib/gr_flat_flowgraph.cc b/gnuradio-runtime/lib/gr_flat_flowgraph.cc
deleted file mode 100644
index de1e227ef0..0000000000
--- a/gnuradio-runtime/lib/gr_flat_flowgraph.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 (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 <gr_flat_flowgraph.h>
-#include <gr_block_detail.h>
-#include <gr_io_signature.h>
-#include <gr_buffer.h>
-#include <gr_prefs.h>
-#include <volk/volk.h>
-#include <iostream>
-#include <map>
-#include <boost/format.hpp>
-
-#define GR_FLAT_FLOWGRAPH_DEBUG 0
-
-// 32Kbyte buffer size between blocks
-#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
-
-static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
-
-gr_flat_flowgraph_sptr
-gr_make_flat_flowgraph()
-{
- return gr_flat_flowgraph_sptr(new gr_flat_flowgraph());
-}
-
-gr_flat_flowgraph::gr_flat_flowgraph()
-{
-}
-
-gr_flat_flowgraph::~gr_flat_flowgraph()
-{
-}
-
-void
-gr_flat_flowgraph::setup_connections()
-{
- gr_basic_block_vector_t blocks = calc_used_blocks();
-
- // Assign block details to blocks
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
- cast_to_block_sptr(*p)->set_detail(allocate_block_detail(*p));
-
- // Connect inputs to outputs for each block
- for(gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- connect_block_inputs(*p);
-
- gr_block_sptr block = cast_to_block_sptr(*p);
- block->set_unaligned(0);
- block->set_is_unaligned(false);
- }
-
- // Connect message ports connetions
- for(gr_msg_edge_viter_t i = d_msg_edges.begin(); i != d_msg_edges.end(); i++){
- if(GR_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_block_detail_sptr
-gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block)
-{
- int ninputs = calc_used_ports(block, true).size();
- int noutputs = calc_used_ports(block, false).size();
- gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
-
- gr_block_sptr grblock = cast_to_block_sptr(block);
- if(!grblock)
- throw std::runtime_error("allocate_block_detail found non-gr_block");
-
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Creating block detail for " << block << std::endl;
-
- for (int i = 0; i < noutputs; i++) {
- grblock->expand_minmax_buffer(i);
-
- gr_buffer_sptr buffer = allocate_buffer(block, i);
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Allocated buffer for output " << block << ":" << i << std::endl;
- detail->set_output(i, buffer);
-
- // Update the block's max_output_buffer based on what was actually allocated.
- grblock->set_max_output_buffer(i, buffer->bufsize());
- }
-
- return detail;
-}
-
-gr_buffer_sptr
-gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port)
-{
- gr_block_sptr grblock = cast_to_block_sptr(block);
- if (!grblock)
- throw std::runtime_error("allocate_buffer found non-gr_block");
- int item_size = block->output_signature()->sizeof_stream_item(port);
-
- // *2 because we're now only filling them 1/2 way in order to
- // increase the available parallelism when using the TPB scheduler.
- // (We're double buffering, where we used to single buffer)
- int nitems = s_fixed_buffer_size * 2 / item_size;
-
- // Make sure there are at least twice the output_multiple no. of items
- if (nitems < 2*grblock->output_multiple()) // Note: this means output_multiple()
- nitems = 2*grblock->output_multiple(); // can't be changed by block dynamically
-
- // If any downstream blocks are decimators and/or have a large output_multiple,
- // ensure we have a buffer at least twice their decimation factor*output_multiple
- gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
-
- // limit buffer size if indicated
- if(grblock->max_output_buffer(port) > 0) {
-// std::cout << "constraining output items to " << block->max_output_buffer(port) << "\n";
- nitems = std::min((long)nitems, (long)grblock->max_output_buffer(port));
- nitems -= nitems%grblock->output_multiple();
- if( nitems < 1 )
- throw std::runtime_error("problems allocating a buffer with the given max output buffer constraint!");
- }
- else if(grblock->min_output_buffer(port) > 0) {
- nitems = std::max((long)nitems, (long)grblock->min_output_buffer(port));
- nitems -= nitems%grblock->output_multiple();
- if( nitems < 1 )
- throw std::runtime_error("problems allocating a buffer with the given min output buffer constraint!");
- }
-
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- gr_block_sptr dgrblock = cast_to_block_sptr(*p);
- if (!dgrblock)
- throw std::runtime_error("allocate_buffer found non-gr_block");
-
- double decimation = (1.0/dgrblock->relative_rate());
- int multiple = dgrblock->output_multiple();
- int history = dgrblock->history();
- nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history)));
- }
-
-// std::cout << "gr_make_buffer(" << nitems << ", " << item_size << ", " << grblock << "\n";
- return gr_make_buffer(nitems, item_size, grblock);
-}
-
-void
-gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block)
-{
- gr_block_sptr grblock = cast_to_block_sptr(block);
- if (!grblock)
- throw std::runtime_error("connect_block_inputs found non-gr_block");
-
- // Get its detail and edges that feed into it
- gr_block_detail_sptr detail = grblock->detail();
- gr_edge_vector_t in_edges = calc_upstream_edges(block);
-
- // For each edge that feeds into it
- for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
- // Set the buffer reader on the destination port to the output
- // buffer on the source port
- int dst_port = e->dst().port();
- int src_port = e->src().port();
- gr_basic_block_sptr src_block = e->src().block();
- gr_block_sptr src_grblock = cast_to_block_sptr(src_block);
- if (!src_grblock)
- throw std::runtime_error("connect_block_inputs found non-gr_block");
- gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
-
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Setting input " << dst_port << " from edge " << (*e) << std::endl;
-
- detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, grblock->history()-1, grblock));
- }
-}
-
-void
-gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg)
-{
- // Allocate block details if needed. Only new blocks that aren't pruned out
- // by flattening will need one; existing blocks still in the new flowgraph will
- // already have one.
- for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
- gr_block_sptr block = cast_to_block_sptr(*p);
-
- if (!block->detail()) {
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: allocating new detail for block " << (*p) << std::endl;
- block->set_detail(allocate_block_detail(block));
- }
- else
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: reusing original detail for block " << (*p) << std::endl;
- }
-
- // Calculate the old edges that will be going away, and clear the buffer readers
- // on the RHS.
- for (gr_edge_viter_t old_edge = old_ffg->d_edges.begin(); old_edge != old_ffg->d_edges.end(); old_edge++) {
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: testing old edge " << (*old_edge) << "...";
-
- gr_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 (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "not in new edge list" << std::endl;
- // zero the buffer reader on RHS of old edge
- gr_block_sptr block(cast_to_block_sptr(old_edge->dst().block()));
- int port = old_edge->dst().port();
- block->detail()->set_input(port, gr_buffer_reader_sptr());
- }
- else {
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "found in new edge list" << std::endl;
- }
- }
-
- // Now connect inputs to outputs, reusing old buffer readers if they exist
- for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
- gr_block_sptr block = cast_to_block_sptr(*p);
-
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "merge: merging " << (*p) << "...";
-
- if (old_ffg->has_block_p(*p)) {
- // Block exists in old flow graph
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "used in old flow graph" << std::endl;
- gr_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 (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "Checking input " << block << ":" << i << "...";
- gr_edge edge = calc_upstream_edge(*p, i);
-
- // Fish out old buffer reader and see if it matches correct buffer from edge list
- gr_block_sptr src_block = cast_to_block_sptr(edge.src().block());
- gr_block_detail_sptr src_detail = src_block->detail();
- gr_buffer_sptr src_buffer = src_detail->output(edge.src().port());
- gr_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 (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "matched, reusing" << std::endl;
- }
- else {
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "needs a new reader" << std::endl;
-
- // Create new buffer reader and assign
- detail->set_input(i, gr_buffer_add_reader(src_buffer, block->history()-1, block));
- }
- }
- }
- else {
- // Block is new, it just needs buffer readers at this point
- if (GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << "new block" << std::endl;
- connect_block_inputs(block);
-
- // Make sure all buffers are aligned
- setup_buffer_alignment(block);
- }
-
- // Now deal with the fact that the block details might have changed numbers of
- // inputs and outputs vs. in the old flowgraph.
- }
-}
-
-void
-gr_flat_flowgraph::setup_buffer_alignment(gr_block_sptr block)
-{
- const int alignment = volk_get_alignment();
- for(int i = 0; i < block->detail()->ninputs(); i++) {
- void *r = (void*)block->detail()->input(i)->read_pointer();
- unsigned long int ri = (unsigned long int)r % alignment;
- //std::cerr << "reader: " << r << " alignment: " << ri << std::endl;
- if(ri != 0) {
- size_t itemsize = block->detail()->input(i)->get_sizeof_item();
- block->detail()->input(i)->update_read_pointer(alignment-ri/itemsize);
- }
- block->set_unaligned(0);
- block->set_is_unaligned(false);
- }
-
- for(int i = 0; i < block->detail()->noutputs(); i++) {
- void *w = (void*)block->detail()->output(i)->write_pointer();
- unsigned long int wi = (unsigned long int)w % alignment;
- //std::cerr << "writer: " << w << " alignment: " << wi << std::endl;
- if(wi != 0) {
- size_t itemsize = block->detail()->output(i)->get_sizeof_item();
- block->detail()->output(i)->update_write_pointer(alignment-wi/itemsize);
- }
- block->set_unaligned(0);
- block->set_is_unaligned(false);
- }
-}
-
-std::string
-gr_flat_flowgraph::edge_list()
-{
- std::stringstream s;
- for(gr_edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++)
- s << (*e) << std::endl;
- return s.str();
-}
-
-void gr_flat_flowgraph::dump()
-{
- for (gr_edge_viter_t e = d_edges.begin(); e != d_edges.end(); e++)
- std::cout << " edge: " << (*e) << std::endl;
-
- for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
- std::cout << " block: " << (*p) << std::endl;
- gr_block_detail_sptr detail = cast_to_block_sptr(*p)->detail();
- std::cout << " detail @" << detail << ":" << std::endl;
-
- int ni = detail->ninputs();
- int no = detail->noutputs();
- for (int i = 0; i < no; i++) {
- gr_buffer_sptr buffer = detail->output(i);
- std::cout << " output " << i << ": " << buffer << std::endl;
- }
-
- for (int i = 0; i < ni; i++) {
- gr_buffer_reader_sptr reader = detail->input(i);
- std::cout << " reader " << i << ": " << reader
- << " reading from buffer=" << reader->buffer() << std::endl;
- }
- }
-
-}
-
-gr_block_vector_t
-gr_flat_flowgraph::make_block_vector(gr_basic_block_vector_t &blocks)
-{
- gr_block_vector_t result;
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- result.push_back(cast_to_block_sptr(*p));
- }
-
- return result;
-}
-
-
-void gr_flat_flowgraph::clear_endpoint(const gr_msg_endpoint &e, bool is_src){
- for(size_t i=0; i<d_msg_edges.size(); i++){
- if(is_src){
- if(d_msg_edges[i].src() == e){
- d_msg_edges.erase(d_msg_edges.begin() + i);
- i--;
- }
- } else {
- if(d_msg_edges[i].dst() == e){
- d_msg_edges.erase(d_msg_edges.begin() + i);
- i--;
- }
- }
- }
-}
-
-void gr_flat_flowgraph::replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src){
- size_t n_replr(0);
- if(GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("gr_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(GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block();
- d_msg_edges.push_back( gr_msg_edge(r, d_msg_edges[i].dst() ) );
- n_replr++;
- }
- } else {
- if(d_msg_edges[i].dst() == e){
- if(GR_FLAT_FLOWGRAPH_DEBUG)
- std::cout << boost::format("gr_flat_flowgraph::replace_endpoint() flattening to ( %s, %s )\n") % r.block()% d_msg_edges[i].dst().block();
- d_msg_edges.push_back( gr_msg_edge(d_msg_edges[i].src(), r ) );
- n_replr++;
- }
- }
- }
-}
-
-void
-gr_flat_flowgraph::enable_pc_rpc()
-{
-#ifdef GR_PERFORMANCE_COUNTERS
- if(gr_prefs::singleton()->get_bool("PerfCounters", "on", false)) {
- gr_basic_block_viter_t p;
- for(p = d_blocks.begin(); p != d_blocks.end(); p++) {
- gr_block_sptr block = cast_to_block_sptr(*p);
- if(!block->is_pc_rpc_set())
- block->setup_pc_rpc();
- }
- }
-#endif /* GR_PERFORMANCE_COUNTERS */
-}
diff --git a/gnuradio-runtime/lib/gr_flat_flowgraph.h b/gnuradio-runtime/lib/gr_flat_flowgraph.h
deleted file mode 100644
index 9c47a77e23..0000000000
--- a/gnuradio-runtime/lib/gr_flat_flowgraph.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,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 (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_FLAT_FLOWGRAPH_H
-#define INCLUDED_GR_FLAT_FLOWGRAPH_H
-
-#include <gr_runtime_api.h>
-#include <gr_flowgraph.h>
-#include <gr_block.h>
-
-// Create a shared pointer to a heap allocated gr_flat_flowgraph
-// (types defined in gr_runtime_types.h)
-GR_RUNTIME_API gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
-
-/*!
- *\brief Class specializing gr_flat_flowgraph that has all nodes
- * as gr_blocks, with no hierarchy
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_flat_flowgraph : public gr_flowgraph
-{
-public:
- friend GR_RUNTIME_API gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
-
- // Destruct an arbitrary gr_flat_flowgraph
- ~gr_flat_flowgraph();
-
- // Wire gr_blocks together in new flat_flowgraph
- void setup_connections();
-
- // Merge applicable connections from existing flat flowgraph
- void merge_connections(gr_flat_flowgraph_sptr sfg);
-
- // Return a string list of edges
- std::string edge_list();
-
- void dump();
-
- /*!
- * Make a vector of gr_block from a vector of gr_basic_block
- */
- static gr_block_vector_t make_block_vector(gr_basic_block_vector_t &blocks);
-
- void replace_endpoint(const gr_msg_endpoint &e, const gr_msg_endpoint &r, bool is_src);
- void clear_endpoint(const gr_msg_endpoint &e, bool is_src);
-
- /*!
- * Enables export of perf. counters to ControlPort on all blocks in
- * the flowgraph.
- */
- void enable_pc_rpc();
-
-private:
- gr_flat_flowgraph();
-
- gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block);
- gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port);
- void connect_block_inputs(gr_basic_block_sptr block);
-
- /* When reusing a flowgraph's blocks, this call makes sure all of the
- * buffer's are aligned at the machine's alignment boundary and tells
- * the blocks that they are aligned.
- *
- * Called from both setup_connections and merge_connections for
- * start and restarts.
- */
- void setup_buffer_alignment(gr_block_sptr block);
-};
-
-#endif /* INCLUDED_GR_FLAT_FLOWGRAPH_H */
diff --git a/gnuradio-runtime/lib/gr_flowgraph.cc b/gnuradio-runtime/lib/gr_flowgraph.cc
deleted file mode 100644
index 28cd693171..0000000000
--- a/gnuradio-runtime/lib/gr_flowgraph.cc
+++ /dev/null
@@ -1,514 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 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 <gr_flowgraph.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-#include <sstream>
-#include <iterator>
-
-#define GR_FLOWGRAPH_DEBUG 0
-
-gr_edge::~gr_edge()
-{
-}
-
-gr_flowgraph_sptr gr_make_flowgraph()
-{
- return gr_flowgraph_sptr(new gr_flowgraph());
-}
-
-gr_flowgraph::gr_flowgraph()
-{
-}
-
-gr_flowgraph::~gr_flowgraph()
-{
-}
-
-template<class T>
-static
-std::vector<T>
-unique_vector(std::vector<T> v)
-{
- std::vector<T> result;
- std::insert_iterator<std::vector<T> > inserter(result, result.begin());
-
- sort(v.begin(), v.end());
- unique_copy(v.begin(), v.end(), inserter);
- return result;
-}
-
-void
-gr_flowgraph::connect(const gr_endpoint &src, const gr_endpoint &dst)
-{
- check_valid_port(src.block()->output_signature(), src.port());
- check_valid_port(dst.block()->input_signature(), dst.port());
- check_dst_not_used(dst);
- check_type_match(src, dst);
-
- // All ist klar, Herr Kommisar
- d_edges.push_back(gr_edge(src,dst));
-}
-
-void
-gr_flowgraph::disconnect(const gr_endpoint &src, const gr_endpoint &dst)
-{
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
- if (src == p->src() && dst == p->dst()) {
- d_edges.erase(p);
- return;
- }
- }
-
- std::stringstream msg;
- msg << "cannot disconnect edge " << gr_edge(src, dst) << ", not found";
- throw std::invalid_argument(msg.str());
-}
-
-void
-gr_flowgraph::validate()
-{
- d_blocks = calc_used_blocks();
-
- for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
- std::vector<int> used_ports;
- int ninputs, noutputs;
-
- if (GR_FLOWGRAPH_DEBUG)
- std::cout << "Validating block: " << (*p) << std::endl;
-
- used_ports = calc_used_ports(*p, true); // inputs
- ninputs = used_ports.size();
- check_contiguity(*p, used_ports, true); // inputs
-
- used_ports = calc_used_ports(*p, false); // outputs
- noutputs = used_ports.size();
- check_contiguity(*p, used_ports, false); // outputs
-
- if (!((*p)->check_topology(ninputs, noutputs))) {
- std::stringstream msg;
- msg << "check topology failed on " << (*p)
- << " using ninputs=" << ninputs
- << ", noutputs=" << noutputs;
- throw std::runtime_error(msg.str());
- }
- }
-}
-
-void
-gr_flowgraph::clear()
-{
- // Boost shared pointers will deallocate as needed
- d_blocks.clear();
- d_edges.clear();
-}
-
-void
-gr_flowgraph::check_valid_port(gr_io_signature_sptr sig, int port)
-{
- std::stringstream msg;
-
- if (port < 0) {
- msg << "negative port number " << port << " is invalid";
- throw std::invalid_argument(msg.str());
- }
-
- int max = sig->max_streams();
- if (max != gr_io_signature::IO_INFINITE && port >= max) {
- msg << "port number " << port << " exceeds max of ";
- if (max == 0)
- msg << "(none)";
- else
- msg << max-1;
- throw std::invalid_argument(msg.str());
- }
-}
-
-void
-gr_flowgraph::check_valid_port(const gr_msg_endpoint &e)
-{
- if (GR_FLOWGRAPH_DEBUG)
- std::cout << "check_valid_port( " << e.block() << ", " << e.port() << ")\n";
-
- if(!e.block()->has_msg_port(e.port()))
- throw std::invalid_argument("invalid msg port in connect() or disconnect()");
-}
-
-void
-gr_flowgraph::check_dst_not_used(const gr_endpoint &dst)
-{
- // A destination is in use if it is already on the edge list
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
- if (p->dst() == dst) {
- std::stringstream msg;
- msg << "destination already in use by edge " << (*p);
- throw std::invalid_argument(msg.str());
- }
-}
-
-void
-gr_flowgraph::check_type_match(const gr_endpoint &src, const gr_endpoint &dst)
-{
- int src_size = src.block()->output_signature()->sizeof_stream_item(src.port());
- int dst_size = dst.block()->input_signature()->sizeof_stream_item(dst.port());
-
- if (src_size != dst_size) {
- std::stringstream msg;
- msg << "itemsize mismatch: " << src << " using " << src_size
- << ", " << dst << " using " << dst_size;
- throw std::invalid_argument(msg.str());
- }
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::calc_used_blocks()
-{
- gr_basic_block_vector_t tmp;
-
- // make sure free standing message blocks are included
- for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
-// for now only blocks receiving messages get a thread context - uncomment to allow senders to also obtain one
-// tmp.push_back(p->src().block());
- tmp.push_back(p->dst().block());
- }
-
- // Collect all blocks in the edge list
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
- tmp.push_back(p->src().block());
- tmp.push_back(p->dst().block());
- }
-
- return unique_vector<gr_basic_block_sptr>(tmp);
-}
-
-std::vector<int>
-gr_flowgraph::calc_used_ports(gr_basic_block_sptr block, bool check_inputs)
-{
- std::vector<int> tmp;
-
- // Collect all seen ports
- gr_edge_vector_t edges = calc_connections(block, check_inputs);
- for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
- if (check_inputs == true)
- tmp.push_back(p->dst().port());
- else
- tmp.push_back(p->src().port());
- }
-
- return unique_vector<int>(tmp);
-}
-
-gr_edge_vector_t
-gr_flowgraph::calc_connections(gr_basic_block_sptr block, bool check_inputs)
-{
- gr_edge_vector_t result;
-
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
- if (check_inputs) {
- if (p->dst().block() == block)
- result.push_back(*p);
- }
- else {
- if (p->src().block() == block)
- result.push_back(*p);
- }
- }
-
- return result; // assumes no duplicates
-}
-
-void
-gr_flowgraph::check_contiguity(gr_basic_block_sptr block,
- const std::vector<int> &used_ports,
- bool check_inputs)
-{
- std::stringstream msg;
-
- gr_io_signature_sptr sig =
- check_inputs ? block->input_signature() : block->output_signature();
-
- int nports = used_ports.size();
- int min_ports = sig->min_streams();
- int max_ports = sig->max_streams();
-
- if (nports == 0 && min_ports == 0)
- return;
-
- if (nports < min_ports) {
- msg << block << ": insufficient connected "
- << (check_inputs ? "input ports " : "output ports ")
- << "(" << min_ports << " needed, " << nports << " connected)";
- throw std::runtime_error(msg.str());
- }
-
- if (nports > max_ports && max_ports != gr_io_signature::IO_INFINITE) {
- msg << block << ": too many connected "
- << (check_inputs ? "input ports " : "output ports ")
- << "(" << max_ports << " allowed, " << nports << " connected)";
- throw std::runtime_error(msg.str());
- }
-
- if (used_ports[nports-1]+1 != nports) {
- for (int i = 0; i < nports; i++) {
- if (used_ports[i] != i) {
- msg << block << ": missing connection "
- << (check_inputs ? "to input port " : "from output port ")
- << i;
- throw std::runtime_error(msg.str());
- }
- }
- }
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block, int port)
-{
- gr_basic_block_vector_t tmp;
-
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
- if (p->src() == gr_endpoint(block, port))
- tmp.push_back(p->dst().block());
-
- return unique_vector<gr_basic_block_sptr>(tmp);
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block)
-{
- gr_basic_block_vector_t tmp;
-
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
- if (p->src().block() == block)
- tmp.push_back(p->dst().block());
-
- return unique_vector<gr_basic_block_sptr>(tmp);
-}
-
-gr_edge_vector_t
-gr_flowgraph::calc_upstream_edges(gr_basic_block_sptr block)
-{
- gr_edge_vector_t result;
-
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
- if (p->dst().block() == block)
- result.push_back(*p);
-
- return result; // Assume no duplicates
-}
-
-bool
-gr_flowgraph::has_block_p(gr_basic_block_sptr block)
-{
- gr_basic_block_viter_t result;
- result = std::find(d_blocks.begin(), d_blocks.end(), block);
- return (result != d_blocks.end());
-}
-
-gr_edge
-gr_flowgraph::calc_upstream_edge(gr_basic_block_sptr block, int port)
-{
- gr_edge result;
-
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
- if (p->dst() == gr_endpoint(block, port)) {
- result = (*p);
- break;
- }
- }
-
- return result;
-}
-
-std::vector<gr_basic_block_vector_t>
-gr_flowgraph::partition()
-{
- std::vector<gr_basic_block_vector_t> result;
- gr_basic_block_vector_t blocks = calc_used_blocks();
- gr_basic_block_vector_t graph;
-
- while (blocks.size() > 0) {
- graph = calc_reachable_blocks(blocks[0], blocks);
- assert(graph.size());
- result.push_back(topological_sort(graph));
-
- for (gr_basic_block_viter_t p = graph.begin(); p != graph.end(); p++)
- blocks.erase(find(blocks.begin(), blocks.end(), *p));
- }
-
- return result;
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
-{
- gr_basic_block_vector_t result;
-
- // Mark all blocks as unvisited
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
- (*p)->set_color(gr_basic_block::WHITE);
-
- // Recursively mark all reachable blocks
- reachable_dfs_visit(block, blocks);
-
- // Collect all the blocks that have been visited
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
- if ((*p)->color() == gr_basic_block::BLACK)
- result.push_back(*p);
-
- return result;
-}
-
-// Recursively mark all reachable blocks from given block and block list
-void
-gr_flowgraph::reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
-{
- // Mark the current one as visited
- block->set_color(gr_basic_block::BLACK);
-
- // Recurse into adjacent vertices
- gr_basic_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
-
- for (gr_basic_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
- if ((*p)->color() == gr_basic_block::WHITE)
- reachable_dfs_visit(*p, blocks);
-}
-
-// Return a list of block adjacent to a given block along any edge
-gr_basic_block_vector_t
-gr_flowgraph::calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks)
-{
- gr_basic_block_vector_t tmp;
-
- // Find any blocks that are inputs or outputs
- for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
- if (p->src().block() == block)
- tmp.push_back(p->dst().block());
- if (p->dst().block() == block)
- tmp.push_back(p->src().block());
- }
-
- return unique_vector<gr_basic_block_sptr>(tmp);
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::topological_sort(gr_basic_block_vector_t &blocks)
-{
- gr_basic_block_vector_t tmp;
- gr_basic_block_vector_t result;
- tmp = sort_sources_first(blocks);
-
- // Start 'em all white
- for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++)
- (*p)->set_color(gr_basic_block::WHITE);
-
- for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
- if ((*p)->color() == gr_basic_block::WHITE)
- topological_dfs_visit(*p, result);
- }
-
- reverse(result.begin(), result.end());
- return result;
-}
-
-gr_basic_block_vector_t
-gr_flowgraph::sort_sources_first(gr_basic_block_vector_t &blocks)
-{
- gr_basic_block_vector_t sources, nonsources, result;
-
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- if (source_p(*p))
- sources.push_back(*p);
- else
- nonsources.push_back(*p);
- }
-
- for (gr_basic_block_viter_t p = sources.begin(); p != sources.end(); p++)
- result.push_back(*p);
-
- for (gr_basic_block_viter_t p = nonsources.begin(); p != nonsources.end(); p++)
- result.push_back(*p);
-
- return result;
-}
-
-bool
-gr_flowgraph::source_p(gr_basic_block_sptr block)
-{
- return (calc_upstream_edges(block).size() == 0);
-}
-
-void
-gr_flowgraph::topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output)
-{
- block->set_color(gr_basic_block::GREY);
- gr_basic_block_vector_t blocks(calc_downstream_blocks(block));
-
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- switch ((*p)->color()) {
- case gr_basic_block::WHITE:
- topological_dfs_visit(*p, output);
- break;
-
- case gr_basic_block::GREY:
- throw std::runtime_error("flow graph has loops!");
-
- case gr_basic_block::BLACK:
- continue;
-
- default:
- throw std::runtime_error("invalid color on block!");
- }
- }
-
- block->set_color(gr_basic_block::BLACK);
- output.push_back(block);
-}
-
-void gr_flowgraph::connect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){
- check_valid_port(src);
- check_valid_port(dst);
- for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
- if(p->src() == src && p->dst() == dst){
- throw std::runtime_error("connect called on already connected edge!");
- }
- }
- d_msg_edges.push_back(gr_msg_edge(src,dst));
-}
-
-void gr_flowgraph::disconnect(const gr_msg_endpoint &src, const gr_msg_endpoint &dst){
- check_valid_port(src);
- check_valid_port(dst);
- for (gr_msg_edge_viter_t p = d_msg_edges.begin(); p != d_msg_edges.end(); p++) {
- if(p->src() == src && p->dst() == dst){
- d_msg_edges.erase(p);
- return;
- }
- }
- throw std::runtime_error("disconnect called on non-connected edge!");
-}
-
-
diff --git a/gnuradio-runtime/lib/gr_hier_block2.cc b/gnuradio-runtime/lib/gr_hier_block2.cc
deleted file mode 100644
index 9e924fdaf5..0000000000
--- a/gnuradio-runtime/lib/gr_hier_block2.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2007,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_hier_block2.h>
-#include <gr_io_signature.h>
-#include <gr_hier_block2_detail.h>
-#include <iostream>
-
-#define GR_HIER_BLOCK2_DEBUG 0
-
-
-gr_hier_block2_sptr
-gr_make_hier_block2(const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature)
-{
- return gnuradio::get_initial_sptr(new gr_hier_block2(name, input_signature, output_signature));
-}
-
-gr_hier_block2::gr_hier_block2(const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature)
- : gr_basic_block(name, input_signature, output_signature),
- d_detail(new gr_hier_block2_detail(this)),
- hier_message_ports_in(pmt::PMT_NIL),
- hier_message_ports_out(pmt::PMT_NIL)
-{
- // This bit of magic ensures that self() works in the constructors of derived classes.
- gnuradio::detail::sptr_magic::create_and_stash_initial_sptr(this);
-}
-
-gr_hier_block2::~gr_hier_block2()
-{
- delete d_detail;
-}
-
-gr_hier_block2::opaque_self
-gr_hier_block2::self()
-{
- return shared_from_this();
-}
-
-gr_hier_block2_sptr
-gr_hier_block2::to_hier_block2()
-{
- return cast_to_hier_block2_sptr(shared_from_this());
-}
-
-void
-gr_hier_block2::connect(gr_basic_block_sptr block)
-{
- d_detail->connect(block);
-}
-
-void
-gr_hier_block2::connect(gr_basic_block_sptr src, int src_port,
- gr_basic_block_sptr dst, int dst_port)
-{
- d_detail->connect(src, src_port, dst, dst_port);
-}
-
-void
-gr_hier_block2::msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport)
-{
- if(!pmt::is_symbol(srcport)){throw std::runtime_error("bad port id"); }
- d_detail->msg_connect(src, srcport, dst, dstport);
-}
-
-void
-gr_hier_block2::msg_connect(gr_basic_block_sptr src, std::string srcport,
- gr_basic_block_sptr dst, std::string dstport)
-{
- d_detail->msg_connect(src, pmt::mp(srcport), dst, pmt::mp(dstport));
-}
-
-void
-gr_hier_block2::msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport)
-{
- if(!pmt::is_symbol(srcport)){throw std::runtime_error("bad port id"); }
- d_detail->msg_disconnect(src, srcport, dst, dstport);
-}
-
-void
-gr_hier_block2::msg_disconnect(gr_basic_block_sptr src, std::string srcport,
- gr_basic_block_sptr dst, std::string dstport)
-{
- d_detail->msg_disconnect(src, pmt::mp(srcport), dst, pmt::mp(dstport));
-}
-
-void
-gr_hier_block2::disconnect(gr_basic_block_sptr block)
-{
- d_detail->disconnect(block);
-}
-
-void
-gr_hier_block2::disconnect(gr_basic_block_sptr src, int src_port,
- gr_basic_block_sptr dst, int dst_port)
-{
- d_detail->disconnect(src, src_port, dst, dst_port);
-}
-
-void
-gr_hier_block2::disconnect_all()
-{
- d_detail->disconnect_all();
-}
-
-void
-gr_hier_block2::lock()
-{
- d_detail->lock();
-}
-
-void
-gr_hier_block2::unlock()
-{
- d_detail->unlock();
-}
-
-
-gr_flat_flowgraph_sptr
-gr_hier_block2::flatten() const
-{
- gr_flat_flowgraph_sptr new_ffg = gr_make_flat_flowgraph();
- d_detail->flatten_aux(new_ffg);
- return new_ffg;
-}
diff --git a/gnuradio-runtime/lib/gr_hier_block2_detail.cc b/gnuradio-runtime/lib/gr_hier_block2_detail.cc
deleted file mode 100644
index c8564f6698..0000000000
--- a/gnuradio-runtime/lib/gr_hier_block2_detail.cc
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright 2006,2007,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 <gr_hier_block2_detail.h>
-#include <gr_io_signature.h>
-#include <gr_prefs.h>
-#include <stdexcept>
-#include <sstream>
-#include <boost/format.hpp>
-
-#define GR_HIER_BLOCK2_DETAIL_DEBUG 0
-
-gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
- d_owner(owner),
- d_parent_detail(0),
- d_fg(gr_make_flowgraph())
-{
- int min_inputs = owner->input_signature()->min_streams();
- int max_inputs = owner->input_signature()->max_streams();
- int min_outputs = owner->output_signature()->min_streams();
- int max_outputs = owner->output_signature()->max_streams();
-
- if (max_inputs == gr_io_signature::IO_INFINITE ||
- max_outputs == gr_io_signature::IO_INFINITE ||
- (min_inputs != max_inputs) ||(min_outputs != max_outputs) ) {
- std::stringstream msg;
- msg << "Hierarchical blocks do not yet support arbitrary or"
- << " variable numbers of inputs or outputs (" << d_owner->name() << ")";
- throw std::runtime_error(msg.str());
- }
-
- d_inputs = std::vector<gr_endpoint_vector_t>(max_inputs);
- d_outputs = gr_endpoint_vector_t(max_outputs);
-}
-
-
-gr_hier_block2_detail::~gr_hier_block2_detail()
-{
- d_owner = 0; // Don't use delete, we didn't allocate
-}
-
-void
-gr_hier_block2_detail::connect(gr_basic_block_sptr block)
-{
- std::stringstream msg;
-
- // Check if duplicate
- if (std::find(d_blocks.begin(), d_blocks.end(), block) != d_blocks.end()) {
- msg << "Block " << block << " already connected.";
- throw std::invalid_argument(msg.str());
- }
-
- // Check if has inputs or outputs
- if (block->input_signature()->max_streams() != 0 ||
- block->output_signature()->max_streams() != 0) {
- msg << "Block " << block << " must not have any input or output ports";
- throw std::invalid_argument(msg.str());
- }
-
- gr_hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
-
- if (hblock && hblock.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connect: block is hierarchical, setting parent to " << this << std::endl;
- hblock->d_detail->d_parent_detail = this;
- }
-
- d_blocks.push_back(block);
-}
-
-void
-gr_hier_block2_detail::connect(gr_basic_block_sptr src, int src_port,
- gr_basic_block_sptr dst, int dst_port)
-{
- std::stringstream msg;
-
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connecting: " << gr_endpoint(src, src_port)
- << " -> " << gr_endpoint(dst, dst_port) << std::endl;
-
- if (src.get() == dst.get())
- throw std::invalid_argument("connect: src and destination blocks cannot be the same");
-
- gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
- gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
-
- if (src_block && src.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
- src_block->d_detail->d_parent_detail = this;
- }
-
- if (dst_block && dst.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
- dst_block->d_detail->d_parent_detail = this;
- }
-
- // Connections to block inputs or outputs
- int max_port;
- if (src.get() == d_owner) {
- max_port = src->input_signature()->max_streams();
- if ((max_port != -1 && (src_port >= max_port)) || src_port < 0) {
- msg << "source port " << src_port << " out of range for " << src;
- throw std::invalid_argument(msg.str());
- }
-
- return connect_input(src_port, dst_port, dst);
- }
-
- if (dst.get() == d_owner) {
- max_port = dst->output_signature()->max_streams();
- if ((max_port != -1 && (dst_port >= max_port)) || dst_port < 0) {
- msg << "destination port " << dst_port << " out of range for " << dst;
- throw std::invalid_argument(msg.str());
- }
-
- return connect_output(dst_port, src_port, src);
- }
-
- // Internal connections
- d_fg->connect(src, src_port, dst, dst_port);
-
- // TODO: connects to NC
-}
-
-void
-gr_hier_block2_detail::msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport)
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connecting message port..." << std::endl;
-
- // register the subscription
-// this is done later...
-// src->message_port_sub(srcport, pmt::cons(dst->alias_pmt(), dstport));
-
- // add block uniquely to list to internal blocks
- if (std::find(d_blocks.begin(), d_blocks.end(), dst) == d_blocks.end()){
- d_blocks.push_back(src);
- d_blocks.push_back(dst);
- }
-
- bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
- bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
-
- gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
- gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
-
- if (src_block && src.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
- src_block->d_detail->d_parent_detail = this;
- }
-
- if (dst_block && dst.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
- dst_block->d_detail->d_parent_detail = this;
- }
-
- // add edge for this message connection
- if(GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << boost::format("connect( (%s, %s, %d), (%s, %s, %d) )\n") %
- src % srcport % hier_out %
- dst % dstport % hier_in;
- d_fg->connect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in));
-}
-
-void
-gr_hier_block2_detail::msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport)
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnecting message port..." << std::endl;
-
- // unregister the subscription - if already subscribed
- src->message_port_unsub(srcport, pmt::cons(dst->alias_pmt(), dstport));
-
- // remove edge for this message connection
- bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
- bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
- d_fg->disconnect( gr_msg_endpoint(src, srcport, hier_out), gr_msg_endpoint(dst, dstport, hier_in));
-}
-
-void
-gr_hier_block2_detail::disconnect(gr_basic_block_sptr block)
-{
- // Check on singleton list
- for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
- if (*p == block) {
- d_blocks.erase(p);
-
- gr_hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
- if (block && block.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnect: block is hierarchical, clearing parent" << std::endl;
- hblock->d_detail->d_parent_detail = 0;
- }
-
- return;
- }
- }
-
- // Otherwise find all edges containing block
- gr_edge_vector_t edges, tmp = d_fg->edges();
- gr_edge_vector_t::iterator p;
- for (p = tmp.begin(); p != tmp.end(); p++) {
- if ((*p).src().block() == block || (*p).dst().block() == block) {
- edges.push_back(*p);
-
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnect: block found in edge " << (*p) << std::endl;
- }
- }
-
- if (edges.size() == 0) {
- std::stringstream msg;
- msg << "cannot disconnect block " << block << ", not found";
- throw std::invalid_argument(msg.str());
- }
-
- for (p = edges.begin(); p != edges.end(); p++) {
- disconnect((*p).src().block(), (*p).src().port(),
- (*p).dst().block(), (*p).dst().port());
- }
-}
-
-void
-gr_hier_block2_detail::disconnect(gr_basic_block_sptr src, int src_port,
- gr_basic_block_sptr dst, int dst_port)
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnecting: " << gr_endpoint(src, src_port)
- << " -> " << gr_endpoint(dst, dst_port) << std::endl;
-
- if (src.get() == dst.get())
- throw std::invalid_argument("disconnect: source and destination blocks cannot be the same");
-
- gr_hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
- gr_hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
-
- if (src_block && src.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnect: src is hierarchical, clearing parent" << std::endl;
- src_block->d_detail->d_parent_detail = 0;
- }
-
- if (dst_block && dst.get() != d_owner) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "disconnect: dst is hierarchical, clearing parent" << std::endl;
- dst_block->d_detail->d_parent_detail = 0;
- }
-
- if (src.get() == d_owner)
- return disconnect_input(src_port, dst_port, dst);
-
- if (dst.get() == d_owner)
- return disconnect_output(dst_port, src_port, src);
-
- // Internal connections
- d_fg->disconnect(src, src_port, dst, dst_port);
-}
-
-void
-gr_hier_block2_detail::connect_input(int my_port, int port, gr_basic_block_sptr block)
-{
- std::stringstream msg;
-
- if (my_port < 0 || my_port >= (signed)d_inputs.size()) {
- msg << "input port " << my_port << " out of range for " << block;
- throw std::invalid_argument(msg.str());
- }
-
- gr_endpoint_vector_t &endps = d_inputs[my_port];
- gr_endpoint endp(block, port);
-
- gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
- if (p != endps.end()) {
- msg << "external input port " << my_port << " already wired to " << endp;
- throw std::invalid_argument(msg.str());
- }
-
- endps.push_back(endp);
-}
-
-void
-gr_hier_block2_detail::connect_output(int my_port, int port, gr_basic_block_sptr block)
-{
- std::stringstream msg;
-
- if (my_port < 0 || my_port >= (signed)d_outputs.size()) {
- msg << "output port " << my_port << " out of range for " << block;
- throw std::invalid_argument(msg.str());
- }
-
- if (d_outputs[my_port].block()) {
- msg << "external output port " << my_port << " already connected from "
- << d_outputs[my_port];
- throw std::invalid_argument(msg.str());
- }
-
- d_outputs[my_port] = gr_endpoint(block, port);
-}
-
-void
-gr_hier_block2_detail::disconnect_input(int my_port, int port, gr_basic_block_sptr block)
-{
- std::stringstream msg;
-
- if (my_port < 0 || my_port >= (signed)d_inputs.size()) {
- msg << "input port number " << my_port << " out of range for " << block;
- throw std::invalid_argument(msg.str());
- }
-
- gr_endpoint_vector_t &endps = d_inputs[my_port];
- gr_endpoint endp(block, port);
-
- gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
- if (p == endps.end()) {
- msg << "external input port " << my_port << " not connected to " << endp;
- throw std::invalid_argument(msg.str());
- }
-
- endps.erase(p);
-}
-
-void
-gr_hier_block2_detail::disconnect_output(int my_port, int port, gr_basic_block_sptr block)
-{
- std::stringstream msg;
-
- if (my_port < 0 || my_port >= (signed)d_outputs.size()) {
- msg << "output port number " << my_port << " out of range for " << block;
- throw std::invalid_argument(msg.str());
- }
-
- if (d_outputs[my_port].block() != block) {
- msg << "block " << block << " not assigned to output "
- << my_port << ", can't disconnect";
- throw std::invalid_argument(msg.str());
- }
-
- d_outputs[my_port] = gr_endpoint();
-}
-
-gr_endpoint_vector_t
-gr_hier_block2_detail::resolve_port(int port, bool is_input)
-{
- std::stringstream msg;
-
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Resolving port " << port << " as an "
- << (is_input ? "input" : "output")
- << " of " << d_owner->name() << std::endl;
-
- gr_endpoint_vector_t result;
-
- if (is_input) {
- if (port < 0 || port >= (signed)d_inputs.size()) {
- msg << "resolve_port: hierarchical block '" << d_owner->name()
- << "': input " << port << " is out of range";
- throw std::runtime_error(msg.str());
- }
-
- if (d_inputs[port].empty()) {
- msg << "resolve_port: hierarchical block '" << d_owner->name()
- << "': input " << port << " is not connected internally";
- throw std::runtime_error(msg.str());
- }
-
- gr_endpoint_vector_t &endps = d_inputs[port];
- gr_endpoint_viter_t p;
- for (p = endps.begin(); p != endps.end(); p++) {
- gr_endpoint_vector_t tmp = resolve_endpoint(*p, true);
- std::copy(tmp.begin(), tmp.end(), back_inserter(result));
- }
- }
- else {
- if (port < 0 || port >= (signed)d_outputs.size()) {
- msg << "resolve_port: hierarchical block '" << d_owner->name()
- << "': output " << port << " is out of range";
- throw std::runtime_error(msg.str());
- }
-
- if (d_outputs[port] == gr_endpoint()) {
- msg << "resolve_port: hierarchical block '" << d_owner->name()
- << "': output " << port << " is not connected internally";
- throw std::runtime_error(msg.str());
- }
-
- result = resolve_endpoint(d_outputs[port], false);
- }
-
- if (result.empty()) {
- msg << "resolve_port: hierarchical block '" << d_owner->name()
- << "': unable to resolve "
- << (is_input ? "input port " : "output port ")
- << port;
- throw std::runtime_error(msg.str());
- }
-
- return result;
-}
-
-void
-gr_hier_block2_detail::disconnect_all()
-{
- d_fg->clear();
- d_blocks.clear();
- d_inputs.clear();
- d_outputs.clear();
-}
-
-gr_endpoint_vector_t
-gr_hier_block2_detail::resolve_endpoint(const gr_endpoint &endp, bool is_input) const
-{
- std::stringstream msg;
- gr_endpoint_vector_t result;
-
- // Check if endpoint is a leaf node
- if (cast_to_block_sptr(endp.block())) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Block " << endp.block() << " is a leaf node, returning." << std::endl;
- result.push_back(endp);
- return result;
- }
-
- // Check if endpoint is a hierarchical block
- gr_hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(endp.block()));
- if (hier_block2) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Resolving endpoint " << endp << " as an "
- << (is_input ? "input" : "output")
- << ", recursing" << std::endl;
- return hier_block2->d_detail->resolve_port(endp.port(), is_input);
- }
-
- msg << "unable to resolve" << (is_input ? " input " : " output ")
- << "endpoint " << endp;
- throw std::runtime_error(msg.str());
-}
-
-void
-gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << " ** Flattening " << d_owner->name() << std::endl;
-
- // Add my edges to the flow graph, resolving references to actual endpoints
- gr_edge_vector_t edges = d_fg->edges();
- gr_msg_edge_vector_t msg_edges = d_fg->msg_edges();
- gr_edge_viter_t p;
- gr_msg_edge_viter_t q,u;
-
- // Only run setup_rpc if ControlPort config param is enabled.
- bool ctrlport_on = gr_prefs::singleton()->get_bool("ControlPort", "on", false);
-
- // For every block (gr_block and gr_hier_block2), set up the RPC
- // interface.
- for(p = edges.begin(); p != edges.end(); p++) {
- gr_basic_block_sptr b;
- b = p->src().block();
-
- if(ctrlport_on) {
- if(!b->is_rpc_set()) {
- b->setup_rpc();
- b->rpc_set();
- }
- }
-
- b = p->dst().block();
- if(ctrlport_on) {
- if(!b->is_rpc_set()) {
- b->setup_rpc();
- b->rpc_set();
- }
- }
- }
-
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Flattening stream connections: " << std::endl;
-
- for (p = edges.begin(); p != edges.end(); p++) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Flattening edge " << (*p) << std::endl;
-
- gr_endpoint_vector_t src_endps = resolve_endpoint(p->src(), false);
- gr_endpoint_vector_t dst_endps = resolve_endpoint(p->dst(), true);
-
- gr_endpoint_viter_t s, d;
- for (s = src_endps.begin(); s != src_endps.end(); s++) {
- for (d = dst_endps.begin(); d != dst_endps.end(); d++) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << (*s) << "->" << (*d) << std::endl;
- sfg->connect(*s, *d);
- }
- }
- }
-
- // loop through flattening hierarchical connections
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "Flattening msg connections: " << std::endl;
-
-
- std::vector<std::pair<gr_msg_endpoint, bool> > resolved_endpoints;
- for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << boost::format(" flattening edge ( %s, %s, %d) -> ( %s, %s, %d)\n") % q->src().block() % q->src().port() % q->src().is_hier() % q->dst().block() % q->dst().port() % q->dst().is_hier();
-
- bool normal_connection = true;
-
- // resolve existing connections to hier ports
- if(q->dst().is_hier()){
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << boost::format(" resolve hier output (%s, %s)") % q->dst().block() % q->dst().port() << std::endl;
- sfg->replace_endpoint( q->dst(), q->src(), true );
- resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->dst(),true));
- normal_connection = false;
- }
-
- if(q->src().is_hier()){
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << boost::format(" resolve hier input (%s, %s)") % q->src().block() % q->src().port() << std::endl;
- sfg->replace_endpoint( q->src(), q->dst(), false );
- resolved_endpoints.push_back(std::pair<gr_msg_endpoint, bool>(q->src(),false));
- normal_connection = false;
- }
-
- // propogate non hier connections through
- if(normal_connection){
- sfg->connect( q->src(), q->dst() );
- }
- }
- for(std::vector<std::pair<gr_msg_endpoint, bool> >::iterator it = resolved_endpoints.begin(); it != resolved_endpoints.end(); it++){
- sfg->clear_endpoint( (*it).first, (*it).second );
- }
-
-/* // connect primitive edges in the new fg
- for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
- if( (!q->src().is_hier()) && (!q->dst().is_hier()) ){
- sfg->connect( q->src(), q->dst() );
- } else {
- std::cout << "not connecting hier connection!" << std::endl;
- }
- }*/
-
- // Construct unique list of blocks used either in edges, inputs,
- // outputs, or by themselves. I still hate STL.
- gr_basic_block_vector_t blocks; // unique list of used blocks
- gr_basic_block_vector_t tmp = d_fg->calc_used_blocks();
-
- // First add the list of singleton blocks
- std::vector<gr_basic_block_sptr>::const_iterator b; // Because flatten_aux is const
- for (b = d_blocks.begin(); b != d_blocks.end(); b++)
- tmp.push_back(*b);
-
- // Now add the list of connected input blocks
- std::stringstream msg;
- for (unsigned int i = 0; i < d_inputs.size(); i++) {
- if (d_inputs[i].size() == 0) {
- msg << "In hierarchical block " << d_owner->name() << ", input " << i
- << " is not connected internally";
- throw std::runtime_error(msg.str());
- }
-
- for (unsigned int j = 0; j < d_inputs[i].size(); j++)
- tmp.push_back(d_inputs[i][j].block());
- }
-
- for (unsigned int i = 0; i < d_outputs.size(); i++) {
- gr_basic_block_sptr blk = d_outputs[i].block();
- if (!blk) {
- msg << "In hierarchical block " << d_owner->name() << ", output " << i
- << " is not connected internally";
- throw std::runtime_error(msg.str());
- }
- tmp.push_back(blk);
- }
- sort(tmp.begin(), tmp.end());
-
- std::insert_iterator<gr_basic_block_vector_t> inserter(blocks, blocks.begin());
- unique_copy(tmp.begin(), tmp.end(), inserter);
-
- // Recurse hierarchical children
- for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
- gr_hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(*p));
- if (hier_block2 && (hier_block2.get() != d_owner)) {
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "flatten_aux: recursing into hierarchical block " << hier_block2 << std::endl;
- hier_block2->d_detail->flatten_aux(sfg);
- }
- }
-}
-
-void
-gr_hier_block2_detail::lock()
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "lock: entered in " << this << std::endl;
-
- if (d_parent_detail)
- d_parent_detail->lock();
- else
- d_owner->lock();
-}
-
-void
-gr_hier_block2_detail::unlock()
-{
- if (GR_HIER_BLOCK2_DETAIL_DEBUG)
- std::cout << "unlock: entered in " << this << std::endl;
-
- if (d_parent_detail)
- d_parent_detail->unlock();
- else
- d_owner->unlock();
-}
-
diff --git a/gnuradio-runtime/lib/gr_hier_block2_detail.h b/gnuradio-runtime/lib/gr_hier_block2_detail.h
deleted file mode 100644
index d08fe20ac0..0000000000
--- a/gnuradio-runtime/lib/gr_hier_block2_detail.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2007,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_GR_HIER_BLOCK2_DETAIL_H
-#define INCLUDED_GR_HIER_BLOCK2_DETAIL_H
-
-#include <gr_runtime_api.h>
-#include <gr_hier_block2.h>
-#include <gr_flat_flowgraph.h>
-#include <boost/utility.hpp>
-
-/*!
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_hier_block2_detail : boost::noncopyable
-{
-public:
- gr_hier_block2_detail(gr_hier_block2 *owner);
- ~gr_hier_block2_detail();
-
- void connect(gr_basic_block_sptr block);
- void connect(gr_basic_block_sptr src, int src_port,
- gr_basic_block_sptr dst, int dst_port);
- void msg_connect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport);
- void msg_disconnect(gr_basic_block_sptr src, pmt::pmt_t srcport,
- gr_basic_block_sptr dst, pmt::pmt_t dstport);
- void disconnect(gr_basic_block_sptr block);
- void disconnect(gr_basic_block_sptr, int src_port,
- gr_basic_block_sptr, int dst_port);
- void disconnect_all();
- void lock();
- void unlock();
- void flatten_aux(gr_flat_flowgraph_sptr sfg) const;
-
-private:
-
- // Private implementation data
- gr_hier_block2 *d_owner;
- gr_hier_block2_detail *d_parent_detail;
- gr_flowgraph_sptr d_fg;
- std::vector<gr_endpoint_vector_t> d_inputs; // Multiple internal endpoints per external input
- gr_endpoint_vector_t d_outputs; // Single internal endpoint per external output
- gr_basic_block_vector_t d_blocks;
-
-
- void connect_input(int my_port, int port, gr_basic_block_sptr block);
- void connect_output(int my_port, int port, gr_basic_block_sptr block);
- void disconnect_input(int my_port, int port, gr_basic_block_sptr block);
- void disconnect_output(int my_port, int port, gr_basic_block_sptr block);
-
- gr_endpoint_vector_t resolve_port(int port, bool is_input);
- gr_endpoint_vector_t resolve_endpoint(const gr_endpoint &endp, bool is_input) const;
-};
-
-#endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-runtime/lib/gr_io_signature.cc b/gnuradio-runtime/lib/gr_io_signature.cc
deleted file mode 100644
index 6ac9acd17d..0000000000
--- a/gnuradio-runtime/lib/gr_io_signature.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,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 (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 <gr_io_signature.h>
-#include <stdexcept>
-#include <iostream>
-
-gr_io_signature_sptr
-gr_make_io_signaturev(int min_streams, int max_streams,
- const std::vector<int> &sizeof_stream_items)
-{
- return gr_io_signature_sptr (new gr_io_signature (min_streams, max_streams,
- sizeof_stream_items));
-}
-
-gr_io_signature_sptr
-gr_make_io_signature(int min_streams, int max_streams,
- int sizeof_stream_item)
-{
- std::vector<int> sizeof_items(1);
- sizeof_items[0] = sizeof_stream_item;
- return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
-}
-
-gr_io_signature_sptr
-gr_make_io_signature2(int min_streams, int max_streams,
- int sizeof_stream_item1,
- int sizeof_stream_item2)
-{
- std::vector<int> sizeof_items(2);
- sizeof_items[0] = sizeof_stream_item1;
- sizeof_items[1] = sizeof_stream_item2;
- return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
-}
-
-gr_io_signature_sptr
-gr_make_io_signature3(int min_streams, int max_streams,
- int sizeof_stream_item1,
- int sizeof_stream_item2,
- int sizeof_stream_item3)
-{
- std::vector<int> sizeof_items(3);
- sizeof_items[0] = sizeof_stream_item1;
- sizeof_items[1] = sizeof_stream_item2;
- sizeof_items[2] = sizeof_stream_item3;
- return gr_make_io_signaturev(min_streams, max_streams, sizeof_items);
-}
-
-// ------------------------------------------------------------------------
-
-
-gr_io_signature::gr_io_signature (int min_streams, int max_streams,
- const std::vector<int> &sizeof_stream_items)
-{
- if (min_streams < 0
- || (max_streams != IO_INFINITE && max_streams < min_streams))
- throw std::invalid_argument ("gr_io_signature(1)");
-
- if (sizeof_stream_items.size() < 1)
- throw std::invalid_argument("gr_io_signature(2)");
-
- for (size_t i = 0; i < sizeof_stream_items.size(); i++){
- if (max_streams != 0 && sizeof_stream_items[i] < 1)
- throw std::invalid_argument("gr_io_signature(3)");
- }
-
- d_min_streams = min_streams;
- d_max_streams = max_streams;
- d_sizeof_stream_item = sizeof_stream_items;
-}
-
-gr_io_signature::~gr_io_signature ()
-{
-}
-
-int
-gr_io_signature::sizeof_stream_item (int _index) const
-{
- if (_index < 0)
- throw std::invalid_argument ("gr_io_signature::sizeof_stream_item");
-
- size_t index = _index;
- return d_sizeof_stream_item[std::min(index, d_sizeof_stream_item.size() - 1)];
-}
-
-std::vector<int>
-gr_io_signature::sizeof_stream_items() const
-{
- return d_sizeof_stream_item;
-}
diff --git a/gnuradio-runtime/lib/gr_local_sighandler.cc b/gnuradio-runtime/lib/gr_local_sighandler.cc
deleted file mode 100644
index fb31742e13..0000000000
--- a/gnuradio-runtime/lib/gr_local_sighandler.cc
+++ /dev/null
@@ -1,187 +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 <gr_local_sighandler.h>
-#include <stdexcept>
-#include <stdio.h>
-#include <string.h>
-
-
-gr_local_sighandler::gr_local_sighandler (int signum,
- void (*new_handler)(int))
- : d_signum (signum)
-{
-#ifdef HAVE_SIGACTION
- struct sigaction new_action;
- memset (&new_action, 0, sizeof (new_action));
-
- new_action.sa_handler = new_handler;
- sigemptyset (&new_action.sa_mask);
- new_action.sa_flags = 0;
-
- if (sigaction (d_signum, &new_action, &d_old_action) < 0){
- perror ("sigaction (install new)");
- throw std::runtime_error ("sigaction");
- }
-#endif
-}
-
-gr_local_sighandler::~gr_local_sighandler ()
-{
-#ifdef HAVE_SIGACTION
- if (sigaction (d_signum, &d_old_action, 0) < 0){
- perror ("sigaction (restore old)");
- throw std::runtime_error ("sigaction");
- }
-#endif
-}
-
-void
-gr_local_sighandler::throw_signal (int signum)
-{
- throw gr_signal (signum);
-}
-
-/*
- * Semi-hideous way to may a signal number into a signal name
- */
-
-#define SIGNAME(x) case x: return #x
-
-std::string
-gr_signal::name () const
-{
- char tmp[128];
-
- switch (signal ()){
-#ifdef SIGHUP
- SIGNAME (SIGHUP);
-#endif
-#ifdef SIGINT
- SIGNAME (SIGINT);
-#endif
-#ifdef SIGQUIT
- SIGNAME (SIGQUIT);
-#endif
-#ifdef SIGILL
- SIGNAME (SIGILL);
-#endif
-#ifdef SIGTRAP
- SIGNAME (SIGTRAP);
-#endif
-#ifdef SIGABRT
- SIGNAME (SIGABRT);
-#endif
-#ifdef SIGBUS
- SIGNAME (SIGBUS);
-#endif
-#ifdef SIGFPE
- SIGNAME (SIGFPE);
-#endif
-#ifdef SIGKILL
- SIGNAME (SIGKILL);
-#endif
-#ifdef SIGUSR1
- SIGNAME (SIGUSR1);
-#endif
-#ifdef SIGSEGV
- SIGNAME (SIGSEGV);
-#endif
-#ifdef SIGUSR2
- SIGNAME (SIGUSR2);
-#endif
-#ifdef SIGPIPE
- SIGNAME (SIGPIPE);
-#endif
-#ifdef SIGALRM
- SIGNAME (SIGALRM);
-#endif
-#ifdef SIGTERM
- SIGNAME (SIGTERM);
-#endif
-#ifdef SIGSTKFLT
- SIGNAME (SIGSTKFLT);
-#endif
-#ifdef SIGCHLD
- SIGNAME (SIGCHLD);
-#endif
-#ifdef SIGCONT
- SIGNAME (SIGCONT);
-#endif
-#ifdef SIGSTOP
- SIGNAME (SIGSTOP);
-#endif
-#ifdef SIGTSTP
- SIGNAME (SIGTSTP);
-#endif
-#ifdef SIGTTIN
- SIGNAME (SIGTTIN);
-#endif
-#ifdef SIGTTOU
- SIGNAME (SIGTTOU);
-#endif
-#ifdef SIGURG
- SIGNAME (SIGURG);
-#endif
-#ifdef SIGXCPU
- SIGNAME (SIGXCPU);
-#endif
-#ifdef SIGXFSZ
- SIGNAME (SIGXFSZ);
-#endif
-#ifdef SIGVTALRM
- SIGNAME (SIGVTALRM);
-#endif
-#ifdef SIGPROF
- SIGNAME (SIGPROF);
-#endif
-#ifdef SIGWINCH
- SIGNAME (SIGWINCH);
-#endif
-#ifdef SIGIO
- SIGNAME (SIGIO);
-#endif
-#ifdef SIGPWR
- SIGNAME (SIGPWR);
-#endif
-#ifdef SIGSYS
- SIGNAME (SIGSYS);
-#endif
- default:
-#if defined (HAVE_SNPRINTF)
-#if defined (SIGRTMIN) && defined (SIGRTMAX)
- if (signal () >= SIGRTMIN && signal () <= SIGRTMAX){
- snprintf (tmp, sizeof (tmp), "SIGRTMIN + %d", signal ());
- return tmp;
- }
-#endif
- snprintf (tmp, sizeof (tmp), "SIGNAL %d", signal ());
- return tmp;
-#else
- return "Unknown signal";
-#endif
- }
-}
diff --git a/gnuradio-runtime/lib/gr_logger.cc b/gnuradio-runtime/lib/gr_logger.cc
deleted file mode 100644
index 6da4a6d914..0000000000
--- a/gnuradio-runtime/lib/gr_logger.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2012 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.
- */
-
-/*******************************************************************************
-* Author: Mark Plett
-* Description:
-* The gr_log module wraps the log4cpp library for logging in gnuradio.
-*******************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_logger.h>
-#include <stdexcept>
-#include <algorithm>
-
-#ifdef ENABLE_GR_LOG
-#ifdef HAVE_LOG4CPP
-
-/**************************** BEGIN LOG4CPP HELPERS ***************************/
-/* Logger config class. This is a singleton that controls how log4cpp is configured
- * If watch_period>0 a thread is started to watch teh config file for changes.
- */
-
-// Getters of logger_config
-logger_config&
-logger_config::get_instance(void){
- static logger_config instance;
- return instance;
-};
-
-std::string
-logger_config::get_filename(){
- logger_config& in=get_instance();
- return in.filename;
-};
-
-unsigned int
-logger_config::get_watch_period(){
- logger_config& in=get_instance();
- return in.watch_period;
-};
-
-// Method to watch config file for changes
-void logger_config::watch_file(std::string filename,unsigned int watch_period){
- std::time_t last_write(boost::filesystem::last_write_time(filename));
- std::time_t current_time(0);
- while(true){
- try{
- current_time = boost::filesystem::last_write_time(filename);
- if(current_time>last_write){
- std::cout<<"GNURadio Reloading logger configuration:"<<filename<<std::endl;
- last_write = current_time;
-// Should we wipe out all old configuration or just add the new? Just adding...
-// logger_reset_config();
- logger_load_config(filename);
- };
- boost::this_thread::sleep(boost::posix_time::time_duration(0,0,watch_period,0));
- }
- catch(const boost::thread_interrupted&){
- std::cout<<"GNURadio leaving logger config file watch."<<std::endl;
- break;
- };
- };
-};
-
-// Method to load the confifuration. It only loads if the filename or watch has changed
-void logger_config::load_config(std::string filename,unsigned int watch_period){
- logger_config& instance = get_instance();
-// Only reconfigure if filename or watch has changed
- if(instance.filename!=filename || watch_period!=instance.watch_period){
- instance.filename = filename;
- instance.watch_period = watch_period;
-// Stop any file watching thread
- if(instance.watch_thread!=NULL) stop_watch();
-// Load configuration
- std::cout<<"GNURadio Loading logger configuration:"<<instance.filename<<std::endl;
- logger_load_config(instance.filename);
-// Start watch if required
- if(instance.watch_period>0){
- instance.watch_thread = new boost::thread(watch_file,instance.filename,instance.watch_period);
- }
- };
-};
-
-// Method to stop the watcher thread
-void logger_config::stop_watch(){
- logger_config& instance = get_instance();
- if(instance.watch_thread){
- instance.watch_thread->interrupt();
- instance.watch_thread->join();
- delete(instance.watch_thread);
- instance.watch_thread=NULL;
- };
-};
-
-// Method to reset logger configuration
-void
-logger_config::reset_config(void){
- logger_config& instance = get_instance();
- stop_watch();
- std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories();
- std::vector<log4cpp::Category*>::iterator logger = loggers->begin();
-// We can't destroy categories but we can neuter them by removing all appenders.
- for (;logger!=loggers->end();logger++){
- (*logger)->removeAllAppenders();
- };
- instance.filename=std::string("");
- instance.watch_period=0;
-}
-
-/***************** Functions to call log4cpp methods *************************/
-
-gr_logger_ptr
-logger_get_logger(std::string name)
-{
- if(log4cpp::Category::exists(name)){
- gr_logger_ptr logger = &log4cpp::Category::getInstance(name);
- return logger;
- }
- else
- {
- gr_logger_ptr logger = &log4cpp::Category::getInstance(name);
- logger->setPriority(log4cpp::Priority::NOTSET);
- return logger;
- };
-};
-
-void
-logger_load_config(const std::string &config_filename)
-{
- if(config_filename.size() != 0) {
- try
- {
- log4cpp::PropertyConfigurator::configure(config_filename);
- }
- catch( log4cpp::ConfigureFailure &e )
- {
- std::cout << "Logger config failed :" << e.what() << std::endl;
- }
- };
-}
-
-void
-logger_set_level(gr_logger_ptr logger, const std::string &level)
-{
- std::string nocase = level;
- std::transform(level.begin(), level.end(), nocase.begin(), ::tolower);
-
- if(nocase == "off" || nocase == "notset")
- logger_set_level(logger, log4cpp::Priority::NOTSET);
- else if(nocase == "all" || nocase == "debug")
- logger_set_level(logger, log4cpp::Priority::DEBUG);
- else if(nocase == "info")
- logger_set_level(logger, log4cpp::Priority::INFO);
- else if(nocase == "notice")
- logger_set_level(logger, log4cpp::Priority::NOTICE);
- else if(nocase == "warn")
- logger_set_level(logger, log4cpp::Priority::WARN);
- else if(nocase == "error")
- logger_set_level(logger, log4cpp::Priority::ERROR);
- else if(nocase == "crit")
- logger_set_level(logger, log4cpp::Priority::CRIT);
- else if(nocase == "alert")
- logger_set_level(logger, log4cpp::Priority::ALERT);
- else if(nocase=="fatal")
- logger_set_level(logger, log4cpp::Priority::FATAL);
- else if(nocase == "emerg")
- logger_set_level(logger, log4cpp::Priority::EMERG);
- else
- throw std::runtime_error("logger_set_level: Bad level type.\n");
-}
-
-void
-logger_set_level(gr_logger_ptr logger, log4cpp::Priority::Value level)
-{
- logger->setPriority(level);
-}
-
-void
-logger_get_level(gr_logger_ptr logger, std::string &level)
-{
- log4cpp::Priority::Value levelPtr = logger->getPriority();
- if(levelPtr == log4cpp::Priority::NOTSET) level = "noset";
- if(levelPtr == log4cpp::Priority::DEBUG) level = "debug";
- if(levelPtr == log4cpp::Priority::INFO) level = "info";
- if(levelPtr == log4cpp::Priority::NOTICE) level = "notice";
- if(levelPtr == log4cpp::Priority::WARN) level = "warn";
- if(levelPtr == log4cpp::Priority::ERROR) level = "error";
- if(levelPtr == log4cpp::Priority::CRIT) level = "crit";
- if(levelPtr == log4cpp::Priority::ALERT) level = "alert";
- if(levelPtr == log4cpp::Priority::FATAL) level = "fatal";
- if(levelPtr == log4cpp::Priority::EMERG) level = "emerg";
-};
-
-void
-logger_get_level(gr_logger_ptr logger,log4cpp::Priority::Value level)
-{
- level = logger->getPriority();
-}
-
-void
-logger_add_console_appender(gr_logger_ptr logger,std::string target,std::string pattern)
-{
-
- log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
- log4cpp::Appender* app;
- if(target=="stdout")
- app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cout);
- else
- app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cerr);
-
- layout->setConversionPattern(pattern);
- app->setLayout(layout);
- logger->setAppender(app);
-
-}
-
-void
-logger_add_file_appender(gr_logger_ptr logger,std::string filename,bool append,std::string pattern)
-{
-
- log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
- log4cpp::Appender* app = new
- log4cpp::FileAppender("FileAppender::"+filename,
- filename);
- layout->setConversionPattern(pattern);
- app->setLayout(layout);
- logger->setAppender(app);
-
-}
-
-void
-logger_add_rollingfile_appender(gr_logger_ptr logger,std::string filename,
- size_t filesize,int bkup_index,bool append,mode_t mode,std::string pattern)
-{
- log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
- log4cpp::Appender* app = new
- log4cpp::RollingFileAppender("RollFileAppender::"+filename,filename,filesize,bkup_index,append,mode);
- layout->setConversionPattern(pattern);
- app->setLayout(layout);
- logger->setAppender(app);
-}
-
-std::vector<std::string>
-logger_get_logger_names(void){
- std::vector<std::string> names;
- std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories();
- std::vector<log4cpp::Category*>::iterator logger = loggers->begin();
-
- for (;logger!=loggers->end();logger++){
- names.push_back((*logger)->getName());
- };
- return names;
-
-}
-
-#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){
- GR_CONFIG_AND_WATCH_LOGGER(config_filename,watch_period);
-};
-std::vector<std::string> gr_logger_get_logger_names(void){
- std::vector<std::string> names;
- GR_GET_LOGGER_NAMES(names);
- return names;
-};
-void gr_logger_reset_config(void){
- GR_RESET_CONFIGURATION();
-};
-
-// Remaining capability provided by gr_logger class in gr_logger.h
-
-#endif /* ENABLE_GR_LOGGER */
diff --git a/gnuradio-runtime/lib/gr_message.cc b/gnuradio-runtime/lib/gr_message.cc
deleted file mode 100644
index a99dcd7653..0000000000
--- a/gnuradio-runtime/lib/gr_message.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 <gr_message.h>
-#include <assert.h>
-#include <string.h>
-
-static long s_ncurrently_allocated = 0;
-
-gr_message_sptr
-gr_make_message (long type, double arg1, double arg2, size_t length)
-{
- return gr_message_sptr (new gr_message (type, arg1, arg2, length));
-}
-
-gr_message_sptr
-gr_make_message_from_string(const std::string s, long type, double arg1, double arg2)
-{
- gr_message_sptr m = gr_make_message(type, arg1, arg2, s.size());
- memcpy(m->msg(), s.data(), s.size());
- return m;
-}
-
-
-gr_message::gr_message (long type, double arg1, double arg2, size_t length)
- : d_type(type), d_arg1(arg1), d_arg2(arg2)
-{
- if (length == 0)
- d_buf_start = d_msg_start = d_msg_end = d_buf_end = 0;
- else {
- d_buf_start = new unsigned char [length];
- d_msg_start = d_buf_start;
- d_msg_end = d_buf_end = d_buf_start + length;
- }
- s_ncurrently_allocated++;
-}
-
-gr_message::~gr_message ()
-{
- assert (d_next == 0);
- delete [] d_buf_start;
- d_msg_start = d_msg_end = d_buf_end = 0;
- s_ncurrently_allocated--;
-}
-
-std::string
-gr_message::to_string() const
-{
- return std::string((char *)d_msg_start, length());
-}
-
-long
-gr_message_ncurrently_allocated ()
-{
- return s_ncurrently_allocated;
-}
diff --git a/gnuradio-runtime/lib/gr_misc.cc b/gnuradio-runtime/lib/gr_misc.cc
deleted file mode 100644
index 1ed2a03d7f..0000000000
--- a/gnuradio-runtime/lib/gr_misc.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 <gr_misc.h>
-
-unsigned int
-gr_rounduppow2(unsigned int n)
-{
- int i;
- for (i=0;((n-1)>>i) != 0;i++)
- ;
- return 1<<i;
-}
-
-// ----------------------------------------------------------------
-
-void
-gr_zero_vector(std::vector<float> &v)
-{
- for(unsigned int i=0; i < v.size(); i++)
- v[i] = 0;
-}
-
-void
-gr_zero_vector(std::vector<double> &v)
-{
- for(unsigned int i=0; i < v.size(); i++)
- v[i] = 0;
-}
-
-void
-gr_zero_vector(std::vector<int> &v)
-{
- for(unsigned int i=0; i < v.size(); i++)
- v[i] = 0;
-}
-
-void
-gr_zero_vector(std::vector<gr_complex> &v)
-{
- for(unsigned int i=0; i < v.size(); i++)
- v[i] = 0;
-}
diff --git a/gnuradio-runtime/lib/gr_msg_queue.cc b/gnuradio-runtime/lib/gr_msg_queue.cc
deleted file mode 100644
index 03bbe046a4..0000000000
--- a/gnuradio-runtime/lib/gr_msg_queue.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005,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 <gr_msg_queue.h>
-#include <stdexcept>
-
-gr_msg_queue_sptr
-gr_make_msg_queue(unsigned int limit)
-{
- return gr_msg_queue_sptr (new gr_msg_queue(limit));
-}
-
-gr_msg_queue::gr_msg_queue(unsigned int limit)
- : d_not_empty(), d_not_full(),
- /*d_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
-{
-}
-
-gr_msg_queue::~gr_msg_queue()
-{
- flush ();
-}
-
-void
-gr_msg_queue::insert_tail(gr_message_sptr msg)
-{
- if (msg->d_next)
- throw std::invalid_argument("gr_msg_queue::insert_tail: msg already in queue");
-
- gr::thread::scoped_lock guard(d_mutex);
-
- while (full_p())
- d_not_full.wait(guard);
-
- if (d_tail == 0){
- d_tail = d_head = msg;
- //msg->d_next = 0;
- msg->d_next.reset();
- }
- else {
- d_tail->d_next = msg;
- d_tail = msg;
- //msg->d_next = 0;
- msg->d_next.reset();
- }
- d_count++;
- d_not_empty.notify_one();
-}
-
-gr_message_sptr
-gr_msg_queue::delete_head()
-{
- gr::thread::scoped_lock guard(d_mutex);
- gr_message_sptr m;
-
- while ((m = d_head) == 0)
- d_not_empty.wait(guard);
-
- d_head = m->d_next;
- if (d_head == 0){
- //d_tail = 0;
- d_tail.reset();
- }
-
- d_count--;
- // m->d_next = 0;
- m->d_next.reset();
- d_not_full.notify_one();
- return m;
-}
-
-gr_message_sptr
-gr_msg_queue::delete_head_nowait()
-{
- gr::thread::scoped_lock guard(d_mutex);
- gr_message_sptr m;
-
- if ((m = d_head) == 0){
- //return 0;
- return gr_message_sptr();
- }
-
- d_head = m->d_next;
- if (d_head == 0){
- //d_tail = 0;
- d_tail.reset();
- }
-
- d_count--;
- //m->d_next = 0;
- m->d_next.reset();
- d_not_full.notify_one();
- return m;
-}
-
-void
-gr_msg_queue::flush()
-{
- gr_message_sptr m;
-
- while ((m = delete_head_nowait ()) != 0)
- ;
-}
diff --git a/gnuradio-runtime/lib/gr_preferences.cc b/gnuradio-runtime/lib/gr_preferences.cc
deleted file mode 100644
index a0f5616603..0000000000
--- a/gnuradio-runtime/lib/gr_preferences.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,2010,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 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 <gr_preferences.h>
-#include <gr_sys_paths.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-namespace fs = boost::filesystem;
-
-/*
- * The simplest thing that could possibly work:
- * the key is the filename; the value is the file contents.
- */
-
-static const char *
-pathname (const char *key)
-{
- static fs::path path;
- path = fs::path(gr_appdata_path()) / ".gnuradio" / "prefs" / key;
- return path.string().c_str();
-}
-
-static void
-ensure_dir_path ()
-{
- fs::path path = fs::path(gr_appdata_path()) / ".gnuradio";
- if (!fs::is_directory(path)) fs::create_directory(path);
-
- path = path / "prefs";
- if (!fs::is_directory(path)) fs::create_directory(path);
-}
-
-const char *
-gr_preferences::get (const char *key)
-{
- static char buf[1024];
-
- FILE *fp = fopen (pathname (key), "r");
- if (fp == 0) {
- perror (pathname (key));
- return 0;
- }
-
- memset (buf, 0, sizeof (buf));
- size_t ret = fread (buf, 1, sizeof (buf) - 1, fp);
- if(ret == 0) {
- if(ferror(fp) != 0) {
- perror (pathname (key));
- fclose (fp);
- return 0;
- }
- }
- fclose (fp);
- return buf;
-}
-
-void
-gr_preferences::set (const char *key, const char *value)
-{
- ensure_dir_path ();
-
- FILE *fp = fopen (pathname (key), "w");
- if (fp == 0){
- perror (pathname (key));
- return;
- }
-
- size_t ret = fwrite (value, 1, strlen (value), fp);
- if(ret == 0) {
- if(ferror(fp) != 0) {
- perror (pathname (key));
- fclose (fp);
- return;
- }
- }
- fclose (fp);
-};
diff --git a/gnuradio-runtime/lib/gr_prefs.cc b/gnuradio-runtime/lib/gr_prefs.cc
deleted file mode 100644
index 8a79c3335f..0000000000
--- a/gnuradio-runtime/lib/gr_prefs.cc
+++ /dev/null
@@ -1,391 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gr_prefs.h>
-#include <gr_sys_paths.h>
-#include <gr_constants.h>
-#include <algorithm>
-
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/filesystem/fstream.hpp>
-namespace fs = boost::filesystem;
-
-/*
- * Stub implementations
- */
-
-static gr_prefs s_default_singleton;
-static gr_prefs *s_singleton = &s_default_singleton;
-
-gr_prefs *
-gr_prefs::singleton()
-{
- return s_singleton;
-}
-
-void
-gr_prefs::set_singleton(gr_prefs *p)
-{
- s_singleton = p;
-}
-
-gr_prefs::gr_prefs()
-{
- _read_files();
-}
-
-gr_prefs::~gr_prefs()
-{
- // nop
-}
-
-std::vector<std::string>
-gr_prefs::_sys_prefs_filenames()
-{
- std::vector<std::string> fnames;
-
- fs::path dir = gr_prefsdir();
- if(!fs::is_directory(dir))
- return fnames;
-
- fs::directory_iterator diritr(dir);
- while(diritr != fs::directory_iterator()) {
- fs::path p = *diritr++;
- if(p.extension() != ".swp")
- fnames.push_back(p.string());
- }
- std::sort(fnames.begin(), fnames.end());
-
- // Find if there is a ~/.gnuradio/config.conf file and add this to
- // the end of the file list to override any preferences in the
- // installed path config files.
- fs::path homedir = fs::path(gr_appdata_path());
- homedir = homedir/".gnuradio/config.conf";
- if(fs::exists(homedir)) {
- fnames.push_back(homedir.string());
- }
-
- return fnames;
-}
-
-void
-gr_prefs::_read_files()
-{
- std::string config;
-
- std::vector<std::string> filenames = _sys_prefs_filenames();
- std::vector<std::string>::iterator sitr;
- char tmp[1024];
- for(sitr = filenames.begin(); sitr != filenames.end(); sitr++) {
- fs::ifstream fin(*sitr);
- while(!fin.eof()) {
- fin.getline(tmp, 1024);
- std::string t(tmp);
- // ignore empty lines or lines of just comments
- if((t.size() > 0) && (t[0] != '#')) {
- // remove any comments in the line
- size_t hash = t.find("#");
-
- // Use hash marks at the end of each segment as a delimiter
- config += t.substr(0, hash) + '#';
- }
- }
- fin.close();
- }
-
- // Remove all whitespace.
- config.erase(std::remove_if(config.begin(), config.end(), ::isspace), config.end());
-
- // Convert the string into a map
- _convert_to_map(config);
-}
-
-void
-gr_prefs::_convert_to_map(const std::string &conf)
-{
- // Convert the string into an map of maps
- // Map is structured as {section name: map of options}
- // And options map is simply: {option name: option value}
- std::string sub = conf;
- size_t sec_start = sub.find("[");
- while(sec_start != std::string::npos) {
- sub = sub.substr(sec_start);
-
- size_t sec_end = sub.find("]");
- if(sec_end == std::string::npos)
- throw std::runtime_error("Config file error: Mismatched section label.\n");
-
- std::string sec = sub.substr(1, sec_end-1);
- size_t next_sec_start = sub.find("[", sec_end);
- std::string subsec = sub.substr(sec_end+1, next_sec_start-sec_end-2);
-
- std::transform(sec.begin(), sec.end(), sec.begin(), ::tolower);
-
- std::map<std::string, std::string> options_map = d_config_map[sec];
- size_t next_opt = 0;
- size_t next_val = 0;
- next_opt = subsec.find("#");
- while(next_opt < subsec.size()-1) {
- next_val = subsec.find("=", next_opt);
- std::string option = subsec.substr(next_opt+1, next_val-next_opt-1);
-
- next_opt = subsec.find("#", next_val);
- std::string value = subsec.substr(next_val+1, next_opt-next_val-1);
-
- std::transform(option.begin(), option.end(), option.begin(), ::tolower);
- options_map[option] = value;
- }
-
- d_config_map[sec] = options_map;
-
- sec_start = sub.find("[", sec_end);
- }
-}
-
-std::string
-gr_prefs::to_string()
-{
- gr_config_map_itr sections;
- gr_config_map_elem_itr options;
- std::stringstream s;
-
- for(sections = d_config_map.begin(); sections != d_config_map.end(); sections++) {
- s << "[" << sections->first << "]" << std::endl;
- for(options = sections->second.begin(); options != sections->second.end(); options++) {
- s << options->first << " = " << options->second << std::endl;
- }
- s << std::endl;
- }
-
- return s.str();
-}
-
-void
-gr_prefs::save()
-{
- std::string conf = to_string();
-
- fs::path homedir = fs::path(gr_appdata_path());
- homedir = homedir/".gnuradio/config.conf";
- fs::ofstream fout(homedir);
- fout << conf;
- fout.close();
-}
-
-char *
-gr_prefs::option_to_env(std::string section, std::string option)
-{
- std::stringstream envname;
- std::string secname=section, optname=option;
-
- std::transform(section.begin(), section.end(), secname.begin(), ::toupper);
- std::transform(option.begin(), option.end(), optname.begin(), ::toupper);
- envname << "GR_CONF_" << secname << "_" << optname;
-
- return getenv(envname.str().c_str());
-}
-
-bool
-gr_prefs::has_section(const std::string &section)
-{
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
- return d_config_map.count(s) > 0;
-}
-
-bool
-gr_prefs::has_option(const std::string &section, const std::string &option)
-{
- if(option_to_env(section, option))
- return true;
-
- if(has_section(section)) {
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- gr_config_map_itr sec = d_config_map.find(s);
- return sec->second.count(o) > 0;
- }
- else {
- return false;
- }
-}
-
-const std::string
-gr_prefs::get_string(const std::string &section, const std::string &option,
- const std::string &default_val)
-{
- char *env = option_to_env(section, option);
- if(env)
- return std::string(env);
-
- if(has_option(section, option)) {
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- gr_config_map_itr sec = d_config_map.find(s);
- gr_config_map_elem_itr opt = sec->second.find(o);
- return opt->second;
- }
- else {
- return default_val;
- }
-}
-
-void
-gr_prefs::set_string(const std::string &section, const std::string &option,
- const std::string &val)
-{
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- std::map<std::string, std::string> opt_map = d_config_map[s];
-
- opt_map[o] = val;
-
- d_config_map[s] = opt_map;
-}
-
-bool
-gr_prefs::get_bool(const std::string &section, const std::string &option, bool default_val)
-{
- if(has_option(section, option)) {
- std::string str = get_string(section, option, "");
- if(str == "") {
- return default_val;
- }
- std::transform(str.begin(), str.end(), str.begin(), ::tolower);
- if((str == "true") || (str == "on") || (str == "1"))
- return true;
- else if((str == "false") || (str == "off") || (str == "0"))
- return false;
- else
- return default_val;
- }
- else {
- return default_val;
- }
-}
-
-void
-gr_prefs::set_bool(const std::string &section, const std::string &option, bool val)
-{
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- std::map<std::string, std::string> opt_map = d_config_map[s];
-
- std::stringstream sstr;
- sstr << (val == true);
- opt_map[o] = sstr.str();
-
- d_config_map[s] = opt_map;
-}
-
-long
-gr_prefs::get_long(const std::string &section, const std::string &option, long default_val)
-{
- if(has_option(section, option)) {
- std::string str = get_string(section, option, "");
- if(str == "") {
- return default_val;
- }
- std::stringstream sstr(str);
- long n;
- sstr >> n;
- return n;
- }
- else {
- return default_val;
- }
-}
-
-void
-gr_prefs::set_long(const std::string &section, const std::string &option, long val)
-{
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- std::map<std::string, std::string> opt_map = d_config_map[s];
-
- std::stringstream sstr;
- sstr << val;
- opt_map[o] = sstr.str();
-
- d_config_map[s] = opt_map;
-}
-
-double
-gr_prefs::get_double(const std::string &section, const std::string &option, double default_val)
-{
- if(has_option(section, option)) {
- std::string str = get_string(section, option, "");
- if(str == "") {
- return default_val;
- }
- std::stringstream sstr(str);
- double n;
- sstr >> n;
- return n;
- }
- else {
- return default_val;
- }
-}
-
-void
-gr_prefs::set_double(const std::string &section, const std::string &option, double val)
-{
- std::string s = section;
- std::transform(section.begin(), section.end(), s.begin(), ::tolower);
-
- std::string o = option;
- std::transform(option.begin(), option.end(), o.begin(), ::tolower);
-
- std::map<std::string, std::string> opt_map = d_config_map[s];
-
- std::stringstream sstr;
- sstr << val;
- opt_map[o] = sstr.str();
-
- d_config_map[s] = opt_map;
-}
diff --git a/gnuradio-runtime/lib/gr_random.cc b/gnuradio-runtime/lib/gr_random.cc
deleted file mode 100644
index 323839acc7..0000000000
--- a/gnuradio-runtime/lib/gr_random.cc
+++ /dev/null
@@ -1,183 +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.
- */
-
-/*
- * Copyright 1997 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <math.h>
-#include <gr_random.h>
-
-#define IA 16807
-#define IM 2147483647
-#define AM (1.0/IM)
-#define IQ 127773
-#define IR 2836
-#define NDIV (1+(IM-1)/NTAB)
-#define EPS 1.2e-7
-#define RNMX (1.0-EPS)
-
-
-gr_random::gr_random (long seed)
-{
- reseed (seed);
-}
-
-void
-gr_random::reseed (long seed)
-{
- d_seed = seed;
- d_iy = 0;
- for (int i = 0; i < NTAB; i++)
- d_iv[i] = 0;
- d_iset = 0;
- d_gset = 0;
-}
-
-/*
- * This looks like it returns a uniform random deviate between 0.0 and 1.0
- * It looks similar to code from "Numerical Recipes in C".
- */
-float gr_random::ran1()
-{
- int j;
- long k;
- float temp;
-
- if (d_seed <= 0 || !d_iy) {
- if (-d_seed < 1)
- d_seed=1;
- else
- d_seed = -d_seed;
- for (j=NTAB+7;j>=0;j--) {
- k=d_seed/IQ;
- d_seed=IA*(d_seed-k*IQ)-IR*k;
- if (d_seed < 0)
- d_seed += IM;
- if (j < NTAB)
- d_iv[j] = d_seed;
- }
- d_iy=d_iv[0];
- }
- k=(d_seed)/IQ;
- d_seed=IA*(d_seed-k*IQ)-IR*k;
- if (d_seed < 0)
- d_seed += IM;
- j=d_iy/NDIV;
- d_iy=d_iv[j];
- d_iv[j] = d_seed;
- temp=AM * d_iy;
- if (temp > RNMX)
- temp = RNMX;
- return temp;
-}
-
-/*
- * Returns a normally distributed deviate with zero mean and variance 1.
- * Also looks like it's from "Numerical Recipes in C".
- */
-float gr_random::gasdev()
-{
- float fac,rsq,v1,v2;
- d_iset = 1 - d_iset;
- if (d_iset) {
- do {
- v1=2.0*ran1()-1.0;
- v2=2.0*ran1()-1.0;
- rsq=v1*v1+v2*v2;
- } while (rsq >= 1.0 || rsq == 0.0);
- fac= sqrt(-2.0*log(rsq)/rsq);
- d_gset=v1*fac;
- return v2*fac;
- }
- return d_gset;
-}
-
-/*
- * Copied from The KC7WW / OH2BNS Channel Simulator
- * FIXME Need to check how good this is at some point
- */
-
-float gr_random::laplacian()
-{
- float z = ran1();
- if (z < 0.5)
- return log(2.0 * z) / M_SQRT2;
- else
- return -log(2.0 * (1.0 - z)) / M_SQRT2;
-}
-
-/*
- * Copied from The KC7WW / OH2BNS Channel Simulator
- * FIXME Need to check how good this is at some point
- */
-
- // 5 => scratchy, 8 => Geiger
-
-float gr_random::impulse(float factor = 5)
-{
- float z = -M_SQRT2 * log(ran1());
- if (fabsf(z) <= factor)
- return 0.0;
- else
- return z;
-}
-
-/*
- * Complex rayleigh is really gaussian I and gaussian Q
- * It can also be generated by real rayleigh magnitude and
- * uniform random angle
- * Adapted from The KC7WW / OH2BNS Channel Simulator
- * FIXME Need to check how good this is at some point
- */
-
-gr_complex gr_random::rayleigh_complex()
-{
- return gr_complex(gasdev(),gasdev());
-}
-
-/* Other option
- mag = rayleigh();
- ang = 2.0 * M_PI * RNG();
- *Rx = rxx * cos(z);
- *Iy = rxx * sin(z);
-*/
-
-
-float gr_random::rayleigh()
-{
- return sqrt(-2.0 * log(ran1()));
-}
diff --git a/gnuradio-runtime/lib/gr_random.h b/gnuradio-runtime/lib/gr_random.h
deleted file mode 100644
index 783c05f920..0000000000
--- a/gnuradio-runtime/lib/gr_random.h
+++ /dev/null
@@ -1,65 +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.
- */
-
-#ifndef INCLUDED_GR_RANDOM_H
-#define INCLUDED_GR_RANDOM_H
-
-#include <gr_runtime_api.h>
-#include <gr_complex.h>
-
-/*!
- * \brief pseudo random number generator
- * \ingroup math_blk
- */
-class GR_RUNTIME_API gr_random {
-protected:
- static const int NTAB = 32;
- long d_seed;
- long d_iy;
- long d_iv[NTAB];
- int d_iset;
- float d_gset;
-
-
-public:
- gr_random (long seed=3021);
-
- void reseed (long seed);
-
- /*!
- * \brief uniform random deviate in the range [0.0, 1.0)
- */
- float ran1 ();
-
- /*!
- * \brief normally distributed deviate with zero mean and variance 1
- */
- float gasdev ();
-
- float laplacian ();
- float impulse (float factor);
- float rayleigh ();
- gr_complex rayleigh_complex ();
-};
-
-#endif /* INCLUDED_GR_RANDOM_H */
-
diff --git a/gnuradio-runtime/lib/gr_realtime.cc b/gnuradio-runtime/lib/gr_realtime.cc
deleted file mode 100644
index d7a7eab5ba..0000000000
--- a/gnuradio-runtime/lib/gr_realtime.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2007,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gr_realtime.h>
-
-gr_rt_status_t
-gr_enable_realtime_scheduling()
-{
- return gr_enable_realtime_scheduling();
-}
diff --git a/gnuradio-runtime/lib/gr_reverse.h b/gnuradio-runtime/lib/gr_reverse.h
deleted file mode 100644
index aa8619619f..0000000000
--- a/gnuradio-runtime/lib/gr_reverse.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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_REVERSE_H
-#define INCLUDED_GR_REVERSE_H
-
-#include <gr_runtime_api.h>
-#include <vector>
-#include <gr_complex.h>
-
-// reverse the order of taps
-std::vector<float> gr_reverse (const std::vector<float> &taps);
-std::vector<gr_complex> gr_reverse (const std::vector<gr_complex> &taps);
-
-
-#endif /* INCLUDED_GR_REVERSE_H */
diff --git a/gnuradio-runtime/lib/gr_scheduler.h b/gnuradio-runtime/lib/gr_scheduler.h
deleted file mode 100644
index 097f575c21..0000000000
--- a/gnuradio-runtime/lib/gr_scheduler.h
+++ /dev/null
@@ -1,65 +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.
- */
-
-#ifndef INCLUDED_GR_SCHEDULER_H
-#define INCLUDED_GR_SCHEDULER_H
-
-#include <gr_runtime_api.h>
-#include <boost/utility.hpp>
-#include <gr_block.h>
-#include <gr_flat_flowgraph.h>
-
-
-class gr_scheduler;
-typedef boost::shared_ptr<gr_scheduler> gr_scheduler_sptr;
-
-
-/*!
- * \brief Abstract scheduler that takes a flattened flow graph and runs it.
- *
- * Preconditions: details, buffers and buffer readers have been assigned.
- */
-class GR_RUNTIME_API gr_scheduler : boost::noncopyable
-{
-
-public:
- /*!
- * \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.
- */
- gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
-
- virtual ~gr_scheduler();
-
- /*!
- * \brief Tell the scheduler to stop executing.
- */
- virtual void stop() = 0;
-
- /*!
- * \brief Block until the graph is done.
- */
- virtual void wait() = 0;
-};
-
-#endif /* INCLUDED_GR_SCHEDULER_H */
diff --git a/gnuradio-runtime/lib/gr_scheduler_sts.cc b/gnuradio-runtime/lib/gr_scheduler_sts.cc
deleted file mode 100644
index 10f01edaf6..0000000000
--- a/gnuradio-runtime/lib/gr_scheduler_sts.cc
+++ /dev/null
@@ -1,87 +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 <gr_scheduler_sts.h>
-#include <gr_single_threaded_scheduler.h>
-#include <thread/thread_body_wrapper.h>
-
-class sts_container
-{
- gr_block_vector_t d_blocks;
-
-public:
-
- sts_container(gr_block_vector_t blocks)
- : d_blocks(blocks) {}
-
- void operator()()
- {
- gr_make_single_threaded_scheduler(d_blocks)->run();
- }
-};
-
-
-gr_scheduler_sptr
-gr_scheduler_sts::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
-{
- return gr_scheduler_sptr(new gr_scheduler_sts(ffg, max_noutput_items));
-}
-
-gr_scheduler_sts::gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
- : gr_scheduler(ffg, max_noutput_items)
-{
- // Split the flattened flow graph into discrete partitions, each
- // of which is topologically sorted.
-
- std::vector<gr_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<gr_basic_block_vector_t>::iterator p = graphs.begin();
- p != graphs.end(); p++) {
-
- gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(*p);
- d_threads.create_thread(
- gr::thread::thread_body_wrapper<sts_container>(sts_container(blocks),
- "single-threaded-scheduler"));
- }
-}
-
-gr_scheduler_sts::~gr_scheduler_sts()
-{
- stop();
-}
-
-void
-gr_scheduler_sts::stop()
-{
- d_threads.interrupt_all();
-}
-
-void
-gr_scheduler_sts::wait()
-{
- d_threads.join_all();
-}
diff --git a/gnuradio-runtime/lib/gr_scheduler_sts.h b/gnuradio-runtime/lib/gr_scheduler_sts.h
deleted file mode 100644
index af98c6d8ba..0000000000
--- a/gnuradio-runtime/lib/gr_scheduler_sts.h
+++ /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.
- */
-#ifndef INCLUDED_GR_SCHEDULER_STS_H
-#define INCLUDED_GR_SCHEDULER_STS_H
-
-#include <gr_runtime_api.h>
-#include <gr_scheduler.h>
-#include <thread/thread_group.h>
-
-/*!
- * \brief Concrete scheduler that uses the single_threaded_scheduler
- */
-class GR_RUNTIME_API gr_scheduler_sts : public gr_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.
- */
- gr_scheduler_sts(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
-
-public:
- static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
-
- ~gr_scheduler_sts();
-
- /*!
- * \brief Tell the scheduler to stop executing.
- */
- void stop();
-
- /*!
- * \brief Block until the graph is done.
- */
- void wait();
-};
-
-
-
-
-#endif /* INCLUDED_GR_SCHEDULER_STS_H */
diff --git a/gnuradio-runtime/lib/gr_scheduler_tpb.cc b/gnuradio-runtime/lib/gr_scheduler_tpb.cc
deleted file mode 100644
index e67078632f..0000000000
--- a/gnuradio-runtime/lib/gr_scheduler_tpb.cc
+++ /dev/null
@@ -1,103 +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 <gr_scheduler_tpb.h>
-#include <gr_tpb_thread_body.h>
-#include <thread/thread_body_wrapper.h>
-#include <sstream>
-
-/*
- * You know, a lambda expression would be sooo much easier...
- */
-class tpb_container
-{
- gr_block_sptr d_block;
- int d_max_noutput_items;
-
-public:
- tpb_container(gr_block_sptr block, int max_noutput_items)
- : d_block(block), d_max_noutput_items(max_noutput_items) {}
-
- void operator()()
- {
- gr_tpb_thread_body body(d_block, d_max_noutput_items);
- }
-};
-
-
-gr_scheduler_sptr
-gr_scheduler_tpb::make(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
-{
- return gr_scheduler_sptr(new gr_scheduler_tpb(ffg, max_noutput_items));
-}
-
-gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
- : gr_scheduler(ffg, max_noutput_items)
-{
- // Get a topologically sorted vector of all the blocks in use.
- // Being topologically sorted probably isn't going to matter, but
- // there's a non-zero chance it might help...
-
- gr_basic_block_vector_t used_blocks = ffg->calc_used_blocks();
- used_blocks = ffg->topological_sort(used_blocks);
- gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(used_blocks);
-
- // Ensure that the done flag is clear on all blocks
-
- for (size_t i = 0; i < blocks.size(); i++){
- blocks[i]->detail()->set_done(false);
- }
-
- // Fire off a thead for each block
-
- for (size_t i = 0; i < blocks.size(); i++){
- std::stringstream name;
- name << "thread-per-block[" << i << "]: " << blocks[i];
-
- // If set, use internal value instead of global value
- if(blocks[i]->is_set_max_noutput_items())
- max_noutput_items = blocks[i]->max_noutput_items();
-
- d_threads.create_thread(
- gr::thread::thread_body_wrapper<tpb_container>(tpb_container(blocks[i], max_noutput_items),
- name.str()));
- }
-}
-
-gr_scheduler_tpb::~gr_scheduler_tpb()
-{
- stop();
-}
-
-void
-gr_scheduler_tpb::stop()
-{
- d_threads.interrupt_all();
-}
-
-void
-gr_scheduler_tpb::wait()
-{
- d_threads.join_all();
-}
diff --git a/gnuradio-runtime/lib/gr_scheduler_tpb.h b/gnuradio-runtime/lib/gr_scheduler_tpb.h
deleted file mode 100644
index 4ab7bb16d2..0000000000
--- a/gnuradio-runtime/lib/gr_scheduler_tpb.h
+++ /dev/null
@@ -1,61 +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.
- */
-#ifndef INCLUDED_GR_SCHEDULER_TPB_H
-#define INCLUDED_GR_SCHEDULER_TPB_H
-
-#include <gr_runtime_api.h>
-#include <gr_scheduler.h>
-#include <thread/thread_group.h>
-
-/*!
- * \brief Concrete scheduler that uses a kernel thread-per-block
- */
-class GR_RUNTIME_API gr_scheduler_tpb : public gr_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.
- */
- gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg, int max_noutput_items);
-
-public:
- static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg, int max_noutput_items=100000);
-
- ~gr_scheduler_tpb();
-
- /*!
- * \brief Tell the scheduler to stop executing.
- */
- void stop();
-
- /*!
- * \brief Block until the graph is done.
- */
- void wait();
-};
-
-
-#endif /* INCLUDED_GR_SCHEDULER_TPB_H */
diff --git a/gnuradio-runtime/lib/gr_single_threaded_scheduler.cc b/gnuradio-runtime/lib/gr_single_threaded_scheduler.cc
deleted file mode 100644
index 1bb9e9b0a8..0000000000
--- a/gnuradio-runtime/lib/gr_single_threaded_scheduler.cc
+++ /dev/null
@@ -1,364 +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 <gr_single_threaded_scheduler.h>
-#include <gr_block.h>
-#include <gr_block_detail.h>
-#include <gr_buffer.h>
-#include <boost/thread.hpp>
-#include <boost/format.hpp>
-#include <iostream>
-#include <limits>
-#include <assert.h>
-#include <stdio.h>
-
-// 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;
-
-gr_single_threaded_scheduler_sptr
-gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks)
-{
- return
- gr_single_threaded_scheduler_sptr (new gr_single_threaded_scheduler (blocks));
-}
-
-gr_single_threaded_scheduler::gr_single_threaded_scheduler (
- const std::vector<gr_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 << "gr_single_threaded_scheduler: "
- << d_blocks.size ()
- << " blocks\n";
- }
-}
-
-gr_single_threaded_scheduler::~gr_single_threaded_scheduler ()
-{
- if (ENABLE_LOGGING)
- delete d_log;
-}
-
-void
-gr_single_threaded_scheduler::run ()
-{
- // d_enabled = true; // KLUDGE
- main_loop ();
-}
-
-void
-gr_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 (gr_block_detail *d, int output_multiple)
-{
- int min_space = std::numeric_limits<int>::max();
-
- for (int i = 0; i < d->noutputs (); i++){
- int n = round_down (d->output(i)->space_available (), output_multiple);
- if (n == 0){ // We're blocked on output.
- if (d->output(i)->done()){ // Downstream is done, therefore we're done.
- return -1;
- }
- return 0;
- }
- min_space = std::min (min_space, n);
- }
- return min_space;
-}
-
-void
-gr_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;
-
- gr_block *m = d_blocks[bi].get ();
- gr_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++){
- ninput_items[i] = d->input(i)->items_available();
- //if (ninput_items[i] == 0 && d->input(i)->done())
- if (ninput_items[i] < m->output_multiple() && d->input(i)->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
- LOG(*d_log << " BLKD_IN\n");
- if (d->input(i)->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] > d->input(i)->max_possible_items_available ()){
- // Nope, never going to happen...
- std::cerr << "\nsched: <gr_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 = "
- << d->input(i)->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();
-}
diff --git a/gnuradio-runtime/lib/gr_sync_block.cc b/gnuradio-runtime/lib/gr_sync_block.cc
deleted file mode 100644
index 94efcdc8ee..0000000000
--- a/gnuradio-runtime/lib/gr_sync_block.cc
+++ /dev/null
@@ -1,68 +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 <gr_sync_block.h>
-
-gr_sync_block::gr_sync_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature)
- : gr_block(name, input_signature, output_signature)
-{
- set_fixed_rate(true);
-}
-
-
-void
-gr_sync_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- unsigned ninputs = ninput_items_required.size();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = fixed_rate_noutput_to_ninput (noutput_items);
-}
-
-int
-gr_sync_block::fixed_rate_noutput_to_ninput(int noutput_items)
-{
- return noutput_items + history() - 1;
-}
-
-int
-gr_sync_block::fixed_rate_ninput_to_noutput(int ninput_items)
-{
- return std::max(0, ninput_items - (int)history() + 1);
-}
-
-int
-gr_sync_block::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- int r = work (noutput_items, input_items, output_items);
- if (r > 0)
- consume_each (r);
- return r;
-}
diff --git a/gnuradio-runtime/lib/gr_sync_decimator.cc b/gnuradio-runtime/lib/gr_sync_decimator.cc
deleted file mode 100644
index a0f907db53..0000000000
--- a/gnuradio-runtime/lib/gr_sync_decimator.cc
+++ /dev/null
@@ -1,69 +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 <gr_sync_decimator.h>
-
-gr_sync_decimator::gr_sync_decimator (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature,
- unsigned decimation)
- : gr_sync_block (name, input_signature, output_signature)
-{
- set_decimation (decimation);
-}
-
-void
-gr_sync_decimator::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
-}
-
-int
-gr_sync_decimator::fixed_rate_noutput_to_ninput(int noutput_items)
-{
- return noutput_items * decimation() + history() - 1;
-}
-
-int
-gr_sync_decimator::fixed_rate_ninput_to_noutput(int ninput_items)
-{
- return std::max(0, ninput_items - (int)history() + 1) / decimation();
-}
-
-int
-gr_sync_decimator::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- int r = work (noutput_items, input_items, output_items);
- if (r > 0)
- consume_each (r * decimation ());
- return r;
-}
-
diff --git a/gnuradio-runtime/lib/gr_sync_interpolator.cc b/gnuradio-runtime/lib/gr_sync_interpolator.cc
deleted file mode 100644
index ece873c14a..0000000000
--- a/gnuradio-runtime/lib/gr_sync_interpolator.cc
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_sync_interpolator.h>
-
-gr_sync_interpolator::gr_sync_interpolator (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature,
- unsigned interpolation)
- : gr_sync_block (name, input_signature, output_signature)
-{
- set_interpolation (interpolation);
-}
-
-void
-gr_sync_interpolator::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
-}
-
-int
-gr_sync_interpolator::fixed_rate_noutput_to_ninput(int noutput_items)
-{
- return noutput_items / interpolation() + history() - 1;
-}
-
-int
-gr_sync_interpolator::fixed_rate_ninput_to_noutput(int ninput_items)
-{
- return std::max(0, ninput_items - (int)history() + 1) * interpolation();
-}
-
-int
-gr_sync_interpolator::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- int r = work (noutput_items, input_items, output_items);
- if (r > 0)
- consume_each (r / interpolation ());
- return r;
-}
-
-
diff --git a/gnuradio-runtime/lib/gr_tagged_stream_block.cc b/gnuradio-runtime/lib/gr_tagged_stream_block.cc
deleted file mode 100644
index a60515f481..0000000000
--- a/gnuradio-runtime/lib/gr_tagged_stream_block.cc
+++ /dev/null
@@ -1,146 +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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <boost/format.hpp>
-#include <gr_tagged_stream_block.h>
-
-gr_tagged_stream_block::gr_tagged_stream_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature,
- const std::string &length_tag_key)
- : gr_block(name, input_signature, output_signature),
- d_length_tag_key(pmt::string_to_symbol(length_tag_key)),
- d_n_input_items_reqd(input_signature->min_streams(), 0),
- d_length_tag_key_str(length_tag_key)
-{
-}
-
-
-// This is evil hackery: We trick the scheduler into creating the right number of input items
-void
-gr_tagged_stream_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
-{
- unsigned ninputs = ninput_items_required.size();
- for (unsigned i = 0; i < ninputs; i++) {
- if (i < d_n_input_items_reqd.size() && d_n_input_items_reqd[i] != 0) {
- ninput_items_required[i] = d_n_input_items_reqd[i];
- } else {
- // If there's no item, there's no tag--so there must at least be one!
- ninput_items_required[i] = std::max(1, (int) std::floor((double) noutput_items / relative_rate() + 0.5));
- }
- }
-}
-
-
-void
-gr_tagged_stream_block::parse_length_tags(
- const std::vector<std::vector<gr_tag_t> > &tags,
- gr_vector_int &n_input_items_reqd
-){
- for (unsigned i = 0; i < tags.size(); i++) {
- for (unsigned k = 0; k < tags[i].size(); k++) {
- if (tags[i][k].key == d_length_tag_key) {
- n_input_items_reqd[i] = pmt::to_long(tags[i][k].value);
- remove_item_tag(i, tags[i][k]);
- }
- }
- }
-}
-
-
-int
-gr_tagged_stream_block::calculate_output_stream_length(const gr_vector_int &ninput_items)
-{
- int noutput_items = *std::max_element(ninput_items.begin(), ninput_items.end());
- return (int) std::floor(relative_rate() * noutput_items + 0.5);
-}
-
-
-void
-gr_tagged_stream_block::update_length_tags(int n_produced, int n_ports)
-{
- for (int i = 0; i < n_ports; i++) {
- add_item_tag(i, nitems_written(i),
- d_length_tag_key,
- pmt::from_long(n_produced)
- );
- }
- return;
-}
-
-
-int
-gr_tagged_stream_block::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
-{
- if (d_length_tag_key_str.empty()) {
- return work(noutput_items, ninput_items, input_items, output_items);
- }
-
- if (d_n_input_items_reqd[0] == 0) { // Otherwise, it's already set from a previous call
- std::vector<std::vector<gr_tag_t> > tags(input_items.size(), std::vector<gr_tag_t>());
- for (unsigned i = 0; i < input_items.size(); i++) {
- get_tags_in_range(tags[i], i, nitems_read(i), nitems_read(i)+1);
- }
- d_n_input_items_reqd.assign(input_items.size(), -1);
- parse_length_tags(tags, d_n_input_items_reqd);
- }
- for (unsigned i = 0; i < input_items.size(); i++) {
- if (d_n_input_items_reqd[i] == -1) {
- GR_LOG_FATAL(d_logger, boost::format("Missing a required length tag on port %1% at item #%2%") % i % nitems_read(i));
- throw std::runtime_error("Missing length tag.");
- }
- if (d_n_input_items_reqd[i] > ninput_items[i]) {
- return 0;
- }
- }
-
- int min_output_size = calculate_output_stream_length(d_n_input_items_reqd);
- if (noutput_items < min_output_size) {
- set_min_noutput_items(min_output_size);
- return 0;
- }
- set_min_noutput_items(1);
-
- // WORK CALLED HERE //
- int n_produced = work(noutput_items, d_n_input_items_reqd, input_items, output_items);
- //////////////////////
-
- if (n_produced == WORK_DONE) {
- return n_produced;
- }
- for (int i = 0; i < (int) d_n_input_items_reqd.size(); i++) {
- consume(i, d_n_input_items_reqd[i]);
- }
- update_length_tags(n_produced, output_items.size());
-
- d_n_input_items_reqd.assign(input_items.size(), 0);
-
- return n_produced;
-}
-
diff --git a/gnuradio-runtime/lib/gr_test.cc b/gnuradio-runtime/lib/gr_test.cc
deleted file mode 100644
index cd5ef83611..0000000000
--- a/gnuradio-runtime/lib/gr_test.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006,2008,2010 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 <gr_test.h>
-#include <gr_io_signature.h>
-#include <stdexcept>
-#include <iostream>
-#include <string.h>
-
-gr_test_sptr gr_make_test (const std::string &name,
- int min_inputs, int max_inputs, unsigned int sizeof_input_item,
- int min_outputs, int max_outputs, unsigned int sizeof_output_item,
- unsigned int history,unsigned int output_multiple,double relative_rate,
- bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type)
-{
- return gnuradio::get_initial_sptr(new gr_test (name, min_inputs,max_inputs,sizeof_input_item,
- min_outputs,max_outputs,sizeof_output_item,
- history,output_multiple,relative_rate,fixed_rate,cons_type, prod_type));
-}
-
- gr_test::gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
- int min_outputs, int max_outputs, unsigned int sizeof_output_item,
- unsigned int history,unsigned int output_multiple,double relative_rate,
- bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type): gr_block (name,
- gr_make_io_signature (min_inputs, max_inputs, sizeof_input_item),
- gr_make_io_signature (min_outputs, max_outputs, sizeof_output_item)),
- d_sizeof_input_item(sizeof_input_item),
- d_sizeof_output_item(sizeof_output_item),
- d_check_topology(true),
- d_consume_type(cons_type),
- d_min_consume(0),
- d_max_consume(0),
- d_produce_type(prod_type),
- d_min_produce(0),
- d_max_produce(0)
- {
- set_history(history);
- set_output_multiple(output_multiple);
- set_relative_rate(relative_rate);
- set_fixed_rate(fixed_rate);
- }
-
-int
-gr_test::general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- //touch all inputs and outputs to detect segfaults
- unsigned ninputs = input_items.size ();
- unsigned noutputs= output_items.size();
- for (unsigned i = 0; i < ninputs; i++)
- {
- char * in=(char *)input_items[i];
- if (ninput_items[i]< (int)(noutput_items+history()))
- {
- std::cerr << "ERROR: ninput_items[" << i << "] < noutput_items+history()" << std::endl;
- std::cerr << "ninput_items[" << i << "] = " << ninput_items[i] << std::endl;
- std::cerr << "noutput_items+history() = " << noutput_items+history() << std::endl;
- std::cerr << "noutput_items = " << noutput_items << std::endl;
- std::cerr << "history() = " << history() << std::endl;
- throw std::runtime_error ("gr_test");
- } else
- {
- for (int j=0;j<ninput_items[i];j++)
- {
- //Touch every available input_item
- //We use a class variable to avoid the compiler to optimize this away
- for(unsigned int k=0;k<d_sizeof_input_item;k++)
- d_temp= in[j*d_sizeof_input_item+k];
- }
- switch (d_consume_type)
- {
- case CONSUME_NOUTPUT_ITEMS:
- consume(i,noutput_items);
- break;
- case CONSUME_NOUTPUT_ITEMS_LIMIT_MAX:
- consume(i,std::min(noutput_items,d_max_consume));
- break;
- case CONSUME_NOUTPUT_ITEMS_LIMIT_MIN:
- consume(i,std::min(std::max(noutput_items,d_min_consume),ninput_items[i]));
- break;
- case CONSUME_ALL_AVAILABLE:
- consume(i,ninput_items[i]);
- break;
- case CONSUME_ALL_AVAILABLE_LIMIT_MAX:
- consume(i,std::min(ninput_items[i],d_max_consume));
- break;
-/* //This could result in segfault, uncomment if you want to test this
- case CONSUME_ALL_AVAILABLE_LIMIT_MIN:
- consume(i,std::max(ninput_items[i],d_max_consume));
- break;*/
- case CONSUME_ZERO:
- consume(i,0);
- break;
- case CONSUME_ONE:
- consume(i,1);
- break;
- case CONSUME_MINUS_ONE:
- consume(i,-1);
- break;
- default:
- consume(i,noutput_items);
- }
- }
- }
- for (unsigned i = 0; i < noutputs; i++)
- {
- char * out=(char *)output_items[i];
- {
- for (int j=0;j<noutput_items;j++)
- {
- //Touch every available output_item
- for(unsigned int k=0;k<d_sizeof_output_item;k++)
- out[j*d_sizeof_input_item+k]=0;
- }
- }
- }
- //Now copy input to output until max ninputs or max noutputs is reached
- int common_nports=std::min(ninputs,noutputs);
- if(d_sizeof_output_item==d_sizeof_input_item)
- for (int i = 0; i < common_nports; i++)
- {
- memcpy(output_items[i],input_items[i],noutput_items*d_sizeof_input_item);
- }
- int noutput_items_produced=0;
- switch (d_produce_type){
- case PRODUCE_NOUTPUT_ITEMS:
- noutput_items_produced=noutput_items;
- break;
- case PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX:
- noutput_items_produced=std::min(noutput_items,d_max_produce);
- break;
-/* //This could result in segfault, uncomment if you want to test this
- case PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN:
- noutput_items_produced=std::max(noutput_items,d_min_produce);
- break;*/
- case PRODUCE_ZERO:
- noutput_items_produced=0;
- break;
- case PRODUCE_ONE:
- noutput_items_produced=1;
- break;
- case PRODUCE_MINUS_ONE:
- noutput_items_produced=-1;
- break;
- default:
- noutput_items_produced=noutput_items;
- }
- return noutput_items_produced;
- }
-
-
-
diff --git a/gnuradio-runtime/lib/gr_test.h b/gnuradio-runtime/lib/gr_test.h
deleted file mode 100644
index 2276ab1967..0000000000
--- a/gnuradio-runtime/lib/gr_test.h
+++ /dev/null
@@ -1,195 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2006 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_TEST_H
-#define INCLUDED_GR_TEST_H
-
-#include <gr_runtime_api.h>
-#include <gr_block.h>
-#include <string>
-#include "gr_test_types.h"
-
-class gr_test;
-typedef boost::shared_ptr<gr_test> gr_test_sptr;
-
-// public constructor
-GR_RUNTIME_API gr_test_sptr gr_make_test (const std::string &name=std::string("gr_test"),
- int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
- int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
- unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
- bool fixed_rate=true,gr_consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS, gr_produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
-
-/*!
- * \brief Test class for testing runtime system (setting up buffers and such.)
- * \ingroup misc
- *
- * This block does not do any usefull actual data processing.
- * It just exposes setting all standard block parameters using the contructor or public methods.
- *
- * This block can be usefull when testing the runtime system.
- * You can force this block to have a large history, decimation
- * factor and/or large output_multiple.
- * The runtime system should detect this and create large enough buffers
- * all through the signal chain.
- */
-class GR_RUNTIME_API gr_test : public gr_block {
-
- public:
-
- ~gr_test (){}
-
-int general_work (int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items);
- // ----------------------------------------------------------------
- // override these to define your behavior
- // ----------------------------------------------------------------
-
- /*!
- * \brief Estimate input requirements given output request
- *
- * \param noutput_items number of output items to produce
- * \param ninput_items_required number of input items required on each input stream
- *
- * Given a request to product \p noutput_items, estimate the number of
- * data items required on each input stream. The estimate doesn't have
- * to be exact, but should be close.
- */
- void forecast (int noutput_items,
- gr_vector_int &ninput_items_required)
- {
- unsigned ninputs = ninput_items_required.size ();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = (int)((double)noutput_items / relative_rate()) + (int)history();
- }
-
-
- /*!
- * \brief Force check topology to return true or false.
- *
- * \param check_topology value to return when check_topology is called (true or false)
- * default check_topology returns true
- *
- */
- void set_check_topology (bool check_topology){ d_check_topology=check_topology;}
-
- /*!
- * \brief Confirm that ninputs and noutputs is an acceptable combination.
- *
- * \param ninputs number of input streams connected
- * \param noutputs number of output streams connected
- *
- * \returns true if this is a valid configuration for this block.
- *
- * This function is called by the runtime system whenever the
- * topology changes. Most classes do not need to override this.
- * This check is in addition to the constraints specified by the input
- * and output gr_io_signatures.
- */
- bool check_topology (int ninputs, int noutputs) { return d_check_topology;}
-
- // ----------------------------------------------------------------
- /*
- * The following two methods provide special case info to the
- * scheduler in the event that a block has a fixed input to output
- * ratio. gr_sync_block, gr_sync_decimator and gr_sync_interpolator
- * override these. If you're fixed rate, subclass one of those.
- */
- /*!
- * \brief Given ninput samples, return number of output samples that will be produced.
- * N.B. this is only defined if fixed_rate returns true.
- * Generally speaking, you don't need to override this.
- */
- int fixed_rate_ninput_to_noutput(int ninput) { return (int)((double)ninput/relative_rate()); }
-
- /*!
- * \brief Given noutput samples, return number of input samples required to produce noutput.
- * N.B. this is only defined if fixed_rate returns true.
- */
- int fixed_rate_noutput_to_ninput(int noutput) { return (int)((double)noutput*relative_rate()); }
-
- /*!
- * \brief Set if fixed rate should return true.
- * N.B. This is normally a private method but we make it available here as public.
- */
- void set_fixed_rate_public(bool fixed_rate){ set_fixed_rate(fixed_rate);}
-
- /*!
- * \brief Set the consume pattern.
- *
- * \param cons_type which consume pattern to use
- */
- void set_consume_type (gr_consume_type_t cons_type) { d_consume_type=cons_type;}
-
- /*!
- * \brief Set the consume limit.
- *
- * \param limit min or maximum items to consume (depending on consume_type)
- */
- void set_consume_limit (unsigned int limit) { d_min_consume=limit; d_max_consume=limit;}
-
- /*!
- * \brief Set the produce pattern.
- *
- * \param prod_type which produce pattern to use
- */
- void set_produce_type (gr_produce_type_t prod_type) { d_produce_type=prod_type;}
-
- /*!
- * \brief Set the produce limit.
- *
- * \param limit min or maximum items to produce (depending on produce_type)
- */
- void set_produce_limit (unsigned int limit) { d_min_produce=limit; d_max_produce=limit;}
-
- // ----------------------------------------------------------------------------
-
-
-
- protected:
- unsigned int d_sizeof_input_item;
- unsigned int d_sizeof_output_item;
- bool d_check_topology;
- char d_temp;
- gr_consume_type_t d_consume_type;
- int d_min_consume;
- int d_max_consume;
- gr_produce_type_t d_produce_type;
- int d_min_produce;
- int d_max_produce;
- gr_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
- int min_outputs, int max_outputs, unsigned int sizeof_output_item,
- unsigned int history,unsigned int output_multiple,double relative_rate,
- bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
-
-
-
- friend GR_RUNTIME_API gr_test_sptr gr_make_test (const std::string &name,int min_inputs, int max_inputs, unsigned int sizeof_input_item,
- int min_outputs, int max_outputs, unsigned int sizeof_output_item,
- unsigned int history,unsigned int output_multiple,double relative_rate,
- bool fixed_rate,gr_consume_type_t cons_type, gr_produce_type_t prod_type);
-};
-
-
-
-#endif /* INCLUDED_GR_TEST_H */
diff --git a/gnuradio-runtime/lib/gr_top_block.cc b/gnuradio-runtime/lib/gr_top_block.cc
deleted file mode 100644
index 362057aadb..0000000000
--- a/gnuradio-runtime/lib/gr_top_block.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-/* -*- c++ -*- */
-/*
- * 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 (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 <unistd.h>
-#include <gr_top_block.h>
-#include <gr_top_block_impl.h>
-#include <gr_io_signature.h>
-#include <gr_prefs.h>
-#include <iostream>
-
-gr_top_block_sptr
-gr_make_top_block(const std::string &name)
-{
- return gnuradio::get_initial_sptr(new gr_top_block(name));
-}
-
-gr_top_block::gr_top_block(const std::string &name)
- : gr_hier_block2(name,
- gr_make_io_signature(0,0,0),
- gr_make_io_signature(0,0,0))
-
-{
- d_impl = new gr_top_block_impl(this);
-}
-
-gr_top_block::~gr_top_block()
-{
- stop();
- wait();
-
- delete d_impl;
-}
-
-void
-gr_top_block::start(int max_noutput_items)
-{
- d_impl->start(max_noutput_items);
-
- if(gr_prefs::singleton()->get_bool("ControlPort", "on", false)) {
- setup_rpc();
- }
-}
-
-void
-gr_top_block::stop()
-{
- d_impl->stop();
-}
-
-void
-gr_top_block::wait()
-{
- d_impl->wait();
-}
-
-void
-gr_top_block::run(int max_noutput_items)
-{
- start(max_noutput_items);
- wait();
-}
-
-void
-gr_top_block::lock()
-{
- d_impl->lock();
-}
-
-void
-gr_top_block::unlock()
-{
- d_impl->unlock();
-}
-
-std::string
-gr_top_block::edge_list()
-{
- return d_impl->edge_list();
-}
-
-void
-gr_top_block::dump()
-{
- d_impl->dump();
-}
-
-int
-gr_top_block::max_noutput_items()
-{
- return d_impl->max_noutput_items();
-}
-
-void
-gr_top_block::set_max_noutput_items(int nmax)
-{
- d_impl->set_max_noutput_items(nmax);
-}
-
-gr_top_block_sptr
-gr_top_block::to_top_block()
-{
- return cast_to_top_block_sptr(shared_from_this());
-}
-
-void
-gr_top_block::setup_rpc()
-{
-#ifdef GR_CTRLPORT
- if(is_rpc_set()) return;
- // Getters
- add_rpc_variable(
- rpcbasic_sptr(new rpcbasic_register_get<gr_top_block, int>(
- alias(), "max noutput_items",
- &gr_top_block::max_noutput_items,
- pmt::mp(0), pmt::mp(8192), pmt::mp(8192),
- "items", "Max number of output items",
- RPC_PRIVLVL_MIN, DISPNULL)));
-
- if(gr_prefs::singleton()->get_bool("ControlPort", "edges_list", false)) {
- add_rpc_variable(
- rpcbasic_sptr(new rpcbasic_register_get<gr_top_block, std::string>(
- alias(), "edge list",
- &gr_top_block::edge_list,
- pmt::mp(""), pmt::mp(""), pmt::mp(""),
- "edges", "List of edges in the graph",
- RPC_PRIVLVL_MIN, DISPNULL)));
- }
-
- // Setters
- add_rpc_variable(
- rpcbasic_sptr(new rpcbasic_register_set<gr_top_block, int>(
- alias(), "max noutput_items",
- &gr_top_block::set_max_noutput_items,
- pmt::mp(0), pmt::mp(8192), pmt::mp(8192),
- "items", "Max number of output items",
- RPC_PRIVLVL_MIN, DISPNULL)));
- rpc_set();
-#endif /* GR_CTRLPORT */
-}
diff --git a/gnuradio-runtime/lib/gr_top_block_impl.cc b/gnuradio-runtime/lib/gr_top_block_impl.cc
deleted file mode 100644
index ef645ea57d..0000000000
--- a/gnuradio-runtime/lib/gr_top_block_impl.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gr_top_block.h>
-#include <gr_top_block_impl.h>
-#include <gr_flat_flowgraph.h>
-#include <gr_scheduler_sts.h>
-#include <gr_scheduler_tpb.h>
-#include <gr_prefs.h>
-
-#include <stdexcept>
-#include <iostream>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#define GR_TOP_BLOCK_IMPL_DEBUG 0
-
-
-typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg,
- int max_noutput_items);
-
-static struct scheduler_table {
- const char *name;
- scheduler_maker f;
-} scheduler_table[] = {
- { "TPB", gr_scheduler_tpb::make }, // first entry is default
- { "STS", gr_scheduler_sts::make }
-};
-
-static gr_scheduler_sptr
-make_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
-{
- static scheduler_maker factory = 0;
-
- if (factory == 0){
- char *v = getenv("GR_SCHEDULER");
- if (!v)
- factory = scheduler_table[0].f; // use default
- else {
- for (size_t i = 0; i < sizeof(scheduler_table)/sizeof(scheduler_table[0]); i++){
- if (strcmp(v, scheduler_table[i].name) == 0){
- factory = scheduler_table[i].f;
- break;
- }
- }
- if (factory == 0){
- std::cerr << "warning: Invalid GR_SCHEDULER environment variable value \""
- << v << "\". Using \"" << scheduler_table[0].name << "\"\n";
- factory = scheduler_table[0].f;
- }
- }
- }
- return factory(ffg, max_noutput_items);
-}
-
-
-gr_top_block_impl::gr_top_block_impl(gr_top_block *owner)
- : d_owner(owner), d_ffg(),
- d_state(IDLE), d_lock_count(0)
-{
-}
-
-gr_top_block_impl::~gr_top_block_impl()
-{
- d_owner = 0;
-}
-
-void
-gr_top_block_impl::start(int max_noutput_items)
-{
- gr::thread::scoped_lock l(d_mutex);
-
- d_max_noutput_items = max_noutput_items;
-
- if (d_state != IDLE)
- throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
-
- if (d_lock_count > 0)
- throw std::runtime_error("top_block::start: can't start with flow graph locked");
-
- // Create new flat flow graph by flattening hierarchy
- d_ffg = d_owner->flatten();
-
- // Validate new simple flow graph and wire it up
- d_ffg->validate();
- d_ffg->setup_connections();
-
- // Only export perf. counters if ControlPort config param is enabled
- // and if the PerfCounter option 'export' is turned on.
- gr_prefs *p = gr_prefs::singleton();
- if(p->get_bool("ControlPort", "on", false) && p->get_bool("PerfCounters", "export", false))
- d_ffg->enable_pc_rpc();
-
- d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
- d_state = RUNNING;
-}
-
-void
-gr_top_block_impl::stop()
-{
- if (d_scheduler)
- d_scheduler->stop();
-}
-
-
-void
-gr_top_block_impl::wait()
-{
- if (d_scheduler)
- d_scheduler->wait();
-
- d_state = IDLE;
-}
-
-// N.B. lock() and unlock() cannot be called from a flow graph thread or
-// deadlock will occur when reconfiguration happens
-void
-gr_top_block_impl::lock()
-{
- gr::thread::scoped_lock lock(d_mutex);
- d_lock_count++;
-}
-
-void
-gr_top_block_impl::unlock()
-{
- gr::thread::scoped_lock lock(d_mutex);
-
- if (d_lock_count <= 0){
- d_lock_count = 0; // fix it, then complain
- throw std::runtime_error("unpaired unlock() call");
- }
-
- d_lock_count--;
- if (d_lock_count > 0 || d_state == IDLE) // nothing to do
- return;
-
- restart();
-}
-
-/*
- * restart is called with d_mutex held
- */
-void
-gr_top_block_impl::restart()
-{
- stop(); // Stop scheduler and wait for completion
- wait();
-
- // Create new simple flow graph
- gr_flat_flowgraph_sptr new_ffg = d_owner->flatten();
- new_ffg->validate(); // check consistency, sanity, etc
- new_ffg->merge_connections(d_ffg); // reuse buffers, etc
- d_ffg = new_ffg;
-
- // Create a new scheduler to execute it
- d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
- d_state = RUNNING;
-}
-
-std::string
-gr_top_block_impl::edge_list()
-{
- if(d_ffg)
- return d_ffg->edge_list();
- else
- return "";
-}
-
-void
-gr_top_block_impl::dump()
-{
- if (d_ffg)
- d_ffg->dump();
-}
-
-int
-gr_top_block_impl::max_noutput_items()
-{
- return d_max_noutput_items;
-}
-
-void
-gr_top_block_impl::set_max_noutput_items(int nmax)
-{
- d_max_noutput_items = nmax;
-}
diff --git a/gnuradio-runtime/lib/gr_top_block_impl.h b/gnuradio-runtime/lib/gr_top_block_impl.h
deleted file mode 100644
index 345a33152f..0000000000
--- a/gnuradio-runtime/lib/gr_top_block_impl.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2007,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 INCLUDED_GR_TOP_BLOCK_IMPL_H
-#define INCLUDED_GR_TOP_BLOCK_IMPL_H
-
-#include <gr_runtime_api.h>
-#include <gr_scheduler.h>
-#include <thread/thread.h>
-
-/*!
- *\brief Abstract implementation details of gr_top_block
- * \ingroup internal
- *
- * The actual implementation of gr_top_block. Separate class allows
- * decoupling of changes from dependent classes.
- *
- */
-class GR_RUNTIME_API gr_top_block_impl
-{
-public:
- gr_top_block_impl(gr_top_block *owner);
- ~gr_top_block_impl();
-
- // Create and start scheduler threads
- void start(int max_noutput_items=100000000);
-
- // Signal scheduler threads to stop
- void stop();
-
- // Wait for scheduler threads to exit
- void wait();
-
- // Lock the top block to allow reconfiguration
- void lock();
-
- // Unlock the top block at end of reconfiguration
- void unlock();
-
- // Return a string list of edges
- std::string edge_list();
-
- // Dump the flowgraph to stdout
- void dump();
-
- // Get the number of max noutput_items in the flowgraph
- int max_noutput_items();
-
- // Set the maximum number of noutput_items in the flowgraph
- void set_max_noutput_items(int nmax);
-
-protected:
-
- enum tb_state { IDLE, RUNNING };
-
- gr_top_block *d_owner;
- gr_flat_flowgraph_sptr d_ffg;
- gr_scheduler_sptr d_scheduler;
-
- gr::thread::mutex d_mutex; // protects d_state and d_lock_count
- tb_state d_state;
- int d_lock_count;
- int d_max_noutput_items;
-
-private:
- void restart();
-};
-
-#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_H */
diff --git a/gnuradio-runtime/lib/gr_tpb_detail.cc b/gnuradio-runtime/lib/gr_tpb_detail.cc
deleted file mode 100644
index 46eb6bbe0d..0000000000
--- a/gnuradio-runtime/lib/gr_tpb_detail.cc
+++ /dev/null
@@ -1,70 +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 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 <gr_tpb_detail.h>
-#include <gr_block.h>
-#include <gr_block_detail.h>
-#include <gr_buffer.h>
-
-using namespace pmt;
-
-/*
- * We assume that no worker threads are ever running when the
- * graph structure is being manipulated, thus it's safe for us to poke
- * around in our neighbors w/o holding any locks.
- */
-
-void
-gr_tpb_detail::notify_upstream(gr_block_detail *d)
-{
- // For each of our inputs, tell the guy upstream that we've consumed
- // some input, and that he most likely has more output buffer space
- // available.
-
- for (size_t i = 0; i < d->d_input.size(); i++){
- // Can you say, "pointer chasing?"
- d->d_input[i]->buffer()->link()->detail()->d_tpb.set_output_changed();
- }
-}
-
-void
-gr_tpb_detail::notify_downstream(gr_block_detail *d)
-{
- // For each of our outputs, tell the guys downstream that they have
- // new input available.
-
- for (size_t i = 0; i < d->d_output.size(); i++){
- gr_buffer_sptr buf = d->d_output[i];
- for (size_t j = 0, k = buf->nreaders(); j < k; j++)
- buf->reader(j)->link()->detail()->d_tpb.set_input_changed();
- }
-}
-
-void
-gr_tpb_detail::notify_neighbors(gr_block_detail *d)
-{
- notify_downstream(d);
- notify_upstream(d);
-}
-
diff --git a/gnuradio-runtime/lib/gr_tpb_thread_body.cc b/gnuradio-runtime/lib/gr_tpb_thread_body.cc
deleted file mode 100644
index 11934dbf09..0000000000
--- a/gnuradio-runtime/lib/gr_tpb_thread_body.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2008,2009,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.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <gr_tpb_thread_body.h>
-#include <gr_prefs.h>
-#include <iostream>
-#include <boost/thread.hpp>
-#include <pmt/pmt.h>
-#include <boost/foreach.hpp>
-
-using namespace pmt;
-
-gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items)
- : d_exec(block, max_noutput_items)
-{
- //std::cerr << "gr_tpb_thread_body: " << block << std::endl;
-
- gr_block_detail *d = block->detail().get();
- gr_block_executor::state s;
- pmt_t msg;
-
- d->threaded = true;
- d->thread = gr::thread::get_current_thread_id();
-
- gr_prefs *p = gr_prefs::singleton();
- size_t max_nmsgs = static_cast<size_t>(p->get_long("DEFAULT", "max_messages", 100));
-
- // Set thread affinity if it was set before fg was started.
- if(block->processor_affinity().size() > 0) {
- gr::thread::thread_bind_to_processor(d->thread, block->processor_affinity());
- }
-
- while (1){
- boost::this_thread::interruption_point();
-
- // handle any queued up messages
- //BOOST_FOREACH( pmt::pmt_t port, block->msg_queue.keys() )
-
- BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
- {
- // Check if we have a message handler attached before getting
- // any messages. This is mostly a protection for the unknown
- // startup sequence of the threads.
- if(block->has_msg_handler(i.first)) {
- while ((msg = block->delete_head_nowait(i.first))){
- block->dispatch_msg(i.first,msg);
- }
- }
- else {
- // If we don't have a handler but are building up messages,
- // prune the queue from the front to keep memory in check.
- if(block->nmsgs(i.first) > max_nmsgs)
- msg = block->delete_head_nowait(i.first);
- }
- }
-
- 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 = gr_block_executor::BLKD_IN;
- }
-
- switch(s){
- case gr_block_executor::READY: // Tell neighbors we made progress.
- d->d_tpb.notify_neighbors(d);
- break;
-
- case gr_block_executor::READY_NO_OUTPUT: // Notify upstream only
- d->d_tpb.notify_upstream(d);
- break;
-
- case gr_block_executor::DONE: // Game over.
- d->d_tpb.notify_neighbors(d);
- return;
-
- case gr_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_p())
- d->d_tpb.input_cond.wait(guard);
-
- // handle all pending messages
- BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
- {
- while ((msg = block->delete_head_nowait(i.first))){
- guard.unlock(); // release lock while processing msg
- block->dispatch_msg(i.first, msg);
- guard.lock();
- }
- }
- }
- }
- break;
-
-
- case gr_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_p())
- d->d_tpb.output_cond.wait(guard);
-
- // handle all pending messages
- BOOST_FOREACH( gr_basic_block::msg_queue_map_t::value_type &i, block->msg_queue )
- {
- while ((msg = block->delete_head_nowait(i.first))){
- guard.unlock(); // release lock while processing msg
- block->dispatch_msg(i.first,msg);
- guard.lock();
- }
- }
- }
- }
- break;
-
- default:
- assert(0);
- }
- }
-}
-
-gr_tpb_thread_body::~gr_tpb_thread_body()
-{
-}
diff --git a/gnuradio-runtime/lib/gr_vco.h b/gnuradio-runtime/lib/gr_vco.h
deleted file mode 100644
index 3ceaf15dd4..0000000000
--- a/gnuradio-runtime/lib/gr_vco.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2005 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 _GR_VCO_H_
-#define _GR_VCO_H_
-
-
-#include <vector>
-#include <gr_sincos.h>
-#include <cmath>
-#include <gr_complex.h>
-
-/*!
- * \brief base class template for Voltage Controlled Oscillator (VCO)
- * \ingroup misc
- */
-
-//FIXME Eventually generalize this to fixed point
-
-template<class o_type, class i_type>
-class gr_vco {
-public:
- gr_vco () : d_phase (0) {}
-
- virtual ~gr_vco () {}
-
- // radians
- void set_phase (double angle) {
- d_phase = angle;
- }
-
- void adjust_phase (double delta_phase) {
- d_phase += delta_phase;
- if (fabs (d_phase) > M_PI){
-
- while (d_phase > M_PI)
- d_phase -= 2*M_PI;
-
- while (d_phase < -M_PI)
- d_phase += 2*M_PI;
- }
- }
-
- double get_phase () const { return d_phase; }
-
- // compute sin and cos for current phase angle
- void sincos (float *sinx, float *cosx) const;
-
- // compute cos or sin for current phase angle
- float cos () const { return std::cos (d_phase); }
- float sin () const { return std::sin (d_phase); }
-
- // compute a block at a time
- void cos (float *output, const float *input, int noutput_items, double k, double ampl = 1.0);
-
-protected:
- double d_phase;
-};
-
-template<class o_type, class i_type>
-void
-gr_vco<o_type,i_type>::sincos (float *sinx, float *cosx) const
-{
- gr_sincosf (d_phase, sinx, cosx);
-}
-
-template<class o_type, class i_type>
-void
-gr_vco<o_type,i_type>::cos (float *output, const float *input, int noutput_items, double k, double ampl)
-{
- for (int i = 0; i < noutput_items; i++){
- output[i] = cos() * ampl;
- adjust_phase(input[i] * k);
- }
-}
-#endif /* _GR_VCO_H_ */
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf.cc b/gnuradio-runtime/lib/gr_vmcircbuf.cc
deleted file mode 100644
index 522d9515d0..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf.cc
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <gr_vmcircbuf.h>
-#include <assert.h>
-#include <stdexcept>
-#include <gr_preferences.h>
-#include <stdio.h>
-#include <string.h>
-#include <gr_local_sighandler.h>
-#include <vector>
-#include <boost/format.hpp>
-
-// all the factories we know about
-#include <gr_vmcircbuf_createfilemapping.h>
-#include <gr_vmcircbuf_sysv_shm.h>
-#include <gr_vmcircbuf_mmap_shm_open.h>
-#include <gr_vmcircbuf_mmap_tmpfile.h>
-
-static const char *FACTORY_PREF_KEY = "gr_vmcircbuf_default_factory";
-
-gr_vmcircbuf::~gr_vmcircbuf ()
-{
-}
-
-gr_vmcircbuf_factory::~gr_vmcircbuf_factory ()
-{
-}
-
-// ----------------------------------------------------------------
-
-static gr_vmcircbuf_factory *s_default_factory = 0;
-
-gr_vmcircbuf_factory *
-gr_vmcircbuf_sysconfig::get_default_factory ()
-{
- if (s_default_factory)
- return s_default_factory;
-
- bool verbose = false;
-
- std::vector<gr_vmcircbuf_factory *> all = all_factories ();
-
- const char *name = gr_preferences::get (FACTORY_PREF_KEY);
-
- if (name){
- for (unsigned int i = 0; i < all.size (); i++){
- if (strcmp (name, all[i]->name ()) == 0){
- s_default_factory = all[i];
- if (verbose)
- fprintf (stderr, "gr_vmcircbuf_sysconfig: using %s\n",
- s_default_factory->name ());
- return s_default_factory;
- }
- }
- }
-
- // either we don't have a default, or the default named is not in our
- // list of factories. Find the first factory that works.
-
- if (verbose)
- fprintf (stderr, "gr_vmcircbuf_sysconfig: finding a working factory...\n");
-
- for (unsigned int i = 0; i < all.size (); i++){
- if (test_factory (all[i], verbose)){
- set_default_factory (all[i]);
- return s_default_factory;
- }
- }
-
- // We're screwed!
-
- fprintf (stderr, "gr_vmcircbuf_sysconfig: unable to find a working factory!\n");
- throw std::runtime_error ("gr_vmcircbuf_sysconfig");
-}
-
-std::vector<gr_vmcircbuf_factory *>
-gr_vmcircbuf_sysconfig::all_factories ()
-{
- std::vector<gr_vmcircbuf_factory *> result;
-
- result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ());
-#ifdef TRY_SHM_VMCIRCBUF
- result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ());
- result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ());
-#endif
- result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ());
-
- return result;
-}
-
-void
-gr_vmcircbuf_sysconfig::set_default_factory (gr_vmcircbuf_factory *f)
-{
- gr_preferences::set (FACTORY_PREF_KEY, f->name ());
- s_default_factory = f;
-}
-
-
-// ------------------------------------------------------------------------
-// test code for vmcircbuf factories
-// ------------------------------------------------------------------------
-
-static void
-init_buffer (gr_vmcircbuf *c, int counter, int size)
-{
- unsigned int *p = (unsigned int *) c->pointer_to_first_copy ();
- for (unsigned int i = 0; i < size / sizeof (int); i++)
- p[i] = counter + i;
-}
-
-static bool
-check_mapping (gr_vmcircbuf *c, int counter, int size, const char *msg, bool verbose)
-{
- bool ok = true;
-
- if (verbose)
- fprintf (stderr, "... %s", msg);
-
- unsigned int *p1 = (unsigned int *) c->pointer_to_first_copy ();
- unsigned int *p2 = (unsigned int *) c->pointer_to_second_copy ();
-
- // fprintf (stderr, "p1 = %p, p2 = %p\n", p1, p2);
-
- for (unsigned int i = 0; i < size / sizeof (int); i++){
- if (p1[i] != counter + i){
- ok = false;
- if (verbose)
- fprintf (stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
- break;
- }
- if (p2[i] != counter + i){
- if (verbose)
- fprintf (stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
- ok = false;
- break;
- }
- }
-
- if (ok && verbose){
- fprintf (stderr, " OK\n");
- }
- return ok;
-}
-
-static const char *
-memsize (int size)
-{
- static std::string buf;
- if (size >= (1 << 20)){
- buf = str(boost::format("%dMB") % (size / (1 << 20)));
- }
- else if (size >= (1 << 10)){
- buf = str(boost::format("%dKB") % (size / (1 << 10)));
- }
- else {
- buf = str(boost::format("%d") % size);
- }
- return buf.c_str();
-}
-
-static bool
-test_a_bunch (gr_vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
-{
- bool ok = true;
- std::vector<int> counter(n);
- std::vector<gr_vmcircbuf *> c(n);
- int cum_size = 0;
-
- for (int i = 0; i < n; i++){
- counter[i] = *start_ptr;
- *start_ptr += size;
- if ((c[i] = factory->make (size)) == 0){
- if (verbose)
- fprintf (stderr,
- "Failed to allocate gr_vmcircbuf number %d of size %d (cum = %s)\n",
- i + 1, size, memsize (cum_size));
- return false;
- }
- init_buffer (c[i], counter[i], size);
- cum_size += size;
- }
-
- for (int i = 0; i < n; i++){
- std::string msg = str(boost::format("test_a_bunch_%dx%s[%d]") % n % memsize (size) % i);
- ok &= check_mapping (c[i], counter[i], size, msg.c_str(), verbose);
- }
-
- for (int i = 0; i < n; i++){
- delete c[i];
- c[i] = 0;
- }
-
- return ok;
-}
-
-static bool
-standard_tests (gr_vmcircbuf_factory *f, int verbose)
-{
- if (verbose >= 1)
- fprintf (stderr, "Testing %s...\n", f->name ());
-
- bool v = verbose >= 2;
- int granularity = f->granularity ();
- int start = 0;
- bool ok = true;
-
- ok &= test_a_bunch (f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB
-
- if (ok){
- ok &= test_a_bunch (f, 64, 4 * granularity, &start, v); // 64 x 16KB = 1MB
- ok &= test_a_bunch (f, 4, 4 * (1L << 20), &start, v); // 4 x 4MB = 16MB
-// ok &= test_a_bunch (f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB
- }
-
- if (verbose >= 1)
- fprintf (stderr, "....... %s: %s", f->name (), ok ? "OK\n" : "Doesn't work\n");
-
- return ok;
-}
-
-bool
-gr_vmcircbuf_sysconfig::test_factory (gr_vmcircbuf_factory *f, int verbose)
-{
- // Install local signal handlers for SIGSEGV and SIGBUS.
- // If something goes wrong, these signals may be invoked.
-
-#ifdef SIGSEGV
- gr_local_sighandler sigsegv (SIGSEGV, gr_local_sighandler::throw_signal);
-#endif
-#ifdef SIGBUS
- gr_local_sighandler sigbus (SIGBUS, gr_local_sighandler::throw_signal);
-#endif
-#ifdef SIGSYS
- gr_local_sighandler sigsys (SIGSYS, gr_local_sighandler::throw_signal);
-#endif
-
- try {
- return standard_tests (f, verbose);
- }
- catch (gr_signal &sig){
- if (verbose){
- fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
- fprintf (stderr,
- "gr_vmcircbuf_factory::test_factory (%s): caught %s\n",
- f->name (), sig.name().c_str());
- return false;
- }
- }
- catch (...){
- if (verbose){
- fprintf (stderr, "....... %s: %s", f->name (), "Doesn't work\n");
- fprintf (stderr,
- "gr_vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
- f->name ());
- }
- return false;
- }
- return false; // never gets here. shut compiler up.
-}
-
-bool
-gr_vmcircbuf_sysconfig::test_all_factories (int verbose)
-{
- bool ok = false;
-
- std::vector<gr_vmcircbuf_factory *> all = all_factories ();
-
- for (unsigned int i = 0; i < all.size (); i++)
- ok |= test_factory (all[i], verbose);
-
- return ok;
-}
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf.h b/gnuradio-runtime/lib/gr_vmcircbuf.h
deleted file mode 100644
index e7f492a8bd..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _GR_VMCIRCBUF_H_
-#define _GR_VMCIRCBUF_H_
-
-#include <gr_runtime_api.h>
-#include <vector>
-
-/*!
- * \brief abstract class to implement doubly mapped virtual memory circular buffers
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_vmcircbuf {
- protected:
- int d_size;
- char *d_base;
-
- // CREATORS
- gr_vmcircbuf (int size) : d_size (size), d_base (0) {};
-
- public:
- virtual ~gr_vmcircbuf ();
-
- // ACCESSORS
- void *pointer_to_first_copy () const { return d_base; }
- void *pointer_to_second_copy () const { return d_base + d_size; }
-};
-
-/*!
- * \brief abstract factory for creating circular buffers
- */
-class GR_RUNTIME_API gr_vmcircbuf_factory {
- protected:
- gr_vmcircbuf_factory () {};
- virtual ~gr_vmcircbuf_factory ();
-
- public:
-
- /*!
- * \brief return name of this factory
- */
- virtual const char *name () const = 0;
-
- /*!
- * \brief return granularity of mapping, typically equal to page size
- */
- virtual int granularity () = 0;
-
- /*!
- * \brief return a gr_vmcircbuf, or 0 if unable.
- *
- * Call this to create a doubly mapped circular buffer.
- */
- virtual gr_vmcircbuf *make (int size) = 0;
-};
-
-/*
- * \brief pulls together all implementations of gr_vmcircbuf
- */
-class GR_RUNTIME_API gr_vmcircbuf_sysconfig {
- public:
-
- /*
- * \brief return the single instance of the default factory.
- *
- * returns the default factory to use if it's already defined,
- * else find the first working factory and use it.
- */
- static gr_vmcircbuf_factory *get_default_factory ();
-
-
- static int granularity () { return get_default_factory()->granularity(); }
- static gr_vmcircbuf *make (int size) { return get_default_factory()->make(size); }
-
-
- // N.B. not all factories are guaranteed to work.
- // It's too hard to check everything at config time, so we check at runtime
- static std::vector<gr_vmcircbuf_factory *> all_factories ();
-
- // make this factory the default
- static void set_default_factory (gr_vmcircbuf_factory *f);
-
- /*!
- * \brief Does this factory really work?
- *
- * verbose = 0: silent
- * verbose = 1: names of factories tested and results
- * verbose = 2: all intermediate results
- */
- static bool test_factory (gr_vmcircbuf_factory *f, int verbose);
-
- /*!
- * \brief Test all factories, return true if at least one of them works
- * verbose = 0: silent
- * verbose = 1: names of factories tested and results
- * verbose = 2: all intermediate results
- */
- static bool test_all_factories (int verbose);
-};
-
-
-#endif /* _GR_VMCIRCBUF_H_ */
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.cc b/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.cc
deleted file mode 100644
index 1b4d9700a5..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,2005,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 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 <stdexcept>
-#include <assert.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <errno.h>
-#include <stdio.h>
-#include <gr_pagesize.h>
-#include <gr_vmcircbuf_createfilemapping.h>
-#include <boost/format.hpp>
-
-#ifdef HAVE_CREATEFILEMAPPING
-// Print Windows error (could/should be global?)
-static void
-werror( char *where, DWORD last_error )
-{
- char buf[1024];
-
- FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- last_error,
- 0, // default language
- buf,
- sizeof(buf)/sizeof(TCHAR), // buffer size
- NULL );
- fprintf( stderr, "%s: Error %d: %s", where, last_error, buf );
- return;
-}
-#endif
-
-
-gr_vmcircbuf_createfilemapping::gr_vmcircbuf_createfilemapping (int size)
- : gr_vmcircbuf (size)
-{
-#if !defined(HAVE_CREATEFILEMAPPING)
- fprintf (stderr, "%s: createfilemapping is not available\n",__FUNCTION__);
- throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
-#else
- static int s_seg_counter = 0;
-
- if (size <= 0 || (size % gr_pagesize ()) != 0){
- fprintf (stderr, "gr_vmcircbuf_createfilemapping: invalid size = %d\n", size);
- throw std::runtime_error ("gr_vmcircbuf_createfilemapping");
- }
-
- std::string seg_name = str(boost::format("/gnuradio-%d-%d") % getpid () % s_seg_counter);
-
- d_handle = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
- NULL, // default security
- PAGE_READWRITE, // read/write access
- 0, // max. object size
- size, // buffer size
- seg_name.c_str()); // name of mapping object
-
- s_seg_counter++;
- if (d_handle == NULL || d_handle == INVALID_HANDLE_VALUE){
- std::string msg = str(boost::format(
- "gr_vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s]") %
- seg_name );
- werror((char *) msg.c_str(), GetLastError() );
- throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
- }
-
- // Allocate virtual memory of the needed size, then free it so we can use it
- LPVOID first_tmp;
- first_tmp = VirtualAlloc( NULL, 2*size, MEM_RESERVE, PAGE_NOACCESS );
- if (first_tmp == NULL){
- werror( "gr_vmcircbuf_mmap_createfilemapping: VirtualAlloc", GetLastError());
- CloseHandle(d_handle); // cleanup
- throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
- }
-
- if (VirtualFree(first_tmp, 0, MEM_RELEASE) == 0){
- werror( "gr_vmcircbuf_mmap_createfilemapping: VirtualFree", GetLastError());
- CloseHandle(d_handle); // cleanup
- throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
- }
-
- d_first_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
- FILE_MAP_WRITE, // read/write permission
- 0,
- 0,
- size,
- first_tmp);
- if (d_first_copy != first_tmp){
- werror( "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(1)", GetLastError());
- CloseHandle(d_handle); // cleanup
- throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
- }
-
- d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
- FILE_MAP_WRITE, // read/write permission
- 0,
- 0,
- size,
- (char *)first_tmp + size);//(LPVOID) ((char *)d_first_copy + size));
-
- if (d_second_copy != (char *)first_tmp + size){
- werror( "gr_vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(2)", GetLastError());
- UnmapViewOfFile(d_first_copy);
- CloseHandle(d_handle); // cleanup
- throw std::runtime_error ("gr_vmcircbuf_mmap_createfilemapping");
- }
-
-#ifdef DEBUG
- fprintf (stderr,"gr_vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p\n",
- (char *)d_first_copy, (char *)d_second_copy, size, (char *)d_first_copy + size);
-#endif
-
- // Now remember the important stuff
- d_base = (char *) d_first_copy;
- d_size = size;
-#endif /*HAVE_CREATEFILEMAPPING*/
-}
-
-gr_vmcircbuf_createfilemapping::~gr_vmcircbuf_createfilemapping ()
-{
-#ifdef HAVE_CREATEFILEMAPPING
- if (UnmapViewOfFile(d_first_copy) == 0)
- {
- werror("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)", GetLastError());
- }
- d_base=NULL;
- if (UnmapViewOfFile(d_second_copy) == 0)
- {
- werror("gr_vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)", GetLastError());
- }
- //d_second=NULL;
- CloseHandle(d_handle);
-#endif
-}
-
-// ----------------------------------------------------------------
-// The factory interface
-// ----------------------------------------------------------------
-
-
-gr_vmcircbuf_factory *gr_vmcircbuf_createfilemapping_factory::s_the_factory = 0;
-
-gr_vmcircbuf_factory *
-gr_vmcircbuf_createfilemapping_factory::singleton ()
-{
- if (s_the_factory)
- return s_the_factory;
- s_the_factory = new gr_vmcircbuf_createfilemapping_factory ();
- return s_the_factory;
-}
-
-int
-gr_vmcircbuf_createfilemapping_factory::granularity ()
-{
-#ifdef HAVE_CREATEFILEMAPPING
- // return 65536;//TODO, check, is this needed or can we just use gr_pagesize()
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
- return (int)system_info.dwAllocationGranularity;
-#else
- return gr_pagesize ();
-#endif
-}
-
-gr_vmcircbuf *
-gr_vmcircbuf_createfilemapping_factory::make (int size)
-{
- try
- {
- return new gr_vmcircbuf_createfilemapping (size);
- }
- catch (...)
- {
- return 0;
- }
-}
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.h b/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.h
deleted file mode 100644
index a4bb5cbe92..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_createfilemapping.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,2005 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 _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
-#define _GR_VMCIRCBUF_CREATEFILEMAPPING_H_
-
-#include <gr_runtime_api.h>
-#include <gr_vmcircbuf.h>
-
-#ifdef HAVE_CREATEFILEMAPPING
-#include <windows.h>
-#endif
-/*!
- * \brief concrete class to implement circular buffers with mmap and shm_open
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_vmcircbuf_createfilemapping : public gr_vmcircbuf
-{
- public:
- // CREATORS
- gr_vmcircbuf_createfilemapping (int size);
- virtual ~gr_vmcircbuf_createfilemapping ();
-#ifdef HAVE_CREATEFILEMAPPING
- private:
- HANDLE d_handle;
- LPVOID d_first_copy;
- LPVOID d_second_copy;
-#endif
-};
-
-/*!
- * \brief concrete factory for circular buffers built using mmap and shm_open
- */
-class GR_RUNTIME_API gr_vmcircbuf_createfilemapping_factory : public gr_vmcircbuf_factory
-{
- private:
- static gr_vmcircbuf_factory *s_the_factory;
-
- public:
- static gr_vmcircbuf_factory *singleton ();
-
- virtual const char *name () const { return "gr_vmcircbuf_createfilemapping_factory"; }
-
- /*!
- * \brief return granularity of mapping, typically equal to page size
- */
- virtual int granularity ();
-
- /*!
- * \brief return a gr_vmcircbuf, or 0 if unable.
- *
- * Call this to create a doubly mapped circular buffer.
- */
- virtual gr_vmcircbuf *make (int size);
-};
-
-#endif /* _GR_VMCIRCBUF_CREATEFILEMAPPING_H_ */
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.cc b/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.cc
deleted file mode 100644
index 3d170081d0..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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 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 <gr_vmcircbuf_mmap_shm_open.h>
-#include <stdexcept>
-#include <assert.h>
-#include <unistd.h>
-#include <fcntl.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <errno.h>
-#include <stdio.h>
-#include <gr_pagesize.h>
-#include <gr_sys_paths.h>
-
-
-gr_vmcircbuf_mmap_shm_open::gr_vmcircbuf_mmap_shm_open (int size)
- : gr_vmcircbuf (size)
-{
-#if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN)
- fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
-#else
- static int s_seg_counter = 0;
-
- if (size <= 0 || (size % gr_pagesize ()) != 0){
- fprintf (stderr, "gr_vmcircbuf_mmap_shm_open: invalid size = %d\n", size);
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
- int shm_fd = -1;
- char seg_name[1024];
- static bool portable_format = true;
-
- // open a new named shared memory segment
-
- while (1){
- if (portable_format){
-
- // This is the POSIX recommended "portable format".
- // Of course the "portable format" doesn't work on some systems...
-
- snprintf (seg_name, sizeof (seg_name),
- "/gnuradio-%d-%d", getpid (), s_seg_counter);
- }
- else {
-
- // Where the "portable format" doesn't work, we try building
- // a full filesystem pathname pointing into a suitable temporary directory.
-
- snprintf (seg_name, sizeof (seg_name),
- "%s/gnuradio-%d-%d", gr_tmp_path (), getpid (), s_seg_counter);
- }
-
- shm_fd = shm_open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (shm_fd == -1 && errno == EACCES && portable_format){
- portable_format = false;
- continue; // try again using "non-portable format"
- }
-
- s_seg_counter++;
-
- if (shm_fd == -1){
- if (errno == EEXIST) // Named segment already exists (shouldn't happen). Try again
- continue;
-
- char msg[1024];
- snprintf (msg, sizeof (msg), "gr_vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name);
- perror (msg);
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
- break;
- }
-
- // We've got a new shared memory segment fd open.
- // Now set it's length to 2x what we really want and mmap it in.
-
- if (ftruncate (shm_fd, (off_t) 2 * size) == -1){
- close (shm_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
- void *first_copy = mmap (0, 2 * size,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- shm_fd, (off_t) 0);
-
- if (first_copy == MAP_FAILED){
- close (shm_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_shm_open: mmap (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
- // unmap the 2nd half
- if (munmap ((char *) first_copy + size, size) == -1){
- close (shm_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_shm_open: munmap (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
- // map the first half into the now available hole where the
- // second half used to be.
-
- void *second_copy = mmap ((char *) first_copy + size, size,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- shm_fd, (off_t) 0);
-
- if (second_copy == MAP_FAILED){
- close (shm_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_shm_open: mmap (2)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
-#if 0 // OS/X doesn't allow you to resize the segment
-
- // cut the shared memory segment down to size
- if (ftruncate (shm_fd, (off_t) size) == -1){
- close (shm_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_shm_open: ftruncate (2)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-#endif
-
- close (shm_fd); // fd no longer needed. The mapping is retained.
-
- if (shm_unlink (seg_name) == -1){ // unlink the seg_name.
- perror ("gr_vmcircbuf_mmap_shm_open: shm_unlink");
- throw std::runtime_error ("gr_vmcircbuf_mmap_shm_open");
- }
-
- // Now remember the important stuff
-
- d_base = (char *) first_copy;
- d_size = size;
-#endif
-}
-
-gr_vmcircbuf_mmap_shm_open::~gr_vmcircbuf_mmap_shm_open ()
-{
-#if defined(HAVE_MMAP)
- if (munmap (d_base, 2 * d_size) == -1){
- perror ("gr_vmcircbuf_mmap_shm_open: munmap (2)");
- }
-#endif
-}
-
-// ----------------------------------------------------------------
-// The factory interface
-// ----------------------------------------------------------------
-
-
-gr_vmcircbuf_factory *gr_vmcircbuf_mmap_shm_open_factory::s_the_factory = 0;
-
-gr_vmcircbuf_factory *
-gr_vmcircbuf_mmap_shm_open_factory::singleton ()
-{
- if (s_the_factory)
- return s_the_factory;
-
- s_the_factory = new gr_vmcircbuf_mmap_shm_open_factory ();
- return s_the_factory;
-}
-
-int
-gr_vmcircbuf_mmap_shm_open_factory::granularity ()
-{
- return gr_pagesize ();
-}
-
-gr_vmcircbuf *
-gr_vmcircbuf_mmap_shm_open_factory::make (int size)
-{
- try {
- return new gr_vmcircbuf_mmap_shm_open (size);
- }
- catch (...){
- return 0;
- }
-}
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.h b/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.h
deleted file mode 100644
index d35df80839..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_shm_open.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
-#define _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_
-
-#include <gr_runtime_api.h>
-#include <gr_vmcircbuf.h>
-
-/*!
- * \brief concrete class to implement circular buffers with mmap and shm_open
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_vmcircbuf_mmap_shm_open : public gr_vmcircbuf {
- public:
-
- // CREATORS
-
- gr_vmcircbuf_mmap_shm_open (int size);
- virtual ~gr_vmcircbuf_mmap_shm_open ();
-};
-
-/*!
- * \brief concrete factory for circular buffers built using mmap and shm_open
- */
-class GR_RUNTIME_API gr_vmcircbuf_mmap_shm_open_factory : public gr_vmcircbuf_factory {
- private:
- static gr_vmcircbuf_factory *s_the_factory;
-
- public:
- static gr_vmcircbuf_factory *singleton ();
-
- virtual const char *name () const { return "gr_vmcircbuf_mmap_shm_open_factory"; }
-
- /*!
- * \brief return granularity of mapping, typically equal to page size
- */
- virtual int granularity ();
-
- /*!
- * \brief return a gr_vmcircbuf, or 0 if unable.
- *
- * Call this to create a doubly mapped circular buffer.
- */
- virtual gr_vmcircbuf *make (int size);
-};
-
-#endif /* _GR_VMCIRCBUF_MMAP_SHM_OPEN_H_ */
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.cc b/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.cc
deleted file mode 100644
index 35de64699e..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003,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 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 <gr_vmcircbuf_mmap_tmpfile.h>
-#include <stdexcept>
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <gr_pagesize.h>
-#include <gr_sys_paths.h>
-
-gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size)
- : gr_vmcircbuf (size)
-{
-#if !defined(HAVE_MMAP)
- fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
-#else
-
- if (size <= 0 || (size % gr_pagesize ()) != 0){
- fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- int seg_fd = -1;
- char seg_name[1024];
-
- static int s_seg_counter = 0;
-
-
- // open a temporary file that we'll map in a bit later
-
- while (1){
- snprintf (seg_name, sizeof (seg_name),
- "%s/gnuradio-%d-%d-XXXXXX", gr_tmp_path (), getpid (), s_seg_counter);
- s_seg_counter++;
-
- seg_fd = open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
- if (seg_fd == -1){
- if (errno == EEXIST) // File already exists (shouldn't happen). Try again
- continue;
-
- char msg[1024];
- snprintf (msg, sizeof (msg),
- "gr_vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
- perror (msg);
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
- break;
- }
-
- if (unlink (seg_name) == -1){
- perror ("gr_vmcircbuf_mmap_tmpfile: unlink");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- // We've got a valid file descriptor to a tmp file.
- // Now set it's length to 2x what we really want and mmap it in.
-
- if (ftruncate (seg_fd, (off_t) 2 * size) == -1){
- close (seg_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- void *first_copy = mmap (0, 2 * size,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- seg_fd, (off_t) 0);
-
- if (first_copy == MAP_FAILED){
- close (seg_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_tmpfile: mmap (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- // unmap the 2nd half
- if (munmap ((char *) first_copy + size, size) == -1){
- close (seg_fd); // cleanup
- perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- // map the first half into the now available hole where the
- // second half used to be.
-
- void *second_copy = mmap ((char *) first_copy + size, size,
- PROT_READ | PROT_WRITE, MAP_SHARED,
- seg_fd, (off_t) 0);
-
- if (second_copy == MAP_FAILED){
- munmap(first_copy, size); // cleanup
- close (seg_fd);
- perror ("gr_vmcircbuf_mmap_tmpfile: mmap (2)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- // check for contiguity
- if ((char *) second_copy != (char *) first_copy + size){
- munmap(first_copy, size); // cleanup
- munmap(second_copy, size);
- close (seg_fd);
- perror ("gr_vmcircbuf_mmap_tmpfile: non-contiguous second copy");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- // cut the tmp file down to size
- if (ftruncate (seg_fd, (off_t) size) == -1){
- munmap(first_copy, size); // cleanup
- munmap(second_copy, size);
- close (seg_fd);
- perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (2)");
- throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
- }
-
- close (seg_fd); // fd no longer needed. The mapping is retained.
-
- // Now remember the important stuff
-
- d_base = (char *) first_copy;
- d_size = size;
-#endif
-}
-
-gr_vmcircbuf_mmap_tmpfile::~gr_vmcircbuf_mmap_tmpfile ()
-{
-#if defined(HAVE_MMAP)
- if (munmap (d_base, 2 * d_size) == -1){
- perror ("gr_vmcircbuf_mmap_tmpfile: munmap (2)");
- }
-#endif
-}
-
-// ----------------------------------------------------------------
-// The factory interface
-// ----------------------------------------------------------------
-
-
-gr_vmcircbuf_factory *gr_vmcircbuf_mmap_tmpfile_factory::s_the_factory = 0;
-
-gr_vmcircbuf_factory *
-gr_vmcircbuf_mmap_tmpfile_factory::singleton ()
-{
- if (s_the_factory)
- return s_the_factory;
-
- s_the_factory = new gr_vmcircbuf_mmap_tmpfile_factory ();
- return s_the_factory;
-}
-
-int
-gr_vmcircbuf_mmap_tmpfile_factory::granularity ()
-{
- return gr_pagesize ();
-}
-
-gr_vmcircbuf *
-gr_vmcircbuf_mmap_tmpfile_factory::make (int size)
-{
- try {
- return new gr_vmcircbuf_mmap_tmpfile (size);
- }
- catch (...){
- return 0;
- }
-}
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.h b/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.h
deleted file mode 100644
index cd865734f2..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_mmap_tmpfile.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _GR_VMCIRCBUF_MMAP_TMPFILE_H_
-#define _GR_VMCIRCBUF_MMAP_TMPFILE_H_
-
-#include <gr_runtime_api.h>
-#include <gr_vmcircbuf.h>
-
-/*!
- * \brief concrete class to implement circular buffers with mmap and shm_open
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_vmcircbuf_mmap_tmpfile : public gr_vmcircbuf {
- public:
-
- // CREATORS
-
- gr_vmcircbuf_mmap_tmpfile (int size);
- virtual ~gr_vmcircbuf_mmap_tmpfile ();
-};
-
-/*!
- * \brief concrete factory for circular buffers built using mmap and shm_open
- */
-class GR_RUNTIME_API gr_vmcircbuf_mmap_tmpfile_factory : public gr_vmcircbuf_factory {
- private:
- static gr_vmcircbuf_factory *s_the_factory;
-
- public:
- static gr_vmcircbuf_factory *singleton ();
-
- virtual const char *name () const { return "gr_vmcircbuf_mmap_tmpfile_factory"; }
-
- /*!
- * \brief return granularity of mapping, typically equal to page size
- */
- virtual int granularity ();
-
- /*!
- * \brief return a gr_vmcircbuf, or 0 if unable.
- *
- * Call this to create a doubly mapped circular buffer.
- */
- virtual gr_vmcircbuf *make (int size);
-};
-
-#endif /* _GR_VMCIRCBUF_MMAP_TMPFILE_H_ */
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.cc b/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.cc
deleted file mode 100644
index d9cf75e70f..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 <gr_vmcircbuf_sysv_shm.h>
-#include <stdexcept>
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#ifdef HAVE_SYS_IPC_H
-#include <sys/ipc.h>
-#endif
-#ifdef HAVE_SYS_SHM_H
-#include <sys/shm.h>
-#endif
-#include <errno.h>
-#include <stdio.h>
-#include <gr_pagesize.h>
-
-
-gr_vmcircbuf_sysv_shm::gr_vmcircbuf_sysv_shm (int size)
- : gr_vmcircbuf (size)
-{
-#if !defined(HAVE_SYS_SHM_H)
- fprintf (stderr, "gr_vmcircbuf_sysv_shm: sysv shared memory is not available\n");
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
-#else
-
- int pagesize = gr_pagesize();
-
- if (size <= 0 || (size % pagesize) != 0){
- fprintf (stderr, "gr_vmcircbuf_sysv_shm: invalid size = %d\n", size);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- int shmid_guard = -1;
- int shmid1 = -1;
- int shmid2 = -1;
-
- // We use this as a guard page. We'll map it read-only on both ends of the buffer.
- // Ideally we'd map it no access, but I don't think that's possible with SysV
- if ((shmid_guard = shmget (IPC_PRIVATE, pagesize, IPC_CREAT | 0400)) == -1){
- perror ("gr_vmcircbuf_sysv_shm: shmget (0)");
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- if ((shmid2 = shmget (IPC_PRIVATE, 2 * size + 2 * pagesize, IPC_CREAT | 0700)) == -1){
- perror ("gr_vmcircbuf_sysv_shm: shmget (1)");
- shmctl (shmid_guard, IPC_RMID, 0);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- if ((shmid1 = shmget (IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1){
- perror ("gr_vmcircbuf_sysv_shm: shmget (2)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid2, IPC_RMID, 0);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- void *first_copy = shmat (shmid2, 0, 0);
- if (first_copy == (void *) -1){
- perror ("gr_vmcircbuf_sysv_shm: shmat (1)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid2, IPC_RMID, 0);
- shmctl (shmid1, IPC_RMID, 0);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- shmctl (shmid2, IPC_RMID, 0);
-
- // There may be a race between our detach and attach.
- //
- // If the system allocates all shared memory segments at the same
- // virtual addresses in all processes and if the system allocates
- // some other segment to first_copy or first_copoy + size between
- // our detach and attach, the attaches below could fail [I've never
- // seen it fail for this reason].
-
- shmdt (first_copy);
-
- // first read-only guard page
- if (shmat (shmid_guard, first_copy, SHM_RDONLY) == (void *) -1){
- perror ("gr_vmcircbuf_sysv_shm: shmat (2)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid1, IPC_RMID, 0);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- // first copy
- if (shmat (shmid1, (char *) first_copy + pagesize, 0) == (void *) -1){
- perror ("gr_vmcircbuf_sysv_shm: shmat (3)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid1, IPC_RMID, 0);
- shmdt (first_copy);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- // second copy
- if (shmat (shmid1, (char *) first_copy + pagesize + size, 0) == (void *) -1){
- perror ("gr_vmcircbuf_sysv_shm: shmat (4)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid1, IPC_RMID, 0);
- shmdt ((char *)first_copy + pagesize);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- // second read-only guard page
- if (shmat (shmid_guard, (char *) first_copy + pagesize + 2 * size, SHM_RDONLY) == (void *) -1){
- perror ("gr_vmcircbuf_sysv_shm: shmat (5)");
- shmctl (shmid_guard, IPC_RMID, 0);
- shmctl (shmid1, IPC_RMID, 0);
- shmdt (first_copy);
- shmdt ((char *)first_copy + pagesize);
- shmdt ((char *)first_copy + pagesize + size);
- throw std::runtime_error ("gr_vmcircbuf_sysv_shm");
- }
-
- shmctl (shmid1, IPC_RMID, 0);
- shmctl (shmid_guard, IPC_RMID, 0);
-
- // Now remember the important stuff
-
- d_base = (char *) first_copy + pagesize;
- d_size = size;
-#endif
-}
-
-gr_vmcircbuf_sysv_shm::~gr_vmcircbuf_sysv_shm ()
-{
-#if defined(HAVE_SYS_SHM_H)
- if (shmdt (d_base - gr_pagesize()) == -1
- || shmdt (d_base) == -1
- || shmdt (d_base + d_size) == -1
- || shmdt (d_base + 2 * d_size) == -1){
- perror ("gr_vmcircbuf_sysv_shm: shmdt (2)");
- }
-#endif
-}
-
-// ----------------------------------------------------------------
-// The factory interface
-// ----------------------------------------------------------------
-
-
-gr_vmcircbuf_factory *gr_vmcircbuf_sysv_shm_factory::s_the_factory = 0;
-
-gr_vmcircbuf_factory *
-gr_vmcircbuf_sysv_shm_factory::singleton ()
-{
- if (s_the_factory)
- return s_the_factory;
-
- s_the_factory = new gr_vmcircbuf_sysv_shm_factory ();
- return s_the_factory;
-}
-
-int
-gr_vmcircbuf_sysv_shm_factory::granularity ()
-{
- return gr_pagesize ();
-}
-
-gr_vmcircbuf *
-gr_vmcircbuf_sysv_shm_factory::make (int size)
-{
- try {
- return new gr_vmcircbuf_sysv_shm (size);
- }
- catch (...){
- return 0;
- }
-}
diff --git a/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.h b/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.h
deleted file mode 100644
index abebd93f1c..0000000000
--- a/gnuradio-runtime/lib/gr_vmcircbuf_sysv_shm.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003 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 _GR_VMCIRCBUF_SYSV_SHM_H_
-#define _GR_VMCIRCBUF_SYSV_SHM_H_
-
-#include <gr_runtime_api.h>
-#include <gr_vmcircbuf.h>
-
-/*!
- * \brief concrete class to implement circular buffers with mmap and shm_open
- * \ingroup internal
- */
-class GR_RUNTIME_API gr_vmcircbuf_sysv_shm : public gr_vmcircbuf {
- public:
-
- // CREATORS
-
- gr_vmcircbuf_sysv_shm (int size);
- virtual ~gr_vmcircbuf_sysv_shm ();
-};
-
-/*!
- * \brief concrete factory for circular buffers built using mmap and shm_open
- */
-class GR_RUNTIME_API gr_vmcircbuf_sysv_shm_factory : public gr_vmcircbuf_factory {
- private:
- static gr_vmcircbuf_factory *s_the_factory;
-
- public:
- static gr_vmcircbuf_factory *singleton ();
-
- virtual const char *name () const { return "gr_vmcircbuf_sysv_shm_factory"; }
-
- /*!
- * \brief return granularity of mapping, typically equal to page size
- */
- virtual int granularity ();
-
- /*!
- * \brief return a gr_vmcircbuf, or 0 if unable.
- *
- * Call this to create a doubly mapped circular buffer.
- */
- virtual gr_vmcircbuf *make (int size);
-};
-
-#endif /* _GR_VMCIRCBUF_SYSV_SHM_H_ */
diff --git a/gnuradio-runtime/lib/gri_debugger_hook.cc b/gnuradio-runtime/lib/gri_debugger_hook.cc
deleted file mode 100644
index d9270c435f..0000000000
--- a/gnuradio-runtime/lib/gri_debugger_hook.cc
+++ /dev/null
@@ -1,29 +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.
- */
-
-#include <gri_debugger_hook.h>
-
-void
-gri_debugger_hook ()
-{
- // nop. set a breakpoint here
-}
diff --git a/gnuradio-runtime/lib/hier_block2.cc b/gnuradio-runtime/lib/hier_block2.cc
new file mode 100644
index 0000000000..f26da18e54
--- /dev/null
+++ b/gnuradio-runtime/lib/hier_block2.cc
@@ -0,0 +1,160 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006-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 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 <gnuradio/hier_block2.h>
+#include <gnuradio/io_signature.h>
+#include "hier_block2_detail.h"
+#include <iostream>
+
+namespace gr {
+
+#define GR_HIER_BLOCK2_DEBUG 0
+
+ hier_block2_sptr
+ make_hier_block2(const std::string &name,
+ gr::io_signature::sptr input_signature,
+ gr::io_signature::sptr output_signature)
+ {
+ return gnuradio::get_initial_sptr
+ (new hier_block2(name, input_signature, output_signature));
+ }
+
+ hier_block2::hier_block2(const std::string &name,
+ gr::io_signature::sptr input_signature,
+ gr::io_signature::sptr output_signature)
+ : basic_block(name, input_signature, output_signature),
+ d_detail(new hier_block2_detail(this)),
+ hier_message_ports_in(pmt::PMT_NIL),
+ hier_message_ports_out(pmt::PMT_NIL)
+ {
+ // This bit of magic ensures that self() works in the constructors of derived classes.
+ gnuradio::detail::sptr_magic::create_and_stash_initial_sptr(this);
+ }
+
+ hier_block2::~hier_block2()
+ {
+ delete d_detail;
+ }
+
+ hier_block2::opaque_self
+ hier_block2::self()
+ {
+ return shared_from_this();
+ }
+
+ hier_block2_sptr
+ hier_block2::to_hier_block2()
+ {
+ return cast_to_hier_block2_sptr(shared_from_this());
+ }
+
+ void
+ hier_block2::connect(basic_block_sptr block)
+ {
+ d_detail->connect(block);
+ }
+
+ void
+ hier_block2::connect(basic_block_sptr src, int src_port,
+ basic_block_sptr dst, int dst_port)
+ {
+ d_detail->connect(src, src_port, dst, dst_port);
+ }
+
+ void
+ hier_block2::msg_connect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport)
+ {
+ if(!pmt::is_symbol(srcport)) {
+ throw std::runtime_error("bad port id");
+ }
+ d_detail->msg_connect(src, srcport, dst, dstport);
+ }
+
+ void
+ hier_block2::msg_connect(basic_block_sptr src, std::string srcport,
+ basic_block_sptr dst, std::string dstport)
+ {
+ d_detail->msg_connect(src, pmt::mp(srcport), dst, pmt::mp(dstport));
+ }
+
+ void
+ hier_block2::msg_disconnect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport)
+ {
+ if(!pmt::is_symbol(srcport)) {
+ throw std::runtime_error("bad port id");
+ }
+ d_detail->msg_disconnect(src, srcport, dst, dstport);
+ }
+
+ void
+ hier_block2::msg_disconnect(basic_block_sptr src, std::string srcport,
+ basic_block_sptr dst, std::string dstport)
+ {
+ d_detail->msg_disconnect(src, pmt::mp(srcport), dst, pmt::mp(dstport));
+ }
+
+ void
+ hier_block2::disconnect(basic_block_sptr block)
+ {
+ d_detail->disconnect(block);
+ }
+
+ void
+ hier_block2::disconnect(basic_block_sptr src, int src_port,
+ basic_block_sptr dst, int dst_port)
+ {
+ d_detail->disconnect(src, src_port, dst, dst_port);
+ }
+
+ void
+ hier_block2::disconnect_all()
+ {
+ d_detail->disconnect_all();
+ }
+
+ void
+ hier_block2::lock()
+ {
+ d_detail->lock();
+ }
+
+ void
+ hier_block2::unlock()
+ {
+ d_detail->unlock();
+ }
+
+ flat_flowgraph_sptr
+ hier_block2::flatten() const
+ {
+ flat_flowgraph_sptr new_ffg = make_flat_flowgraph();
+ d_detail->flatten_aux(new_ffg);
+ return new_ffg;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/hier_block2_detail.cc b/gnuradio-runtime/lib/hier_block2_detail.cc
new file mode 100644
index 0000000000..83207d978c
--- /dev/null
+++ b/gnuradio-runtime/lib/hier_block2_detail.cc
@@ -0,0 +1,657 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2009,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hier_block2_detail.h"
+#include <gnuradio/io_signature.h>
+#include <gnuradio/prefs.h>
+#include <stdexcept>
+#include <sstream>
+#include <boost/format.hpp>
+
+namespace gr {
+
+#define HIER_BLOCK2_DETAIL_DEBUG 0
+
+ hier_block2_detail::hier_block2_detail(hier_block2 *owner)
+ : d_owner(owner),
+ d_parent_detail(0),
+ d_fg(make_flowgraph())
+ {
+ int min_inputs = owner->input_signature()->min_streams();
+ int max_inputs = owner->input_signature()->max_streams();
+ int min_outputs = owner->output_signature()->min_streams();
+ int max_outputs = owner->output_signature()->max_streams();
+
+ if(max_inputs == io_signature::IO_INFINITE ||
+ max_outputs == io_signature::IO_INFINITE ||
+ (min_inputs != max_inputs) ||(min_outputs != max_outputs) ) {
+ std::stringstream msg;
+ msg << "Hierarchical blocks do not yet support arbitrary or"
+ << " variable numbers of inputs or outputs (" << d_owner->name() << ")";
+ throw std::runtime_error(msg.str());
+ }
+
+ d_inputs = std::vector<endpoint_vector_t>(max_inputs);
+ d_outputs = endpoint_vector_t(max_outputs);
+ }
+
+ hier_block2_detail::~hier_block2_detail()
+ {
+ d_owner = 0; // Don't use delete, we didn't allocate
+ }
+
+ void
+ hier_block2_detail::connect(basic_block_sptr block)
+ {
+ std::stringstream msg;
+
+ // Check if duplicate
+ if(std::find(d_blocks.begin(), d_blocks.end(), block) != d_blocks.end()) {
+ msg << "Block " << block << " already connected.";
+ throw std::invalid_argument(msg.str());
+ }
+
+ // Check if has inputs or outputs
+ if(block->input_signature()->max_streams() != 0 ||
+ block->output_signature()->max_streams() != 0) {
+ msg << "Block " << block << " must not have any input or output ports";
+ throw std::invalid_argument(msg.str());
+ }
+
+ hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
+
+ if(hblock && hblock.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: block is hierarchical, setting parent to " << this << std::endl;
+ hblock->d_detail->d_parent_detail = this;
+ }
+
+ d_blocks.push_back(block);
+ }
+
+ void
+ hier_block2_detail::connect(basic_block_sptr src, int src_port,
+ basic_block_sptr dst, int dst_port)
+ {
+ std::stringstream msg;
+
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connecting: " << endpoint(src, src_port)
+ << " -> " << endpoint(dst, dst_port) << std::endl;
+
+ if(src.get() == dst.get())
+ throw std::invalid_argument("connect: src and destination blocks cannot be the same");
+
+ hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if(src_block && src.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
+ src_block->d_detail->d_parent_detail = this;
+ }
+
+ if(dst_block && dst.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
+ dst_block->d_detail->d_parent_detail = this;
+ }
+
+ // Connections to block inputs or outputs
+ int max_port;
+ if(src.get() == d_owner) {
+ max_port = src->input_signature()->max_streams();
+ if((max_port != -1 && (src_port >= max_port)) || src_port < 0) {
+ msg << "source port " << src_port << " out of range for " << src;
+ throw std::invalid_argument(msg.str());
+ }
+
+ return connect_input(src_port, dst_port, dst);
+ }
+
+ if(dst.get() == d_owner) {
+ max_port = dst->output_signature()->max_streams();
+ if((max_port != -1 && (dst_port >= max_port)) || dst_port < 0) {
+ msg << "destination port " << dst_port << " out of range for " << dst;
+ throw std::invalid_argument(msg.str());
+ }
+
+ return connect_output(dst_port, src_port, src);
+ }
+
+ // Internal connections
+ d_fg->connect(src, src_port, dst, dst_port);
+
+ // TODO: connects to NC
+ }
+
+ void
+ hier_block2_detail::msg_connect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport)
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connecting message port..." << std::endl;
+
+ // register the subscription
+ // this is done later...
+ // src->message_port_sub(srcport, pmt::cons(dst->alias_pmt(), dstport));
+
+ // add block uniquely to list to internal blocks
+ if(std::find(d_blocks.begin(), d_blocks.end(), dst) == d_blocks.end()){
+ d_blocks.push_back(src);
+ d_blocks.push_back(dst);
+ }
+
+ bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
+ bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
+
+ hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if(src_block && src.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: src is hierarchical, setting parent to " << this << std::endl;
+ src_block->d_detail->d_parent_detail = this;
+ }
+
+ if(dst_block && dst.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "connect: dst is hierarchical, setting parent to " << this << std::endl;
+ dst_block->d_detail->d_parent_detail = this;
+ }
+
+ // add edge for this message connection
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format("connect( (%s, %s, %d), (%s, %s, %d) )\n") % \
+ src % srcport % hier_out %
+ dst % dstport % hier_in;
+ d_fg->connect(msg_endpoint(src, srcport, hier_out), msg_endpoint(dst, dstport, hier_in));
+ }
+
+ void
+ hier_block2_detail::msg_disconnect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport)
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnecting message port..." << std::endl;
+
+ // unregister the subscription - if already subscribed
+ src->message_port_unsub(srcport, pmt::cons(dst->alias_pmt(), dstport));
+
+ // remove edge for this message connection
+ bool hier_out = (d_owner == src.get()) && src->message_port_is_hier_out(srcport);;
+ bool hier_in = (d_owner == dst.get()) && dst->message_port_is_hier_in(dstport);
+ d_fg->disconnect(msg_endpoint(src, srcport, hier_out), msg_endpoint(dst, dstport, hier_in));
+ }
+
+ void
+ hier_block2_detail::disconnect(basic_block_sptr block)
+ {
+ // Check on singleton list
+ for(basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+ if(*p == block) {
+ d_blocks.erase(p);
+
+ hier_block2_sptr hblock(cast_to_hier_block2_sptr(block));
+ if(block && block.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: block is hierarchical, clearing parent" << std::endl;
+ hblock->d_detail->d_parent_detail = 0;
+ }
+
+ return;
+ }
+ }
+
+ // Otherwise find all edges containing block
+ edge_vector_t edges, tmp = d_fg->edges();
+ edge_vector_t::iterator p;
+ for(p = tmp.begin(); p != tmp.end(); p++) {
+ if((*p).src().block() == block || (*p).dst().block() == block) {
+ edges.push_back(*p);
+
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: block found in edge " << (*p) << std::endl;
+ }
+ }
+
+ if(edges.size() == 0) {
+ std::stringstream msg;
+ msg << "cannot disconnect block " << block << ", not found";
+ throw std::invalid_argument(msg.str());
+ }
+
+ for(p = edges.begin(); p != edges.end(); p++) {
+ disconnect((*p).src().block(), (*p).src().port(),
+ (*p).dst().block(), (*p).dst().port());
+ }
+ }
+
+ void
+ hier_block2_detail::disconnect(basic_block_sptr src, int src_port,
+ basic_block_sptr dst, int dst_port)
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnecting: " << endpoint(src, src_port)
+ << " -> " << endpoint(dst, dst_port) << std::endl;
+
+ if(src.get() == dst.get())
+ throw std::invalid_argument("disconnect: source and destination blocks cannot be the same");
+
+ hier_block2_sptr src_block(cast_to_hier_block2_sptr(src));
+ hier_block2_sptr dst_block(cast_to_hier_block2_sptr(dst));
+
+ if(src_block && src.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: src is hierarchical, clearing parent" << std::endl;
+ src_block->d_detail->d_parent_detail = 0;
+ }
+
+ if(dst_block && dst.get() != d_owner) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "disconnect: dst is hierarchical, clearing parent" << std::endl;
+ dst_block->d_detail->d_parent_detail = 0;
+ }
+
+ if(src.get() == d_owner)
+ return disconnect_input(src_port, dst_port, dst);
+
+ if(dst.get() == d_owner)
+ return disconnect_output(dst_port, src_port, src);
+
+ // Internal connections
+ d_fg->disconnect(src, src_port, dst, dst_port);
+ }
+
+ void
+ hier_block2_detail::connect_input(int my_port, int port,
+ basic_block_sptr block)
+ {
+ std::stringstream msg;
+
+ if(my_port < 0 || my_port >= (signed)d_inputs.size()) {
+ msg << "input port " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endpoint_vector_t &endps = d_inputs[my_port];
+ endpoint endp(block, port);
+
+ endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if(p != endps.end()) {
+ msg << "external input port " << my_port << " already wired to " << endp;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endps.push_back(endp);
+ }
+
+ void
+ hier_block2_detail::connect_output(int my_port, int port,
+ basic_block_sptr block)
+ {
+ std::stringstream msg;
+
+ if(my_port < 0 || my_port >= (signed)d_outputs.size()) {
+ msg << "output port " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ if(d_outputs[my_port].block()) {
+ msg << "external output port " << my_port << " already connected from "
+ << d_outputs[my_port];
+ throw std::invalid_argument(msg.str());
+ }
+
+ d_outputs[my_port] = endpoint(block, port);
+ }
+
+ void
+ hier_block2_detail::disconnect_input(int my_port, int port,
+ basic_block_sptr block)
+ {
+ std::stringstream msg;
+
+ if(my_port < 0 || my_port >= (signed)d_inputs.size()) {
+ msg << "input port number " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endpoint_vector_t &endps = d_inputs[my_port];
+ endpoint endp(block, port);
+
+ endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if(p == endps.end()) {
+ msg << "external input port " << my_port << " not connected to " << endp;
+ throw std::invalid_argument(msg.str());
+ }
+
+ endps.erase(p);
+ }
+
+ void
+ hier_block2_detail::disconnect_output(int my_port, int port,
+ basic_block_sptr block)
+ {
+ std::stringstream msg;
+
+ if(my_port < 0 || my_port >= (signed)d_outputs.size()) {
+ msg << "output port number " << my_port << " out of range for " << block;
+ throw std::invalid_argument(msg.str());
+ }
+
+ if(d_outputs[my_port].block() != block) {
+ msg << "block " << block << " not assigned to output "
+ << my_port << ", can't disconnect";
+ throw std::invalid_argument(msg.str());
+ }
+
+ d_outputs[my_port] = endpoint();
+ }
+
+ endpoint_vector_t
+ hier_block2_detail::resolve_port(int port, bool is_input)
+ {
+ std::stringstream msg;
+
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Resolving port " << port << " as an "
+ << (is_input ? "input" : "output")
+ << " of " << d_owner->name() << std::endl;
+
+ endpoint_vector_t result;
+
+ if(is_input) {
+ if(port < 0 || port >= (signed)d_inputs.size()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': input " << port << " is out of range";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(d_inputs[port].empty()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': input " << port << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ endpoint_vector_t &endps = d_inputs[port];
+ endpoint_viter_t p;
+ for(p = endps.begin(); p != endps.end(); p++) {
+ endpoint_vector_t tmp = resolve_endpoint(*p, true);
+ std::copy(tmp.begin(), tmp.end(), back_inserter(result));
+ }
+ }
+ else {
+ if(port < 0 || port >= (signed)d_outputs.size()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': output " << port << " is out of range";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(d_outputs[port] == endpoint()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': output " << port << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ result = resolve_endpoint(d_outputs[port], false);
+ }
+
+ if(result.empty()) {
+ msg << "resolve_port: hierarchical block '" << d_owner->name()
+ << "': unable to resolve "
+ << (is_input ? "input port " : "output port ")
+ << port;
+ throw std::runtime_error(msg.str());
+ }
+
+ return result;
+ }
+
+ void
+ hier_block2_detail::disconnect_all()
+ {
+ d_fg->clear();
+ d_blocks.clear();
+ d_inputs.clear();
+ d_outputs.clear();
+ }
+
+ endpoint_vector_t
+ hier_block2_detail::resolve_endpoint(const endpoint &endp, bool is_input) const
+ {
+ std::stringstream msg;
+ endpoint_vector_t result;
+
+ // Check if endpoint is a leaf node
+ if(cast_to_block_sptr(endp.block())) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Block " << endp.block() << " is a leaf node, returning." << std::endl;
+ result.push_back(endp);
+ return result;
+ }
+
+ // Check if endpoint is a hierarchical block
+ hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(endp.block()));
+ if(hier_block2) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Resolving endpoint " << endp << " as an "
+ << (is_input ? "input" : "output")
+ << ", recursing" << std::endl;
+ return hier_block2->d_detail->resolve_port(endp.port(), is_input);
+ }
+
+ msg << "unable to resolve" << (is_input ? " input " : " output ")
+ << "endpoint " << endp;
+ throw std::runtime_error(msg.str());
+ }
+
+ void
+ hier_block2_detail::flatten_aux(flat_flowgraph_sptr sfg) const
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << " ** Flattening " << d_owner->name() << std::endl;
+
+ // Add my edges to the flow graph, resolving references to actual endpoints
+ edge_vector_t edges = d_fg->edges();
+ msg_edge_vector_t msg_edges = d_fg->msg_edges();
+ edge_viter_t p;
+ msg_edge_viter_t q,u;
+
+ // Only run setup_rpc if ControlPort config param is enabled.
+ bool ctrlport_on = prefs::singleton()->get_bool("ControlPort", "on", false);
+
+ // For every block (gr::block and gr::hier_block2), set up the RPC
+ // interface.
+ for(p = edges.begin(); p != edges.end(); p++) {
+ basic_block_sptr b;
+ b = p->src().block();
+
+ if(ctrlport_on) {
+ if(!b->is_rpc_set()) {
+ b->setup_rpc();
+ b->rpc_set();
+ }
+ }
+
+ b = p->dst().block();
+ if(ctrlport_on) {
+ if(!b->is_rpc_set()) {
+ b->setup_rpc();
+ b->rpc_set();
+ }
+ }
+ }
+
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening stream connections: " << std::endl;
+
+ for(p = edges.begin(); p != edges.end(); p++) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening edge " << (*p) << std::endl;
+
+ endpoint_vector_t src_endps = resolve_endpoint(p->src(), false);
+ endpoint_vector_t dst_endps = resolve_endpoint(p->dst(), true);
+
+ endpoint_viter_t s, d;
+ for(s = src_endps.begin(); s != src_endps.end(); s++) {
+ for(d = dst_endps.begin(); d != dst_endps.end(); d++) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << (*s) << "->" << (*d) << std::endl;
+ sfg->connect(*s, *d);
+ }
+ }
+ }
+
+ // loop through flattening hierarchical connections
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "Flattening msg connections: " << std::endl;
+
+ std::vector<std::pair<msg_endpoint, bool> > resolved_endpoints;
+ for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" flattening edge ( %s, %s, %d) -> ( %s, %s, %d)\n") % \
+ q->src().block() % q->src().port() % q->src().is_hier() % q->dst().block() % \
+ q->dst().port() % q->dst().is_hier();
+
+ bool normal_connection = true;
+
+ // resolve existing connections to hier ports
+ if(q->dst().is_hier()) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" resolve hier output (%s, %s)") % \
+ q->dst().block() % q->dst().port() << std::endl;
+ sfg->replace_endpoint( q->dst(), q->src(), true );
+ resolved_endpoints.push_back(std::pair<msg_endpoint, bool>(q->dst(),true));
+ normal_connection = false;
+ }
+
+ if(q->src().is_hier()) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << boost::format(" resolve hier input (%s, %s)") % \
+ q->src().block() % q->src().port() << std::endl;
+ sfg->replace_endpoint( q->src(), q->dst(), false );
+ resolved_endpoints.push_back(std::pair<msg_endpoint, bool>(q->src(),false));
+ normal_connection = false;
+ }
+
+ // propogate non hier connections through
+ if(normal_connection){
+ sfg->connect( q->src(), q->dst() );
+ }
+ }
+
+ for(std::vector<std::pair<msg_endpoint, bool> >::iterator it = resolved_endpoints.begin();
+ it != resolved_endpoints.end(); it++) {
+ sfg->clear_endpoint((*it).first, (*it).second);
+ }
+
+ /*
+ // connect primitive edges in the new fg
+ for(q = msg_edges.begin(); q != msg_edges.end(); q++) {
+ if((!q->src().is_hier()) && (!q->dst().is_hier())) {
+ sfg->connect(q->src(), q->dst());
+ }
+ else {
+ std::cout << "not connecting hier connection!" << std::endl;
+ }
+ }
+ */
+
+ // Construct unique list of blocks used either in edges, inputs,
+ // outputs, or by themselves. I still hate STL.
+ basic_block_vector_t blocks; // unique list of used blocks
+ basic_block_vector_t tmp = d_fg->calc_used_blocks();
+
+ // First add the list of singleton blocks
+ std::vector<basic_block_sptr>::const_iterator b; // Because flatten_aux is const
+ for(b = d_blocks.begin(); b != d_blocks.end(); b++)
+ tmp.push_back(*b);
+
+ // Now add the list of connected input blocks
+ std::stringstream msg;
+ for(unsigned int i = 0; i < d_inputs.size(); i++) {
+ if(d_inputs[i].size() == 0) {
+ msg << "In hierarchical block " << d_owner->name() << ", input " << i
+ << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+
+ for(unsigned int j = 0; j < d_inputs[i].size(); j++)
+ tmp.push_back(d_inputs[i][j].block());
+ }
+
+ for(unsigned int i = 0; i < d_outputs.size(); i++) {
+ basic_block_sptr blk = d_outputs[i].block();
+ if(!blk) {
+ msg << "In hierarchical block " << d_owner->name() << ", output " << i
+ << " is not connected internally";
+ throw std::runtime_error(msg.str());
+ }
+ tmp.push_back(blk);
+ }
+ sort(tmp.begin(), tmp.end());
+
+ std::insert_iterator<basic_block_vector_t> inserter(blocks, blocks.begin());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ // Recurse hierarchical children
+ for(basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ hier_block2_sptr hier_block2(cast_to_hier_block2_sptr(*p));
+ if(hier_block2 && (hier_block2.get() != d_owner)) {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "flatten_aux: recursing into hierarchical block "
+ << hier_block2 << std::endl;
+ hier_block2->d_detail->flatten_aux(sfg);
+ }
+ }
+ }
+
+ void
+ hier_block2_detail::lock()
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "lock: entered in " << this << std::endl;
+
+ if(d_parent_detail)
+ d_parent_detail->lock();
+ else
+ d_owner->lock();
+ }
+
+ void
+ hier_block2_detail::unlock()
+ {
+ if(HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << "unlock: entered in " << this << std::endl;
+
+ if(d_parent_detail)
+ d_parent_detail->unlock();
+ else
+ d_owner->unlock();
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/hier_block2_detail.h b/gnuradio-runtime/lib/hier_block2_detail.h
new file mode 100644
index 0000000000..99bf6e8ef1
--- /dev/null
+++ b/gnuradio-runtime/lib/hier_block2_detail.h
@@ -0,0 +1,77 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,2009,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.
+ */
+
+#ifndef INCLUDED_GR_RUNTIME_HIER_BLOCK2_DETAIL_H
+#define INCLUDED_GR_RUNTIME_HIER_BLOCK2_DETAIL_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/hier_block2.h>
+#include <flat_flowgraph.h>
+#include <boost/utility.hpp>
+
+namespace gr {
+
+ /*!
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API hier_block2_detail : boost::noncopyable
+ {
+ public:
+ hier_block2_detail(hier_block2 *owner);
+ ~hier_block2_detail();
+
+ void connect(basic_block_sptr block);
+ void connect(basic_block_sptr src, int src_port,
+ basic_block_sptr dst, int dst_port);
+ void msg_connect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport);
+ void msg_disconnect(basic_block_sptr src, pmt::pmt_t srcport,
+ basic_block_sptr dst, pmt::pmt_t dstport);
+ void disconnect(basic_block_sptr block);
+ void disconnect(basic_block_sptr, int src_port,
+ basic_block_sptr, int dst_port);
+ void disconnect_all();
+ void lock();
+ void unlock();
+ void flatten_aux(flat_flowgraph_sptr sfg) const;
+
+ private:
+ // Private implementation data
+ hier_block2 *d_owner;
+ hier_block2_detail *d_parent_detail;
+ flowgraph_sptr d_fg;
+ std::vector<endpoint_vector_t> d_inputs; // Multiple internal endpoints per external input
+ endpoint_vector_t d_outputs; // Single internal endpoint per external output
+ basic_block_vector_t d_blocks;
+
+ void connect_input(int my_port, int port, basic_block_sptr block);
+ void connect_output(int my_port, int port, basic_block_sptr block);
+ void disconnect_input(int my_port, int port, basic_block_sptr block);
+ void disconnect_output(int my_port, int port, basic_block_sptr block);
+
+ endpoint_vector_t resolve_port(int port, bool is_input);
+ endpoint_vector_t resolve_endpoint(const endpoint &endp, bool is_input) const;
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_RUNTIME_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-runtime/lib/io_signature.cc b/gnuradio-runtime/lib/io_signature.cc
new file mode 100644
index 0000000000..ccfdf3c06b
--- /dev/null
+++ b/gnuradio-runtime/lib/io_signature.cc
@@ -0,0 +1,117 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2007,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+namespace gr {
+
+ gr::io_signature::sptr
+ io_signature::makev(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items)
+ {
+ return gr::io_signature::sptr
+ (new io_signature(min_streams, max_streams,
+ sizeof_stream_items));
+ }
+
+ gr::io_signature::sptr
+ io_signature::make(int min_streams, int max_streams,
+ int sizeof_stream_item)
+ {
+ std::vector<int> sizeof_items(1);
+ sizeof_items[0] = sizeof_stream_item;
+ return io_signature::makev(min_streams, max_streams, sizeof_items);
+ }
+
+ gr::io_signature::sptr
+ io_signature::make2(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2)
+ {
+ std::vector<int> sizeof_items(2);
+ sizeof_items[0] = sizeof_stream_item1;
+ sizeof_items[1] = sizeof_stream_item2;
+ return io_signature::makev(min_streams, max_streams, sizeof_items);
+ }
+
+ gr::io_signature::sptr
+ io_signature::make3(int min_streams, int max_streams,
+ int sizeof_stream_item1,
+ int sizeof_stream_item2,
+ int sizeof_stream_item3)
+ {
+ std::vector<int> sizeof_items(3);
+ sizeof_items[0] = sizeof_stream_item1;
+ sizeof_items[1] = sizeof_stream_item2;
+ sizeof_items[2] = sizeof_stream_item3;
+ return io_signature::makev(min_streams, max_streams, sizeof_items);
+ }
+
+ // ------------------------------------------------------------------------
+
+ io_signature::io_signature(int min_streams, int max_streams,
+ const std::vector<int> &sizeof_stream_items)
+ {
+ if(min_streams < 0
+ || (max_streams != IO_INFINITE && max_streams < min_streams))
+ throw std::invalid_argument ("gr::io_signature(1)");
+
+ if(sizeof_stream_items.size() < 1)
+ throw std::invalid_argument("gr::io_signature(2)");
+
+ for(size_t i = 0; i < sizeof_stream_items.size(); i++) {
+ if(max_streams != 0 && sizeof_stream_items[i] < 1)
+ throw std::invalid_argument("gr::io_signature(3)");
+ }
+
+ d_min_streams = min_streams;
+ d_max_streams = max_streams;
+ d_sizeof_stream_item = sizeof_stream_items;
+ }
+
+ io_signature::~io_signature()
+ {
+ }
+
+ int
+ io_signature::sizeof_stream_item(int _index) const
+ {
+ if(_index < 0)
+ throw std::invalid_argument("gr::io_signature::sizeof_stream_item");
+
+ size_t index = _index;
+ return d_sizeof_stream_item[std::min(index, d_sizeof_stream_item.size() - 1)];
+ }
+
+ std::vector<int>
+ io_signature::sizeof_stream_items() const
+ {
+ return d_sizeof_stream_item;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/local_sighandler.cc b/gnuradio-runtime/lib/local_sighandler.cc
new file mode 100644
index 0000000000..ebd9bb1362
--- /dev/null
+++ b/gnuradio-runtime/lib/local_sighandler.cc
@@ -0,0 +1,189 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "local_sighandler.h"
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+
+namespace gr {
+
+ local_sighandler::local_sighandler(int signum,
+ void (*new_handler)(int))
+ : d_signum(signum)
+ {
+#ifdef HAVE_SIGACTION
+ struct sigaction new_action;
+ memset(&new_action, 0, sizeof(new_action));
+
+ new_action.sa_handler = new_handler;
+ sigemptyset(&new_action.sa_mask);
+ new_action.sa_flags = 0;
+
+ if(sigaction (d_signum, &new_action, &d_old_action) < 0) {
+ perror("sigaction (install new)");
+ throw std::runtime_error("sigaction");
+ }
+#endif
+ }
+
+ local_sighandler::~local_sighandler()
+ {
+#ifdef HAVE_SIGACTION
+ if(sigaction (d_signum, &d_old_action, 0) < 0) {
+ perror("sigaction (restore old)");
+ throw std::runtime_error("sigaction");
+ }
+#endif
+ }
+
+ void
+ local_sighandler::throw_signal(int signum)
+ {
+ throw signal(signum);
+ }
+
+ /*
+ * Semi-hideous way to may a signal number into a signal name
+ */
+ #define SIGNAME(x) case x: return #x
+
+ std::string
+ signal::name() const
+ {
+ char tmp[128];
+
+ switch(signum()) {
+#ifdef SIGHUP
+ SIGNAME(SIGHUP);
+#endif
+#ifdef SIGINT
+ SIGNAME(SIGINT);
+#endif
+#ifdef SIGQUIT
+ SIGNAME(SIGQUIT);
+#endif
+#ifdef SIGILL
+ SIGNAME(SIGILL);
+#endif
+#ifdef SIGTRAP
+ SIGNAME(SIGTRAP);
+#endif
+#ifdef SIGABRT
+ SIGNAME(SIGABRT);
+#endif
+#ifdef SIGBUS
+ SIGNAME(SIGBUS);
+#endif
+#ifdef SIGFPE
+ SIGNAME(SIGFPE);
+#endif
+#ifdef SIGKILL
+ SIGNAME(SIGKILL);
+#endif
+#ifdef SIGUSR1
+ SIGNAME(SIGUSR1);
+#endif
+#ifdef SIGSEGV
+ SIGNAME(SIGSEGV);
+#endif
+#ifdef SIGUSR2
+ SIGNAME(SIGUSR2);
+#endif
+#ifdef SIGPIPE
+ SIGNAME(SIGPIPE);
+#endif
+#ifdef SIGALRM
+ SIGNAME(SIGALRM);
+#endif
+#ifdef SIGTERM
+ SIGNAME(SIGTERM);
+#endif
+#ifdef SIGSTKFLT
+ SIGNAME(SIGSTKFLT);
+#endif
+#ifdef SIGCHLD
+ SIGNAME(SIGCHLD);
+#endif
+#ifdef SIGCONT
+ SIGNAME(SIGCONT);
+#endif
+#ifdef SIGSTOP
+ SIGNAME(SIGSTOP);
+#endif
+#ifdef SIGTSTP
+ SIGNAME(SIGTSTP);
+#endif
+#ifdef SIGTTIN
+ SIGNAME(SIGTTIN);
+#endif
+#ifdef SIGTTOU
+ SIGNAME(SIGTTOU);
+#endif
+#ifdef SIGURG
+ SIGNAME(SIGURG);
+#endif
+#ifdef SIGXCPU
+ SIGNAME(SIGXCPU);
+#endif
+#ifdef SIGXFSZ
+ SIGNAME(SIGXFSZ);
+#endif
+#ifdef SIGVTALRM
+ SIGNAME(SIGVTALRM);
+#endif
+#ifdef SIGPROF
+ SIGNAME(SIGPROF);
+#endif
+#ifdef SIGWINCH
+ SIGNAME(SIGWINCH);
+#endif
+#ifdef SIGIO
+ SIGNAME(SIGIO);
+#endif
+#ifdef SIGPWR
+ SIGNAME(SIGPWR);
+#endif
+#ifdef SIGSYS
+ SIGNAME(SIGSYS);
+#endif
+ default:
+#if defined (HAVE_SNPRINTF)
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+ if(signum() >= SIGRTMIN && signum() <= SIGRTMAX) {
+ snprintf(tmp, sizeof(tmp), "SIGRTMIN + %d", signum());
+ return tmp;
+ }
+#endif
+ snprintf(tmp, sizeof(tmp), "SIGNAL %d", signum());
+ return tmp;
+#else
+ return "Unknown signal";
+#endif
+ }
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_local_sighandler.h b/gnuradio-runtime/lib/local_sighandler.h
index a49ee031ca..bd322e5b00 100644
--- a/gnuradio-runtime/lib/gr_local_sighandler.h
+++ b/gnuradio-runtime/lib/local_sighandler.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -27,39 +27,48 @@
#include <signal.h>
#endif
-#include <gr_runtime_api.h>
+#include <gnuradio/api.h>
#include <string>
-/*!
- * \brief Get and set signal handler.
- *
- * \ingroup internal
- * Constructor installs new handler, destructor reinstalls
- * original value.
- */
-class GR_RUNTIME_API gr_local_sighandler {
- int d_signum;
+namespace gr {
+
+ /*!
+ * \brief Get and set signal handler.
+ *
+ * \ingroup internal
+ * Constructor installs new handler, destructor reinstalls
+ * original value.
+ */
+ class GR_RUNTIME_API local_sighandler
+ {
+ private:
+ int d_signum;
#ifdef HAVE_SIGACTION
- struct sigaction d_old_action;
+ struct sigaction d_old_action;
#endif
-public:
- gr_local_sighandler (int signum, void (*new_handler)(int));
- ~gr_local_sighandler ();
- /* throw gr_signal (signum) */
- static void throw_signal (int signum);
-};
+ public:
+ local_sighandler(int signum, void (*new_handler)(int));
+ ~local_sighandler();
-/*!
- * \brief Representation of signal.
- */
-class GR_RUNTIME_API gr_signal
-{
- int d_signum;
-public:
- gr_signal (int signum) : d_signum (signum) {}
- int signal () const { return d_signum; }
- std::string name () const;
-};
+ /* throw gr_signal (signum) */
+ static void throw_signal(int signum);
+ };
+
+ /*!
+ * \brief Representation of signal.
+ */
+ class GR_RUNTIME_API signal
+ {
+ private:
+ int d_signum;
+
+ public:
+ signal(int signum) : d_signum(signum) {}
+ int signum() const { return d_signum; }
+ std::string name() const;
+ };
+
+} /* namespace gr */
#endif /* INCLUDED_GR_LOCAL_SIGHANDLER_H */
diff --git a/gnuradio-runtime/lib/logger.cc b/gnuradio-runtime/lib/logger.cc
new file mode 100644
index 0000000000..dceb18471f
--- /dev/null
+++ b/gnuradio-runtime/lib/logger.cc
@@ -0,0 +1,323 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2012 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.
+ */
+
+/*******************************************************************************
+* Author: Mark Plett
+* Description:
+* The gr_log module wraps the log4cpp library for logging in gnuradio.
+*******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/logger.h>
+#include <stdexcept>
+#include <algorithm>
+
+
+#ifdef ENABLE_GR_LOG
+#ifdef HAVE_LOG4CPP
+
+namespace gr {
+
+ bool logger_config::logger_configured(false);
+
+ /************************ BEGIN LOG4CPP HELPERS ***********************/
+ /* Logger config class. This is a singleton that controls how
+ * log4cpp is configured If watch_period>0 a thread is started to
+ * watch teh config file for changes.
+ */
+
+ // Getters of logger_config
+ logger_config&
+ logger_config::get_instance(void)
+ {
+ static logger_config instance;
+ return instance;
+ }
+
+ std::string
+ logger_config::get_filename()
+ {
+ logger_config& in=get_instance();
+ return in.filename;
+ }
+
+ unsigned int
+ logger_config::get_watch_period()
+ {
+ logger_config& in=get_instance();
+ return in.watch_period;
+ }
+
+ // Method to watch config file for changes
+ void
+ logger_config::watch_file(std::string filename, unsigned int watch_period)
+ {
+ std::time_t last_write(boost::filesystem::last_write_time(filename));
+ std::time_t current_time(0);
+ while(true) {
+ try {
+ current_time = boost::filesystem::last_write_time(filename);
+ if(current_time>last_write) {
+ std::cout<<"GNURadio Reloading logger configuration:"<<filename<<std::endl;
+ last_write = current_time;
+ // Should we wipe out all old configuration or just add the
+ // new? Just adding... logger_reset_config();
+ logger_configured = logger_load_config(filename);
+ }
+ boost::this_thread::sleep(boost::posix_time::time_duration(0,0,watch_period,0));
+ }
+ catch(const boost::thread_interrupted&) {
+ std::cout<<"GNURadio leaving logger config file watch."<<std::endl;
+ break;
+ }
+ }
+ }
+
+ // Method to load the confifuration. It only loads if the filename
+ // or watch has changed
+ void
+ logger_config::load_config(std::string filename,unsigned int watch_period)
+ {
+ logger_config& instance = get_instance();
+ // Only reconfigure if filename or watch has changed
+ if(!logger_configured) {
+ instance.filename = filename;
+ instance.watch_period = watch_period;
+ // Stop any file watching thread
+ if(instance.watch_thread!=NULL)
+ stop_watch();
+ // Load configuration
+ std::cout<<"GNURadio Loading logger configuration:"<<instance.filename<<std::endl;
+ logger_configured = logger_load_config(instance.filename);
+ // Start watch if required
+ if(instance.watch_period>0) {
+ instance.watch_thread = new boost::thread(watch_file, instance.filename,
+ instance.watch_period);
+ }
+ }
+ }
+
+ // Method to stop the watcher thread
+ void
+ logger_config::stop_watch()
+ {
+ logger_config& instance = get_instance();
+ if(instance.watch_thread) {
+ instance.watch_thread->interrupt();
+ instance.watch_thread->join();
+ delete(instance.watch_thread);
+ instance.watch_thread=NULL;
+ }
+ }
+
+ // Method to reset logger configuration
+ void
+ logger_config::reset_config(void)
+ {
+ logger_config& instance = get_instance();
+ stop_watch();
+ std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories();
+ std::vector<log4cpp::Category*>::iterator logger = loggers->begin();
+ // We can't destroy categories but we can neuter them by removing all appenders.
+ for(;logger!=loggers->end();logger++) {
+ (*logger)->removeAllAppenders();
+ }
+ instance.filename = std::string("");
+ instance.watch_period = 0;
+ logger_configured = false;
+ }
+
+ /***************** Functions to call log4cpp methods *************************/
+
+ logger_ptr
+ logger_get_logger(std::string name)
+ {
+ if(log4cpp::Category::exists(name)) {
+ logger_ptr logger = &log4cpp::Category::getInstance(name);
+ return logger;
+ }
+ else {
+ logger_ptr logger = &log4cpp::Category::getInstance(name);
+ logger->setPriority(log4cpp::Priority::NOTSET);
+ return logger;
+ }
+ }
+
+ bool
+ logger_load_config(const std::string &config_filename)
+ {
+ if(config_filename.size() != 0) {
+ try {
+ log4cpp::PropertyConfigurator::configure(config_filename);
+ return true;
+ }
+ catch(log4cpp::ConfigureFailure &e) {
+ std::cout << "Logger config failed :" << e.what() << std::endl;
+ }
+ }
+ return false;
+ }
+
+ void
+ logger_set_level(logger_ptr logger, const std::string &level)
+ {
+ std::string nocase = level;
+ std::transform(level.begin(), level.end(), nocase.begin(), ::tolower);
+
+ if(nocase == "off" || nocase == "notset")
+ logger_set_level(logger, log4cpp::Priority::NOTSET);
+ else if(nocase == "all" || nocase == "debug")
+ logger_set_level(logger, log4cpp::Priority::DEBUG);
+ else if(nocase == "info")
+ logger_set_level(logger, log4cpp::Priority::INFO);
+ else if(nocase == "notice")
+ logger_set_level(logger, log4cpp::Priority::NOTICE);
+ else if(nocase == "warn")
+ logger_set_level(logger, log4cpp::Priority::WARN);
+ else if(nocase == "error")
+ logger_set_level(logger, log4cpp::Priority::ERROR);
+ else if(nocase == "crit")
+ logger_set_level(logger, log4cpp::Priority::CRIT);
+ else if(nocase == "alert")
+ logger_set_level(logger, log4cpp::Priority::ALERT);
+ else if(nocase=="fatal")
+ logger_set_level(logger, log4cpp::Priority::FATAL);
+ else if(nocase == "emerg")
+ logger_set_level(logger, log4cpp::Priority::EMERG);
+ else
+ throw std::runtime_error("logger_set_level: Bad level type.\n");
+ }
+
+ void
+ logger_set_level(logger_ptr logger, log4cpp::Priority::Value level)
+ {
+ logger->setPriority(level);
+ }
+
+ void
+ logger_get_level(logger_ptr logger, std::string &level)
+ {
+ log4cpp::Priority::Value levelPtr = logger->getPriority();
+ if(levelPtr == log4cpp::Priority::NOTSET) level = "noset";
+ if(levelPtr == log4cpp::Priority::DEBUG) level = "debug";
+ if(levelPtr == log4cpp::Priority::INFO) level = "info";
+ if(levelPtr == log4cpp::Priority::NOTICE) level = "notice";
+ if(levelPtr == log4cpp::Priority::WARN) level = "warn";
+ if(levelPtr == log4cpp::Priority::ERROR) level = "error";
+ if(levelPtr == log4cpp::Priority::CRIT) level = "crit";
+ if(levelPtr == log4cpp::Priority::ALERT) level = "alert";
+ if(levelPtr == log4cpp::Priority::FATAL) level = "fatal";
+ if(levelPtr == log4cpp::Priority::EMERG) level = "emerg";
+ }
+
+ void
+ logger_get_level(logger_ptr logger,log4cpp::Priority::Value level)
+ {
+ level = logger->getPriority();
+ }
+
+ void
+ logger_add_console_appender(logger_ptr logger, std::string target, std::string pattern)
+ {
+ log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
+ log4cpp::Appender* app;
+ if(target=="stdout")
+ app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cout);
+ else
+ app = new log4cpp::OstreamAppender("ConsoleAppender::",&std::cerr);
+
+ layout->setConversionPattern(pattern);
+ app->setLayout(layout);
+ logger->setAppender(*app);
+ }
+
+ void
+ logger_add_file_appender(logger_ptr logger, std::string filename,
+ bool append, std::string pattern)
+ {
+ log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
+ log4cpp::Appender* app = new
+ log4cpp::FileAppender("FileAppender::"+filename,
+ filename);
+ layout->setConversionPattern(pattern);
+ app->setLayout(layout);
+ logger->setAppender(app);
+ }
+
+ void
+ logger_add_rollingfile_appender(logger_ptr logger, std::string filename,
+ size_t filesize, int bkup_index, bool append,
+ mode_t mode, std::string pattern)
+ {
+ log4cpp::PatternLayout* layout = new log4cpp::PatternLayout();
+ log4cpp::Appender* app = new
+ log4cpp::RollingFileAppender("RollFileAppender::" + filename, filename,
+ filesize, bkup_index, append, mode);
+ layout->setConversionPattern(pattern);
+ app->setLayout(layout);
+ logger->setAppender(app);
+ }
+
+ std::vector<std::string>
+ logger_get_logger_names(void)
+ {
+ std::vector<std::string> names;
+ std::vector<log4cpp::Category*> *loggers = log4cpp::Category::getCurrentCategories();
+ std::vector<log4cpp::Category*>::iterator logger = loggers->begin();
+
+ for(;logger!=loggers->end();logger++) {
+ names.push_back((*logger)->getName());
+ }
+ return names;
+ }
+
+} /* 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)
+{
+ GR_CONFIG_AND_WATCH_LOGGER(config_filename, watch_period);
+}
+
+std::vector<std::string>
+gr_logger_get_logger_names(void)
+{
+ std::vector<std::string> names;
+ GR_GET_LOGGER_NAMES(names);
+ return names;
+}
+
+void
+gr_logger_reset_config(void)
+{
+ GR_RESET_CONFIGURATION();
+}
+
+// Remaining capability provided by gr::logger class in gnuradio/logger.h
+
+#endif /* ENABLE_GR_LOGGER */
diff --git a/gnuradio-runtime/lib/malloc16.h b/gnuradio-runtime/lib/malloc16.h
index 90d1eca77a..05f80cbf4f 100644
--- a/gnuradio-runtime/lib/malloc16.h
+++ b/gnuradio-runtime/lib/malloc16.h
@@ -20,7 +20,7 @@
* Boston, MA 02110-1301, USA.
*/
-#include <gr_runtime_api.h>
+#include <gnuradio/api.h>
#ifdef __cplusplus
extern "C" {
diff --git a/gnuradio-runtime/lib/math/CMakeLists.txt b/gnuradio-runtime/lib/math/CMakeLists.txt
new file mode 100644
index 0000000000..c95c84cecb
--- /dev/null
+++ b/gnuradio-runtime/lib/math/CMakeLists.txt
@@ -0,0 +1,29 @@
+# Copyright 2010,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.
+
+########################################################################
+# This file included, use CMake directory variables
+########################################################################
+
+list(APPEND gnuradio_runtime_sources
+ ${CMAKE_CURRENT_SOURCE_DIR}/fast_atan2f.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/fxpt.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/random.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/sincos.cc
+)
diff --git a/gnuradio-runtime/lib/math/fast_atan2f.cc b/gnuradio-runtime/lib/math/fast_atan2f.cc
new file mode 100644
index 0000000000..3555cf50ec
--- /dev/null
+++ b/gnuradio-runtime/lib/math/fast_atan2f.cc
@@ -0,0 +1,202 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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/math.h> // declaration is in here
+#include <cmath>
+
+namespace gr {
+
+ /***************************************************************************/
+ /* Constant definitions */
+ /***************************************************************************/
+
+ #define TAN_MAP_RES 0.003921569 /* (smallest non-zero value in table) */
+ #define RAD_PER_DEG 0.017453293
+ #define TAN_MAP_SIZE 256
+
+ /* arctangents from 0 to pi/4 radians */
+ static float
+ fast_atan_table[257] = {
+ 0.000000e+00, 3.921549e-03, 7.842976e-03, 1.176416e-02,
+ 1.568499e-02, 1.960533e-02, 2.352507e-02, 2.744409e-02,
+ 3.136226e-02, 3.527947e-02, 3.919560e-02, 4.311053e-02,
+ 4.702413e-02, 5.093629e-02, 5.484690e-02, 5.875582e-02,
+ 6.266295e-02, 6.656816e-02, 7.047134e-02, 7.437238e-02,
+ 7.827114e-02, 8.216752e-02, 8.606141e-02, 8.995267e-02,
+ 9.384121e-02, 9.772691e-02, 1.016096e-01, 1.054893e-01,
+ 1.093658e-01, 1.132390e-01, 1.171087e-01, 1.209750e-01,
+ 1.248376e-01, 1.286965e-01, 1.325515e-01, 1.364026e-01,
+ 1.402496e-01, 1.440924e-01, 1.479310e-01, 1.517652e-01,
+ 1.555948e-01, 1.594199e-01, 1.632403e-01, 1.670559e-01,
+ 1.708665e-01, 1.746722e-01, 1.784728e-01, 1.822681e-01,
+ 1.860582e-01, 1.898428e-01, 1.936220e-01, 1.973956e-01,
+ 2.011634e-01, 2.049255e-01, 2.086818e-01, 2.124320e-01,
+ 2.161762e-01, 2.199143e-01, 2.236461e-01, 2.273716e-01,
+ 2.310907e-01, 2.348033e-01, 2.385093e-01, 2.422086e-01,
+ 2.459012e-01, 2.495869e-01, 2.532658e-01, 2.569376e-01,
+ 2.606024e-01, 2.642600e-01, 2.679104e-01, 2.715535e-01,
+ 2.751892e-01, 2.788175e-01, 2.824383e-01, 2.860514e-01,
+ 2.896569e-01, 2.932547e-01, 2.968447e-01, 3.004268e-01,
+ 3.040009e-01, 3.075671e-01, 3.111252e-01, 3.146752e-01,
+ 3.182170e-01, 3.217506e-01, 3.252758e-01, 3.287927e-01,
+ 3.323012e-01, 3.358012e-01, 3.392926e-01, 3.427755e-01,
+ 3.462497e-01, 3.497153e-01, 3.531721e-01, 3.566201e-01,
+ 3.600593e-01, 3.634896e-01, 3.669110e-01, 3.703234e-01,
+ 3.737268e-01, 3.771211e-01, 3.805064e-01, 3.838825e-01,
+ 3.872494e-01, 3.906070e-01, 3.939555e-01, 3.972946e-01,
+ 4.006244e-01, 4.039448e-01, 4.072558e-01, 4.105574e-01,
+ 4.138496e-01, 4.171322e-01, 4.204054e-01, 4.236689e-01,
+ 4.269229e-01, 4.301673e-01, 4.334021e-01, 4.366272e-01,
+ 4.398426e-01, 4.430483e-01, 4.462443e-01, 4.494306e-01,
+ 4.526070e-01, 4.557738e-01, 4.589307e-01, 4.620778e-01,
+ 4.652150e-01, 4.683424e-01, 4.714600e-01, 4.745676e-01,
+ 4.776654e-01, 4.807532e-01, 4.838312e-01, 4.868992e-01,
+ 4.899573e-01, 4.930055e-01, 4.960437e-01, 4.990719e-01,
+ 5.020902e-01, 5.050985e-01, 5.080968e-01, 5.110852e-01,
+ 5.140636e-01, 5.170320e-01, 5.199904e-01, 5.229388e-01,
+ 5.258772e-01, 5.288056e-01, 5.317241e-01, 5.346325e-01,
+ 5.375310e-01, 5.404195e-01, 5.432980e-01, 5.461666e-01,
+ 5.490251e-01, 5.518738e-01, 5.547124e-01, 5.575411e-01,
+ 5.603599e-01, 5.631687e-01, 5.659676e-01, 5.687566e-01,
+ 5.715357e-01, 5.743048e-01, 5.770641e-01, 5.798135e-01,
+ 5.825531e-01, 5.852828e-01, 5.880026e-01, 5.907126e-01,
+ 5.934128e-01, 5.961032e-01, 5.987839e-01, 6.014547e-01,
+ 6.041158e-01, 6.067672e-01, 6.094088e-01, 6.120407e-01,
+ 6.146630e-01, 6.172755e-01, 6.198784e-01, 6.224717e-01,
+ 6.250554e-01, 6.276294e-01, 6.301939e-01, 6.327488e-01,
+ 6.352942e-01, 6.378301e-01, 6.403565e-01, 6.428734e-01,
+ 6.453808e-01, 6.478788e-01, 6.503674e-01, 6.528466e-01,
+ 6.553165e-01, 6.577770e-01, 6.602282e-01, 6.626701e-01,
+ 6.651027e-01, 6.675261e-01, 6.699402e-01, 6.723452e-01,
+ 6.747409e-01, 6.771276e-01, 6.795051e-01, 6.818735e-01,
+ 6.842328e-01, 6.865831e-01, 6.889244e-01, 6.912567e-01,
+ 6.935800e-01, 6.958943e-01, 6.981998e-01, 7.004964e-01,
+ 7.027841e-01, 7.050630e-01, 7.073330e-01, 7.095943e-01,
+ 7.118469e-01, 7.140907e-01, 7.163258e-01, 7.185523e-01,
+ 7.207701e-01, 7.229794e-01, 7.251800e-01, 7.273721e-01,
+ 7.295557e-01, 7.317307e-01, 7.338974e-01, 7.360555e-01,
+ 7.382053e-01, 7.403467e-01, 7.424797e-01, 7.446045e-01,
+ 7.467209e-01, 7.488291e-01, 7.509291e-01, 7.530208e-01,
+ 7.551044e-01, 7.571798e-01, 7.592472e-01, 7.613064e-01,
+ 7.633576e-01, 7.654008e-01, 7.674360e-01, 7.694633e-01,
+ 7.714826e-01, 7.734940e-01, 7.754975e-01, 7.774932e-01,
+ 7.794811e-01, 7.814612e-01, 7.834335e-01, 7.853983e-01,
+ 7.853983e-01
+ };
+
+
+ /*****************************************************************************
+ Function: Arc tangent
+
+ Syntax: angle = fast_atan2(y, x);
+ float y y component of input vector
+ float x x component of input vector
+ float angle angle of vector (x, y) in radians
+
+ Description: This function calculates the angle of the vector (x,y)
+ based on a table lookup and linear interpolation. The table uses a
+ 256 point table covering -45 to +45 degrees and uses symetry to
+ determine the final angle value in the range of -180 to 180
+ degrees. Note that this function uses the small angle approximation
+ for values close to zero. This routine calculates the arc tangent
+ with an average error of +/- 0.045 degrees.
+ *****************************************************************************/
+
+ float
+ fast_atan2f(float y, float x)
+ {
+ float x_abs, y_abs, z;
+ float alpha, angle, base_angle;
+ int index;
+
+ /* don't divide by zero! */ // FIXME could get hosed with -0.0
+ if((y == 0.0) && (x == 0.0))
+ return 0.0;
+
+ /* normalize to +/- 45 degree range */
+ y_abs = fabsf(y);
+ x_abs = fabsf(x);
+ //z = (y_abs < x_abs ? y_abs / x_abs : x_abs / y_abs);
+ if(y_abs < x_abs)
+ z = y_abs / x_abs;
+ else
+ z = x_abs / y_abs;
+
+ /* when ratio approaches the table resolution, the angle is */
+ /* best approximated with the argument itself... */
+ if(z < TAN_MAP_RES)
+ base_angle = z;
+ else {
+ /* find index and interpolation value */
+ alpha = z * (float)TAN_MAP_SIZE - .5;
+ index = (int)alpha;
+ alpha -= (float)index;
+ /* determine base angle based on quadrant and */
+ /* add or subtract table value from base angle based on quadrant */
+ base_angle = fast_atan_table[index];
+ base_angle +=
+ (fast_atan_table[index + 1] - fast_atan_table[index]) * alpha;
+ }
+
+ if(x_abs > y_abs) { /* -45 -> 45 or 135 -> 225 */
+ if(x >= 0.0) { /* -45 -> 45 */
+ if(y >= 0.0)
+ angle = base_angle; /* 0 -> 45, angle OK */
+ else
+ angle = -base_angle; /* -45 -> 0, angle = -angle */
+ }
+ else { /* 135 -> 180 or 180 -> -135 */
+ angle = 3.14159265358979323846;
+ if(y >= 0.0)
+ angle -= base_angle; /* 135 -> 180, angle = 180 - angle */
+ else
+ angle = base_angle - angle; /* 180 -> -135, angle = angle - 180 */
+ }
+ }
+ else { /* 45 -> 135 or -135 -> -45 */
+ if(y >= 0.0) { /* 45 -> 135 */
+ angle = 1.57079632679489661923;
+ if(x >= 0.0)
+ angle -= base_angle; /* 45 -> 90, angle = 90 - angle */
+ else
+ angle += base_angle; /* 90 -> 135, angle = 90 + angle */
+ }
+ else { /* -135 -> -45 */
+ angle = -1.57079632679489661923;
+ if(x >= 0.0)
+ angle += base_angle; /* -90 -> -45, angle = -90 + angle */
+ else
+ angle -= base_angle; /* -135 -> -90, angle = -90 - angle */
+ }
+ }
+
+ #ifdef ZERO_TO_TWOPI
+ if (angle < 0)
+ return (angle + TWOPI);
+ else
+ return (angle);
+ #else
+ return (angle);
+ #endif
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_fxpt.cc b/gnuradio-runtime/lib/math/fxpt.cc
index 2ea8520e6b..23fdda1241 100644
--- a/gnuradio-runtime/lib/gr_fxpt.cc
+++ b/gnuradio-runtime/lib/math/fxpt.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,12 +24,15 @@
#include "config.h"
#endif
-#include <gr_fxpt.h>
+#include <gnuradio/fxpt.h>
-const float gr_fxpt::s_sine_table[1 << NBITS][2] = {
-#include "sine_table.h"
-};
+namespace gr {
-const float gr_fxpt::PI = 3.14159265358979323846;
-const float gr_fxpt::TWO_TO_THE_31 = 2147483648.0;
+ const float fxpt::s_sine_table[1 << NBITS][2] = {
+ #include "sine_table.h"
+ };
+ const float fxpt::PI = 3.14159265358979323846;
+ const float fxpt::TWO_TO_THE_31 = 2147483648.0;
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gen_sine_table.py b/gnuradio-runtime/lib/math/gen_sine_table.py
index d7d11eff11..d7d11eff11 100755
--- a/gnuradio-runtime/lib/gen_sine_table.py
+++ b/gnuradio-runtime/lib/math/gen_sine_table.py
diff --git a/gnuradio-runtime/lib/math/qa_fxpt.cc b/gnuradio-runtime/lib/math/qa_fxpt.cc
new file mode 100644
index 0000000000..d368e7de82
--- /dev/null
+++ b/gnuradio-runtime/lib/math/qa_fxpt.cc
@@ -0,0 +1,102 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_fxpt.h>
+#include <gnuradio/fxpt.h>
+#include <cppunit/TestAssert.h>
+#include <iostream>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+static const float SIN_COS_TOLERANCE = 1e-5;
+
+void
+qa_fxpt::t0()
+{
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/2, gr::fxpt::fixed_to_float(0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, gr::fxpt::fixed_to_float(0x00000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-M_PI, gr::fxpt::fixed_to_float(0x80000000), SIN_COS_TOLERANCE);
+
+ if(0) {
+ /*
+ * These are disabled because of some precision issues.
+ *
+ * Different compilers seem to have different opinions on whether
+ * the calulations are done single or double (or extended)
+ * precision. Any of the answers are fine for our real purpose, but
+ * sometimes the answer is off by a few bits at the bottom.
+ * Hence, the disabled check.
+ */
+ CPPUNIT_ASSERT_EQUAL((gr_int32)0x40000000, gr::fxpt::float_to_fixed(M_PI/2));
+ CPPUNIT_ASSERT_EQUAL((gr_int32)0, gr::fxpt::float_to_fixed(0));
+ CPPUNIT_ASSERT_EQUAL((gr_int32)0x80000000, gr::fxpt::float_to_fixed(-M_PI));
+ }
+}
+
+void
+qa_fxpt::t1()
+{
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0, gr::fxpt::sin(0x00000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.707106781, gr::fxpt::sin(0x20000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, gr::fxpt::sin(0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.707106781, gr::fxpt::sin(0x60000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0, gr::fxpt::sin(0x7fffffff), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0, gr::fxpt::sin(0x80000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL( 0, gr::fxpt::sin(0x80000001), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-1, gr::fxpt::sin(-0x40000000), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.707106781, gr::fxpt::sin(-0x20000000), SIN_COS_TOLERANCE);
+
+ for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ float expected = sin(p);
+ float actual = gr::fxpt::sin(gr::fxpt::float_to_fixed (p));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, SIN_COS_TOLERANCE);
+ }
+}
+
+void
+qa_fxpt::t2()
+{
+ for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ float expected = cos(p);
+ float actual = gr::fxpt::cos(gr::fxpt::float_to_fixed(p));
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, SIN_COS_TOLERANCE);
+ }
+}
+
+void
+qa_fxpt::t3()
+{
+ for(float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600) {
+ float expected_sin = sin(p);
+ float expected_cos = cos(p);
+ float actual_sin;
+ float actual_cos;
+ gr::fxpt::sincos(gr::fxpt::float_to_fixed (p), &actual_sin, &actual_cos);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected_sin, actual_sin, SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(expected_cos, actual_cos, SIN_COS_TOLERANCE);
+ }
+}
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt.h b/gnuradio-runtime/lib/math/qa_fxpt.h
index 72211563e7..58a6f02d1b 100644
--- a/gnuradio-runtime/lib/qa_gr_fxpt.h
+++ b/gnuradio-runtime/lib/math/qa_fxpt.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,28 +19,27 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+
#ifndef INCLUDED_QA_GR_FXPT_H
#define INCLUDED_QA_GR_FXPT_H
-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_fxpt : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_fxpt);
- CPPUNIT_TEST (t0);
- CPPUNIT_TEST (t1);
- CPPUNIT_TEST (t2);
- CPPUNIT_TEST (t3);
- CPPUNIT_TEST_SUITE_END ();
+class qa_fxpt : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_fxpt);
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
private:
- void t0 ();
- void t1 ();
- void t2 ();
- void t3 ();
-
+ void t0();
+ void t1();
+ void t2();
+ void t3();
};
#endif /* INCLUDED_QA_GR_FXPT_H */
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt_nco.cc b/gnuradio-runtime/lib/math/qa_fxpt_nco.cc
index 6f208eac80..cf229d68be 100644
--- a/gnuradio-runtime/lib/qa_gr_fxpt_nco.cc
+++ b/gnuradio-runtime/lib/math/qa_fxpt_nco.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,9 +23,10 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <qa_gr_fxpt_nco.h>
-#include <gr_fxpt_nco.h>
-#include <gr_nco.h>
+
+#include <qa_fxpt_nco.h>
+#include <gnuradio/fxpt_nco.h>
+#include <gnuradio/nco.h>
#include <cppunit/TestAssert.h>
#include <iostream>
#include <stdio.h>
@@ -45,59 +46,59 @@ static double max_d(double a, double b)
}
void
-qa_gr_fxpt_nco::t0 ()
+qa_fxpt_nco::t0()
{
- gr_nco<float,float> ref_nco;
- gr_fxpt_nco new_nco;
+ gr::nco<float,float> ref_nco;
+ 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 * M_PI / SIN_COS_FREQ));
+ new_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
- float ref_sin = ref_nco.sin ();
- float new_sin = new_nco.sin ();
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
+ float ref_sin = ref_nco.sin();
+ float new_sin = new_nco.sin();
//printf ("i = %6d\n", i);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_sin, new_sin, SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_sin, new_sin, SIN_COS_TOLERANCE);
- max_error = max_d (max_error, ref_sin-new_sin);
+ max_error = max_d(max_error, ref_sin-new_sin);
- float ref_cos = ref_nco.cos ();
- float new_cos = new_nco.cos ();
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+ float ref_cos = ref_nco.cos();
+ float new_cos = new_nco.cos();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_cos, new_cos, SIN_COS_TOLERANCE);
- max_error = max_d (max_error, ref_cos-new_cos);
+ max_error = max_d(max_error, ref_cos-new_cos);
- ref_nco.step ();
- new_nco.step ();
+ ref_nco.step();
+ new_nco.step();
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_nco.get_phase(), new_nco.get_phase(), SIN_COS_TOLERANCE);
- max_phase_error = max_d (max_phase_error, ref_nco.get_phase()-new_nco.get_phase());
+ max_phase_error = max_d(max_phase_error, ref_nco.get_phase()-new_nco.get_phase());
}
// printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
}
void
-qa_gr_fxpt_nco::t1 ()
+qa_fxpt_nco::t1()
{
- gr_nco<float,float> ref_nco;
- gr_fxpt_nco new_nco;
+ gr::nco<float,float> ref_nco;
+ gr::fxpt_nco new_nco;
gr_complex ref_block[SIN_COS_BLOCK_SIZE];
gr_complex new_block[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 * M_PI / SIN_COS_FREQ));
+ new_nco.set_freq((float)(2 * M_PI / SIN_COS_FREQ));
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_nco.get_freq(), new_nco.get_freq(), SIN_COS_TOLERANCE);
- ref_nco.sincos ((gr_complex*)ref_block, SIN_COS_BLOCK_SIZE);
- new_nco.sincos ((gr_complex*)new_block, SIN_COS_BLOCK_SIZE);
+ ref_nco.sincos((gr_complex*)ref_block, SIN_COS_BLOCK_SIZE);
+ new_nco.sincos((gr_complex*)new_block, SIN_COS_BLOCK_SIZE);
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i].real(), new_block[i].real(), SIN_COS_TOLERANCE);
max_error = max_d (max_error, ref_block[i].real()-new_block[i].real());
@@ -109,11 +110,11 @@ qa_gr_fxpt_nco::t1 ()
}
void
-qa_gr_fxpt_nco::t2 ()
+qa_fxpt_nco::t2()
{
}
void
-qa_gr_fxpt_nco::t3 ()
+qa_fxpt_nco::t3()
{
}
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt_nco.h b/gnuradio-runtime/lib/math/qa_fxpt_nco.h
index 8998922bbb..1b2cdaede6 100644
--- a/gnuradio-runtime/lib/qa_gr_fxpt_nco.h
+++ b/gnuradio-runtime/lib/math/qa_fxpt_nco.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,28 +19,27 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+
#ifndef INCLUDED_QA_GR_FXPT_NCO_H
#define INCLUDED_QA_GR_FXPT_NCO_H
-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_fxpt_nco : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_fxpt_nco);
- CPPUNIT_TEST (t0);
- CPPUNIT_TEST (t1);
- CPPUNIT_TEST (t2);
- CPPUNIT_TEST (t3);
- CPPUNIT_TEST_SUITE_END ();
-
- private:
- void t0 ();
- void t1 ();
- void t2 ();
- void t3 ();
-
+class qa_fxpt_nco : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_fxpt_nco);
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void t0();
+ void t1();
+ void t2();
+ void t3();
};
#endif /* INCLUDED_QA_GR_FXPT_NCO_H */
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt_vco.cc b/gnuradio-runtime/lib/math/qa_fxpt_vco.cc
index 5b6993a30c..ee9865e926 100644
--- a/gnuradio-runtime/lib/qa_gr_fxpt_vco.cc
+++ b/gnuradio-runtime/lib/math/qa_fxpt_vco.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2005 Free Software Foundation, Inc.
+ * Copyright 2004,2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,9 +23,10 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <qa_gr_fxpt_vco.h>
-#include <gr_fxpt_vco.h>
-#include <gr_vco.h>
+
+#include <qa_fxpt_vco.h>
+#include <gnuradio/fxpt_vco.h>
+#include <vco.h>
#include <cppunit/TestAssert.h>
#include <iostream>
#include <stdio.h>
@@ -45,66 +46,65 @@ static double max_d(double a, double b)
}
void
-qa_gr_fxpt_vco::t0 ()
+qa_fxpt_vco::t0()
{
- gr_vco<float,float> ref_vco;
- gr_fxpt_vco new_vco;
+ gr::vco<float,float> ref_vco;
+ gr::fxpt_vco new_vco;
double max_error = 0, max_phase_error = 0;
float input[SIN_COS_BLOCK_SIZE];
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
- input[i] = sin(double(i));
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
+ input[i] = sin(double(i));
}
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
- float ref_cos = ref_vco.cos ();
- float new_cos = new_vco.cos ();
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_cos, new_cos, SIN_COS_TOLERANCE);
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
+ float ref_cos = ref_vco.cos();
+ float new_cos = new_vco.cos();
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_cos, new_cos, SIN_COS_TOLERANCE);
- max_error = max_d (max_error, ref_cos-new_cos);
+ max_error = max_d(max_error, ref_cos-new_cos);
- ref_vco.adjust_phase (input[i]);
- new_vco.adjust_phase (input[i]);
+ ref_vco.adjust_phase(input[i]);
+ new_vco.adjust_phase(input[i]);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
- max_phase_error = max_d (max_phase_error, ref_vco.get_phase()-new_vco.get_phase());
+ max_phase_error = max_d(max_phase_error, ref_vco.get_phase()-new_vco.get_phase());
}
// printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, max_phase_error);
}
-
void
-qa_gr_fxpt_vco::t1 ()
+qa_fxpt_vco::t1()
{
- gr_vco<float,float> ref_vco;
- gr_fxpt_vco new_vco;
+ gr::vco<float,float> ref_vco;
+ gr::fxpt_vco new_vco;
float ref_block[SIN_COS_BLOCK_SIZE];
float new_block[SIN_COS_BLOCK_SIZE];
float input[SIN_COS_BLOCK_SIZE];
double max_error = 0;
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
- input[i] = sin(double(i));
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
+ input[i] = sin(double(i));
}
- ref_vco.cos (ref_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
- new_vco.cos (new_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+ ref_vco.cos(ref_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
+ new_vco.cos(new_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL);
- for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_block[i], new_block[i], SIN_COS_TOLERANCE);
- max_error = max_d (max_error, ref_block[i]-new_block[i]);
+ for(int i = 0; i < SIN_COS_BLOCK_SIZE; i++) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_block[i], new_block[i], SIN_COS_TOLERANCE);
+ max_error = max_d(max_error, ref_block[i]-new_block[i]);
}
- CPPUNIT_ASSERT_DOUBLES_EQUAL (ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(ref_vco.get_phase(), new_vco.get_phase(), SIN_COS_TOLERANCE);
// printf ("Fxpt max error %.9f, max phase error %.9f\n", max_error, ref_vco.get_phase()-new_vco.get_phase());
}
void
-qa_gr_fxpt_vco::t2 ()
+qa_fxpt_vco::t2()
{
}
void
-qa_gr_fxpt_vco::t3 ()
+qa_fxpt_vco::t3()
{
}
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt_vco.h b/gnuradio-runtime/lib/math/qa_fxpt_vco.h
index fab8022e36..72693f32e2 100644
--- a/gnuradio-runtime/lib/qa_gr_fxpt_vco.h
+++ b/gnuradio-runtime/lib/math/qa_fxpt_vco.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2005 Free Software Foundation, Inc.
+ * Copyright 2004,2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,28 +19,27 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+
#ifndef INCLUDED_QA_GR_FXPT_VCO_H
#define INCLUDED_QA_GR_FXPT_VCO_H
-
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_fxpt_vco : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_fxpt_vco);
- CPPUNIT_TEST (t0);
- CPPUNIT_TEST (t1);
- CPPUNIT_TEST (t2);
- CPPUNIT_TEST (t3);
- CPPUNIT_TEST_SUITE_END ();
-
- private:
- void t0 ();
- void t1 ();
- void t2 ();
- void t3 ();
-
+class qa_fxpt_vco : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_fxpt_vco);
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void t0();
+ void t1();
+ void t2();
+ void t3();
};
#endif /* INCLUDED_QA_GR_FXPT_VCO_H */
diff --git a/gnuradio-runtime/lib/qa_gr_math.cc b/gnuradio-runtime/lib/math/qa_math.cc
index 74d51b536e..1fb43cc67f 100644
--- a/gnuradio-runtime/lib/qa_gr_math.cc
+++ b/gnuradio-runtime/lib/math/qa_math.cc
@@ -19,21 +19,21 @@
* Boston, MA 02110-1301, USA.
*/
-#include <gr_math.h>
-#include <qa_gr_math.h>
+#include <gnuradio/math.h>
+#include <qa_math.h>
#include <cppunit/TestAssert.h>
#include <stdio.h>
void
-qa_gr_math::test_binary_slicer1 ()
+qa_math::test_binary_slicer1()
{
float x[5] = {-1, -0.5, 0, 0.5, 1.0};
unsigned int z[5] = {0, 0, 1, 1, 1};
unsigned int y;
//printf("\nBinary\n");
- for (unsigned int i = 0; i < 5; i++) {
- y = gr_binary_slicer(x[i]);
+ for(unsigned int i = 0; i < 5; i++) {
+ y = gr::binary_slicer(x[i]);
//printf("in: %f out: %d desired: %d\n", x[i], y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
@@ -41,7 +41,7 @@ qa_gr_math::test_binary_slicer1 ()
//printf("\nBranchless Binary\n");
for (unsigned int i = 0; i < 5; i++) {
- y = gr_branchless_binary_slicer(x[i]);
+ y = gr::branchless_binary_slicer(x[i]);
//printf("in: %f out: %d desired: %d\n", x[i], y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
@@ -49,7 +49,7 @@ qa_gr_math::test_binary_slicer1 ()
}
void
-qa_gr_math::test_quad_0deg_slicer1 ()
+qa_math::test_quad_0deg_slicer1()
{
gr_complex x[4] = {gr_complex(1, 0),
gr_complex(0, 1),
@@ -61,7 +61,7 @@ qa_gr_math::test_quad_0deg_slicer1 ()
//printf("\nQuad0\n");
for (unsigned int i = 0; i < 4; i++) {
- y = gr_quad_0deg_slicer(x[i]);
+ y = gr::quad_0deg_slicer(x[i]);
//printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
@@ -69,7 +69,7 @@ qa_gr_math::test_quad_0deg_slicer1 ()
//printf("\nBranchless Quad0\n");
for (unsigned int i = 0; i < 4; i++) {
- y = gr_branchless_quad_0deg_slicer(x[i]);
+ y = gr::branchless_quad_0deg_slicer(x[i]);
//printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
@@ -77,7 +77,7 @@ qa_gr_math::test_quad_0deg_slicer1 ()
}
void
-qa_gr_math::test_quad_45deg_slicer1 ()
+qa_math::test_quad_45deg_slicer1()
{
gr_complex x[4] = {gr_complex(0.707, 0.707),
gr_complex(-0.707, 0.707),
@@ -89,7 +89,7 @@ qa_gr_math::test_quad_45deg_slicer1 ()
//printf("\nQuad45\n");
for (unsigned int i = 0; i < 4; i++) {
- y = gr_quad_45deg_slicer(x[i]);
+ y = gr::quad_45deg_slicer(x[i]);
//printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
@@ -97,7 +97,7 @@ qa_gr_math::test_quad_45deg_slicer1 ()
//printf("\nBranchless Quad45\n");
for (unsigned int i = 0; i < 4; i++) {
- y = gr_branchless_quad_45deg_slicer(x[i]);
+ y = gr::branchless_quad_45deg_slicer(x[i]);
//printf("in: %.4f+j%.4f out: %d desired: %d\n", x[i].real(), x[i].imag(), y, z[i]);
CPPUNIT_ASSERT_DOUBLES_EQUAL(y, z[i], 1e-9);
diff --git a/gnuradio-runtime/lib/qa_gr_math.h b/gnuradio-runtime/lib/math/qa_math.h
index 86858c03d5..3621283b37 100644
--- a/gnuradio-runtime/lib/qa_gr_math.h
+++ b/gnuradio-runtime/lib/math/qa_math.h
@@ -25,9 +25,9 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_math : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE(qa_gr_math);
+class qa_math : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_math);
CPPUNIT_TEST(test_binary_slicer1);
CPPUNIT_TEST(test_quad_0deg_slicer1);
CPPUNIT_TEST(test_quad_45deg_slicer1);
diff --git a/gnuradio-runtime/lib/qa_sincos.cc b/gnuradio-runtime/lib/math/qa_sincos.cc
index be163117de..7def8a9bb8 100644
--- a/gnuradio-runtime/lib/qa_sincos.cc
+++ b/gnuradio-runtime/lib/math/qa_sincos.cc
@@ -25,8 +25,7 @@
#endif
#include <qa_sincos.h>
-#include <gr_sincos.h>
-#include <attributes.h>
+#include <gnuradio/sincos.h>
#include <cppunit/TestAssert.h>
#include <cmath>
@@ -42,7 +41,7 @@ qa_sincos::t1()
c_sin = sin(x);
c_cos = cos(x);
- gr_sincos(x, &gr_sin, &gr_cos);
+ gr::sincos(x, &gr_sin, &gr_cos);
CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001);
CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001);
@@ -61,7 +60,7 @@ qa_sincos::t2()
c_sin = sinf(x);
c_cos = cosf(x);
- gr_sincosf(x, &gr_sin, &gr_cos);
+ gr::sincosf(x, &gr_sin, &gr_cos);
CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001);
CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001);
diff --git a/gnuradio-runtime/lib/qa_sincos.h b/gnuradio-runtime/lib/math/qa_sincos.h
index c54b75f97f..c54b75f97f 100644
--- a/gnuradio-runtime/lib/qa_sincos.h
+++ b/gnuradio-runtime/lib/math/qa_sincos.h
diff --git a/gnuradio-runtime/lib/math/random.cc b/gnuradio-runtime/lib/math/random.cc
new file mode 100644
index 0000000000..7170f27edf
--- /dev/null
+++ b/gnuradio-runtime/lib/math/random.cc
@@ -0,0 +1,188 @@
+/* -*- 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.
+ */
+
+/*
+ * Copyright 1997 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <gnuradio/random.h>
+
+namespace gr {
+
+#define IA 16807
+#define IM 2147483647
+#define AM (1.0/IM)
+#define IQ 127773
+#define IR 2836
+#define NDIV (1+(IM-1)/NTAB)
+#define EPS 1.2e-7
+#define RNMX (1.0-EPS)
+
+ random::random(long seed)
+ {
+ reseed(seed);
+ }
+
+ void
+ random::reseed(long seed)
+ {
+ d_seed = seed;
+ d_iy = 0;
+ for(int i = 0; i < NTAB; i++)
+ d_iv[i] = 0;
+ d_iset = 0;
+ d_gset = 0;
+ }
+
+ /*
+ * This looks like it returns a uniform random deviate between 0.0 and 1.0
+ * It looks similar to code from "Numerical Recipes in C".
+ */
+ float
+ random::ran1()
+ {
+ int j;
+ long k;
+ float temp;
+
+ if(d_seed <= 0 || !d_iy) {
+ if(-d_seed < 1)
+ d_seed=1;
+ else
+ d_seed = -d_seed;
+ for(j=NTAB+7;j>=0;j--) {
+ k=d_seed/IQ;
+ d_seed=IA*(d_seed-k*IQ)-IR*k;
+ if(d_seed < 0)
+ d_seed += IM;
+ if(j < NTAB)
+ d_iv[j] = d_seed;
+ }
+ d_iy=d_iv[0];
+ }
+ k=(d_seed)/IQ;
+ d_seed=IA*(d_seed-k*IQ)-IR*k;
+ if(d_seed < 0)
+ d_seed += IM;
+ j=d_iy/NDIV;
+ d_iy=d_iv[j];
+ d_iv[j] = d_seed;
+ temp=AM * d_iy;
+ if(temp > RNMX)
+ temp = RNMX;
+ return temp;
+ }
+
+ /*
+ * Returns a normally distributed deviate with zero mean and variance 1.
+ * Also looks like it's from "Numerical Recipes in C".
+ */
+ float
+ random::gasdev()
+ {
+ float fac,rsq,v1,v2;
+ d_iset = 1 - d_iset;
+ if(d_iset) {
+ do {
+ v1=2.0*ran1()-1.0;
+ v2=2.0*ran1()-1.0;
+ rsq=v1*v1+v2*v2;
+ } while(rsq >= 1.0 || rsq == 0.0);
+ fac= sqrt(-2.0*log(rsq)/rsq);
+ d_gset=v1*fac;
+ return v2*fac;
+ }
+ return d_gset;
+ }
+
+ /*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+ float
+ random::laplacian()
+ {
+ float z = ran1();
+ if(z < 0.5)
+ return log(2.0 * z) / M_SQRT2;
+ else
+ return -log(2.0 * (1.0 - z)) / M_SQRT2;
+ }
+
+ /*
+ * Copied from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+ // 5 => scratchy, 8 => Geiger
+ float
+ random::impulse(float factor = 5)
+ {
+ float z = -M_SQRT2 * log(ran1());
+ if(fabsf(z) <= factor)
+ return 0.0;
+ else
+ return z;
+ }
+
+ /*
+ * Complex rayleigh is really gaussian I and gaussian Q
+ * It can also be generated by real rayleigh magnitude and
+ * uniform random angle
+ * Adapted from The KC7WW / OH2BNS Channel Simulator
+ * FIXME Need to check how good this is at some point
+ */
+ gr_complex
+ random::rayleigh_complex()
+ {
+ return gr_complex(gasdev(),gasdev());
+ }
+
+ /* Other option
+ mag = rayleigh();
+ ang = 2.0 * M_PI * RNG();
+ *Rx = rxx * cos(z);
+ *Iy = rxx * sin(z);
+ */
+
+ float
+ random::rayleigh()
+ {
+ return sqrt(-2.0 * log(ran1()));
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_sincos.c b/gnuradio-runtime/lib/math/sincos.cc
index a8d01b0da4..49a90d2128 100644
--- a/gnuradio-runtime/lib/gr_sincos.c
+++ b/gnuradio-runtime/lib/math/sincos.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004,2010 Free Software Foundation, Inc.
+ * Copyright 2004,2010,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -28,56 +28,58 @@
#define _GNU_SOURCE // ask for GNU extensions if available
#endif
-#include <gr_sincos.h>
+#include <gnuradio/sincos.h>
#include <math.h>
-// ----------------------------------------------------------------
+namespace gr {
#if defined (HAVE_SINCOS)
-void
-gr_sincos (double x, double *sinx, double *cosx)
-{
- sincos (x, sinx, cosx);
-}
+ void
+ sincos(double x, double *sinx, double *cosx)
+ {
+ ::sincos(x, sinx, cosx);
+ }
#else
-void
-gr_sincos (double x, double *sinx, double *cosx)
-{
- *sinx = sin (x);
- *cosx = cos (x);
-}
+ void
+ sincos(double x, double *sinx, double *cosx)
+ {
+ *sinx = ::sin(x);
+ *cosx = ::cos(x);
+ }
#endif
-// ----------------------------------------------------------------
+ // ----------------------------------------------------------------
#if defined (HAVE_SINCOSF)
-void
-gr_sincosf (float x, float *sinx, float *cosx)
-{
- sincosf (x, sinx, cosx);
-}
+ void
+ sincosf(float x, float *sinx, float *cosx)
+ {
+ ::sincosf(x, sinx, cosx);
+ }
#elif defined (HAVE_SINF) && defined (HAVE_COSF)
-void
-gr_sincosf (float x, float *sinx, float *cosx)
-{
- *sinx = sinf (x);
- *cosx = cosf (x);
-}
+ void
+ sincosf(float x, float *sinx, float *cosx)
+ {
+ *sinx = ::sinf(x);
+ *cosx = ::cosf(x);
+ }
#else
-void
-gr_sincosf (float x, float *sinx, float *cosx)
-{
- *sinx = sin (x);
- *cosx = cos (x);
-}
+ void
+ sincosf(float x, float *sinx, float *cosx)
+ {
+ *sinx = ::sin(x);
+ *cosx = ::cos(x);
+ }
#endif
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/sine_table.h b/gnuradio-runtime/lib/math/sine_table.h
index 69834943bc..69834943bc 100644
--- a/gnuradio-runtime/lib/sine_table.h
+++ b/gnuradio-runtime/lib/math/sine_table.h
diff --git a/gnuradio-runtime/lib/math/vco.h b/gnuradio-runtime/lib/math/vco.h
new file mode 100644
index 0000000000..fa11732c1f
--- /dev/null
+++ b/gnuradio-runtime/lib/math/vco.h
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,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.
+ */
+
+#ifndef _GR_VCO_H_
+#define _GR_VCO_H_
+
+#include <gnuradio/sincos.h>
+#include <gnuradio/gr_complex.h>
+#include <vector>
+#include <cmath>
+
+namespace gr {
+
+ /*!
+ * \brief base class template for Voltage Controlled Oscillator (VCO)
+ * \ingroup misc
+ */
+ template<class o_type, class i_type>
+ class vco
+ {
+ public:
+ vco() : d_phase(0) {}
+
+ virtual ~vco() {}
+
+ // radians
+ void set_phase(double angle) {
+ d_phase = angle;
+ }
+
+ void adjust_phase(double delta_phase) {
+ d_phase += delta_phase;
+ if(fabs (d_phase) > M_PI){
+
+ while(d_phase > M_PI)
+ d_phase -= 2*M_PI;
+
+ while(d_phase < -M_PI)
+ d_phase += 2*M_PI;
+ }
+ }
+
+ double get_phase() const { return d_phase; }
+
+ // compute sin and cos for current phase angle
+ void sincos(float *sinx, float *cosx) const;
+
+ // compute cos or sin for current phase angle
+ float cos() const { return std::cos(d_phase); }
+ float sin() const { return std::sin(d_phase); }
+
+ // compute a block at a time
+ void cos(float *output, const float *input,
+ int noutput_items, double k, double ampl = 1.0);
+
+ protected:
+ double d_phase;
+ };
+
+ template<class o_type, class i_type>
+ void
+ vco<o_type,i_type>::sincos(float *sinx, float *cosx) const
+ {
+ gr::sincosf(d_phase, sinx, cosx);
+ }
+
+ template<class o_type, class i_type>
+ void
+ vco<o_type,i_type>::cos(float *output, const float *input,
+ int noutput_items, double k, double ampl)
+ {
+ for(int i = 0; i < noutput_items; i++) {
+ output[i] = cos() * ampl;
+ adjust_phase(input[i] * k);
+ }
+ }
+
+} /* namespace gr */
+
+#endif /* _GR_VCO_H_ */
diff --git a/gnuradio-runtime/lib/message.cc b/gnuradio-runtime/lib/message.cc
new file mode 100644
index 0000000000..ac066d668e
--- /dev/null
+++ b/gnuradio-runtime/lib/message.cc
@@ -0,0 +1,82 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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 <gnuradio/message.h>
+#include <assert.h>
+#include <string.h>
+
+namespace gr {
+
+ static long s_ncurrently_allocated = 0;
+
+ message::sptr
+ message::make(long type, double arg1, double arg2, size_t length)
+ {
+ return message::sptr(new message(type, arg1, arg2, length));
+ }
+
+ message::sptr
+ message::make_from_string(const std::string s, long type, double arg1, double arg2)
+ {
+ message::sptr m = message::make(type, arg1, arg2, s.size());
+ memcpy(m->msg(), s.data(), s.size());
+ return m;
+ }
+
+ message::message(long type, double arg1, double arg2, size_t length)
+ : d_type(type), d_arg1(arg1), d_arg2(arg2)
+ {
+ if(length == 0)
+ d_buf_start = d_msg_start = d_msg_end = d_buf_end = 0;
+ else {
+ d_buf_start = new unsigned char[length];
+ d_msg_start = d_buf_start;
+ d_msg_end = d_buf_end = d_buf_start + length;
+ }
+ s_ncurrently_allocated++;
+ }
+
+ message::~message()
+ {
+ assert (d_next == 0);
+ delete [] d_buf_start;
+ d_msg_start = d_msg_end = d_buf_end = 0;
+ s_ncurrently_allocated--;
+ }
+
+ std::string
+ message::to_string() const
+ {
+ return std::string((char *)d_msg_start, length());
+ }
+
+ long
+ message_ncurrently_allocated()
+ {
+ return s_ncurrently_allocated;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/messages/msg_accepter.cc b/gnuradio-runtime/lib/messages/msg_accepter.cc
index a0d2d840c6..cc86a6ff8a 100644
--- a/gnuradio-runtime/lib/messages/msg_accepter.cc
+++ b/gnuradio-runtime/lib/messages/msg_accepter.cc
@@ -24,7 +24,7 @@
#include "config.h"
#endif
-#include <messages/msg_accepter.h>
+#include <gnuradio/messages/msg_accepter.h>
namespace gr {
namespace messages {
diff --git a/gnuradio-runtime/lib/messages/msg_accepter_msgq.cc b/gnuradio-runtime/lib/messages/msg_accepter_msgq.cc
index adbea5ebc6..7ee6ea02c1 100644
--- a/gnuradio-runtime/lib/messages/msg_accepter_msgq.cc
+++ b/gnuradio-runtime/lib/messages/msg_accepter_msgq.cc
@@ -23,9 +23,7 @@
#include <config.h>
#endif
-#include <messages/msg_accepter_msgq.h>
-
-using namespace pmt;
+#include <gnuradio/messages/msg_accepter_msgq.h>
namespace gr {
namespace messages {
@@ -41,7 +39,7 @@ namespace gr {
}
void
- msg_accepter_msgq::post(pmt_t msg)
+ msg_accepter_msgq::post(pmt::pmt_t msg)
{
d_msg_queue->insert_tail(msg);
}
diff --git a/gnuradio-runtime/lib/messages/msg_producer.cc b/gnuradio-runtime/lib/messages/msg_producer.cc
index c354422aa6..3f56bc6637 100644
--- a/gnuradio-runtime/lib/messages/msg_producer.cc
+++ b/gnuradio-runtime/lib/messages/msg_producer.cc
@@ -24,7 +24,7 @@
#include "config.h"
#endif
-#include <messages/msg_producer.h>
+#include <gnuradio/messages/msg_producer.h>
namespace gr {
namespace messages {
diff --git a/gnuradio-runtime/lib/messages/msg_queue.cc b/gnuradio-runtime/lib/messages/msg_queue.cc
index 0d460dc05c..6db2d2daa2 100644
--- a/gnuradio-runtime/lib/messages/msg_queue.cc
+++ b/gnuradio-runtime/lib/messages/msg_queue.cc
@@ -24,11 +24,9 @@
#include "config.h"
#endif
-#include <messages/msg_queue.h>
+#include <gnuradio/messages/msg_queue.h>
#include <stdexcept>
-using namespace pmt;
-
namespace gr {
namespace messages {
@@ -49,7 +47,7 @@ namespace gr {
}
void
- msg_queue::insert_tail(pmt_t msg)
+ msg_queue::insert_tail(pmt::pmt_t msg)
{
gr::thread::scoped_lock guard(d_mutex);
@@ -60,7 +58,7 @@ namespace gr {
d_not_empty.notify_one();
}
- pmt_t
+ pmt::pmt_t
msg_queue::delete_head()
{
gr::thread::scoped_lock guard(d_mutex);
@@ -68,7 +66,7 @@ namespace gr {
while(empty_p())
d_not_empty.wait(guard);
- pmt_t m(d_msgs.front());
+ pmt::pmt_t m(d_msgs.front());
d_msgs.pop_front();
if(d_limit > 0) // Unlimited length queues never block on write
@@ -77,15 +75,15 @@ namespace gr {
return m;
}
- pmt_t
+ pmt::pmt_t
msg_queue::delete_head_nowait()
{
gr::thread::scoped_lock guard(d_mutex);
if(empty_p())
- return pmt_t();
+ return pmt::pmt_t();
- pmt_t m(d_msgs.front());
+ pmt::pmt_t m(d_msgs.front());
d_msgs.pop_front();
if(d_limit > 0) // Unlimited length queues never block on write
@@ -97,7 +95,7 @@ namespace gr {
void
msg_queue::flush()
{
- while(delete_head_nowait() != pmt_t())
+ while(delete_head_nowait() != pmt::pmt_t())
;
}
diff --git a/gnuradio-runtime/lib/gr_reverse.cc b/gnuradio-runtime/lib/misc.cc
index 08c588cb55..f9ad6ca89c 100644
--- a/gnuradio-runtime/lib/gr_reverse.cc
+++ b/gnuradio-runtime/lib/misc.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,37 +24,47 @@
#include "config.h"
#endif
-#include <gr_reverse.h>
+#include "misc.h"
+namespace gr {
-std::vector<float>
-gr_reverse (const std::vector<float> &taps)
-{
- int size = taps.size ();
- std::vector<float> new_taps(size);
+ unsigned int
+ rounduppow2(unsigned int n)
+ {
+ int i;
+ for(i=0;((n-1)>>i) != 0;i++)
+ ;
+ return 1<<i;
+ }
- if (size == 0)
- return new_taps;
+ // ----------------------------------------------------------------
- for (int i = 0; i < size; i++)
- new_taps[i] = taps[size - i - 1];
+ void
+ zero_vector(std::vector<float> &v)
+ {
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+ }
- return new_taps;
-}
+ void
+ zero_vector(std::vector<double> &v)
+ {
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+ }
+ void
+ zero_vector(std::vector<int> &v)
+ {
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+ }
-std::vector<gr_complex>
-gr_reverse (const std::vector<gr_complex> &taps)
-{
- int size = taps.size ();
- std::vector<gr_complex> new_taps(size);
-
- if (size == 0)
- return new_taps;
-
- for (int i = 0; i < size; i++)
- new_taps[i] = taps[size - i - 1];
-
- return new_taps;
-}
+ void
+ zero_vector(std::vector<gr_complex> &v)
+ {
+ for(unsigned int i=0; i < v.size(); i++)
+ v[i] = 0;
+ }
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_misc.h b/gnuradio-runtime/lib/misc.h
index 182ae87de6..833b6470a5 100644
--- a/gnuradio-runtime/lib/gr_misc.h
+++ b/gnuradio-runtime/lib/misc.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,17 +23,20 @@
#ifndef INCLUDED_GR_MISC_H
#define INCLUDED_GR_MISC_H
-#include <gr_runtime_api.h>
-#include <gr_types.h>
+#include <gnuradio/api.h>
+#include <gnuradio/types.h>
-GR_RUNTIME_API unsigned int
-gr_rounduppow2(unsigned int n);
+namespace gr {
-// FIXME should be template
-GR_RUNTIME_API void gr_zero_vector(std::vector<float> &v);
-GR_RUNTIME_API void gr_zero_vector(std::vector<double> &v);
-GR_RUNTIME_API void gr_zero_vector(std::vector<int> &v);
-GR_RUNTIME_API void gr_zero_vector(std::vector<gr_complex> &v);
+ GR_RUNTIME_API unsigned int
+ rounduppow2(unsigned int n);
+ // FIXME should be template
+ GR_RUNTIME_API void zero_vector(std::vector<float> &v);
+ GR_RUNTIME_API void zero_vector(std::vector<double> &v);
+ GR_RUNTIME_API void zero_vector(std::vector<int> &v);
+ GR_RUNTIME_API void zero_vector(std::vector<gr_complex> &v);
+
+} /* namespace gr */
#endif /* INCLUDED_GR_MISC_H */
diff --git a/gnuradio-runtime/lib/gr_msg_accepter.cc b/gnuradio-runtime/lib/msg_accepter.cc
index 93d5fb20e8..354fce0c3d 100644
--- a/gnuradio-runtime/lib/gr_msg_accepter.cc
+++ b/gnuradio-runtime/lib/msg_accepter.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2009 Free Software Foundation, Inc.
+ * Copyright 2009,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,37 +23,40 @@
#include <config.h>
#endif
-#include <gr_msg_accepter.h>
-#include <gr_block.h>
-#include <gr_block_detail.h>
-#include <gr_hier_block2.h>
+#include <gnuradio/msg_accepter.h>
+#include <gnuradio/block.h>
+#include <gnuradio/block_detail.h>
+#include <gnuradio/hier_block2.h>
#include <stdexcept>
-using namespace pmt;
-
-gr_msg_accepter::gr_msg_accepter()
-{
-}
-
-gr_msg_accepter::~gr_msg_accepter()
-{
- // NOP, required as virtual destructor
-}
-
-void
-gr_msg_accepter::post(pmt_t which_port, pmt_t msg)
-{
- // Notify derived class, handled case by case
- gr_block *p = dynamic_cast<gr_block *>(this);
- if (p) {
- p->_post(which_port,msg);
- return;
+namespace gr {
+
+ msg_accepter::msg_accepter()
+ {
+ }
+
+ msg_accepter::~msg_accepter()
+ {
+ // NOP, required as virtual destructor
}
- gr_hier_block2 *p2 = dynamic_cast<gr_hier_block2 *>(this);
- if (p2){
- // FIXME do the right thing
- return;
+
+ void
+ msg_accepter::post(pmt::pmt_t which_port, pmt::pmt_t msg)
+ {
+ // Notify derived class, handled case by case
+ block *p = dynamic_cast<block *>(this);
+ if(p) {
+ p->_post(which_port, msg);
+ return;
+ }
+
+ hier_block2 *p2 = dynamic_cast<hier_block2 *>(this);
+ if(p2) {
+ // FIXME do the right thing
+ return;
+ }
+
+ throw std::runtime_error("unknown derived class");
}
- throw std::runtime_error("unknown derived class");
-}
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_msg_handler.cc b/gnuradio-runtime/lib/msg_handler.cc
index 0f93497088..32d14eb715 100644
--- a/gnuradio-runtime/lib/gr_msg_handler.cc
+++ b/gnuradio-runtime/lib/msg_handler.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,8 +23,13 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <gr_msg_handler.h>
-gr_msg_handler::~gr_msg_handler ()
-{
-}
+#include <gnuradio/msg_handler.h>
+
+namespace gr {
+
+ msg_handler::~msg_handler()
+ {
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/msg_queue.cc b/gnuradio-runtime/lib/msg_queue.cc
new file mode 100644
index 0000000000..9961f76296
--- /dev/null
+++ b/gnuradio-runtime/lib/msg_queue.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005,2009,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/msg_queue.h>
+#include <stdexcept>
+
+namespace gr {
+
+ msg_queue::sptr
+ msg_queue::make(unsigned int limit)
+ {
+ return msg_queue::sptr(new msg_queue(limit));
+ }
+
+ msg_queue::msg_queue(unsigned int limit)
+ : d_not_empty(), d_not_full(),
+ /*d_head(0), d_tail(0),*/ d_count(0), d_limit(limit)
+ {
+ }
+
+ msg_queue::~msg_queue()
+ {
+ flush ();
+ }
+
+ void
+ msg_queue::insert_tail(message::sptr msg)
+ {
+ if(msg->d_next)
+ throw std::invalid_argument("gr::msg_queue::insert_tail: msg already in queue");
+
+ gr::thread::scoped_lock guard(d_mutex);
+
+ while(full_p())
+ d_not_full.wait(guard);
+
+ if(d_tail == 0) {
+ d_tail = d_head = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ else {
+ d_tail->d_next = msg;
+ d_tail = msg;
+ //msg->d_next = 0;
+ msg->d_next.reset();
+ }
+ d_count++;
+ d_not_empty.notify_one();
+ }
+
+ message::sptr
+ msg_queue::delete_head()
+ {
+ gr::thread::scoped_lock guard(d_mutex);
+ message::sptr m;
+
+ while((m = d_head) == 0)
+ d_not_empty.wait(guard);
+
+ d_head = m->d_next;
+ if(d_head == 0){
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ // m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.notify_one();
+ return m;
+ }
+
+ message::sptr
+ msg_queue::delete_head_nowait()
+ {
+ gr::thread::scoped_lock guard(d_mutex);
+ message::sptr m;
+
+ if((m = d_head) == 0) {
+ //return 0;
+ return message::sptr();
+ }
+
+ d_head = m->d_next;
+ if(d_head == 0) {
+ //d_tail = 0;
+ d_tail.reset();
+ }
+
+ d_count--;
+ //m->d_next = 0;
+ m->d_next.reset();
+ d_not_full.notify_one();
+ return m;
+ }
+
+ void
+ msg_queue::flush()
+ {
+ message::sptr m;
+
+ while((m = delete_head_nowait ()) != 0)
+ ;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_pagesize.cc b/gnuradio-runtime/lib/pagesize.cc
index e31e05ca70..373c0b6654 100644
--- a/gnuradio-runtime/lib/gr_pagesize.cc
+++ b/gnuradio-runtime/lib/pagesize.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2003 Free Software Foundation, Inc.
+ * Copyright 2003,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,33 +24,36 @@
#include "config.h"
#endif
-#include <gr_pagesize.h>
+#include "pagesize.h"
#include <unistd.h>
#include <stdio.h>
+namespace gr {
+
#if defined(_WIN32) && defined(HAVE_GETPAGESIZE)
-extern "C" size_t getpagesize(void);
+ extern "C" size_t getpagesize(void);
#endif
-int
-gr_pagesize ()
-{
- static int s_pagesize = -1;
+ int
+ pagesize()
+ {
+ static int s_pagesize = -1;
- if (s_pagesize == -1){
+ if(s_pagesize == -1) {
#if defined(HAVE_GETPAGESIZE)
- s_pagesize = getpagesize ();
+ s_pagesize = getpagesize();
#elif defined (HAVE_SYSCONF)
- s_pagesize = sysconf (_SC_PAGESIZE);
- if (s_pagesize == -1){
- perror ("_SC_PAGESIZE");
- s_pagesize = 4096;
- }
+ s_pagesize = sysconf(_SC_PAGESIZE);
+ if(s_pagesize == -1) {
+ perror("_SC_PAGESIZE");
+ s_pagesize = 4096;
+ }
#else
- fprintf (stderr, "gr_pagesize: no info; setting pagesize = 4096\n");
- s_pagesize = 4096;
+ fprintf(stderr, "gr::pagesize: no info; setting pagesize = 4096\n");
+ s_pagesize = 4096;
#endif
+ }
+ return s_pagesize;
}
- return s_pagesize;
-}
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_pagesize.h b/gnuradio-runtime/lib/pagesize.h
index d14cb22b1b..6a16882002 100644
--- a/gnuradio-runtime/lib/gr_pagesize.h
+++ b/gnuradio-runtime/lib/pagesize.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2003 Free Software Foundation, Inc.
+ * Copyright 2003,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,16 +19,19 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef _GR_PAGESIZE_H_
-#define _GR_PAGESIZE_H_
-#include <gr_runtime_api.h>
+#ifndef GR_PAGESIZE_H_
+#define GR_PAGESIZE_H_
-/*!
- * \brief return the page size in bytes
- */
+#include <gnuradio/api.h>
+
+namespace gr {
-GR_RUNTIME_API int gr_pagesize ();
+ /*!
+ * \brief return the page size in bytes
+ */
+ GR_RUNTIME_API int pagesize();
+} /* namespace gr */
-#endif /* _GR_PAGESIZE_H_ */ \ No newline at end of file
+#endif /* GR_PAGESIZE_H_ */
diff --git a/gnuradio-runtime/lib/pmt/pmt.cc b/gnuradio-runtime/lib/pmt/pmt.cc
index b6b3004331..f3f7783839 100644
--- a/gnuradio-runtime/lib/pmt/pmt.cc
+++ b/gnuradio-runtime/lib/pmt/pmt.cc
@@ -27,7 +27,7 @@
#include <vector>
#include <pmt/pmt.h>
#include "pmt_int.h"
-#include <messages/msg_accepter.h>
+#include <gnuradio/messages/msg_accepter.h>
#include <pmt/pmt_pool.h>
#include <stdio.h>
#include <string.h>
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt.h b/gnuradio-runtime/lib/pmt/qa_pmt.h
index 3e0c91abac..9293a076a6 100644
--- a/gnuradio-runtime/lib/pmt/qa_pmt.h
+++ b/gnuradio-runtime/lib/pmt/qa_pmt.h
@@ -23,7 +23,7 @@
#ifndef INCLUDED_QA_PMT_H
#define INCLUDED_QA_PMT_H
-#include <attributes.h>
+#include <gnuradio/attributes.h>
#include <cppunit/TestSuite.h>
//! collect all the tests for pmt
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
index e9a897deac..bfe71fbe5a 100644
--- a/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_prims.cc
@@ -22,7 +22,7 @@
#include <qa_pmt_prims.h>
#include <cppunit/TestAssert.h>
-#include <messages/msg_passing.h>
+#include <gnuradio/messages/msg_passing.h>
#include <boost/format.hpp>
#include <cstdio>
#include <cstring>
diff --git a/gnuradio-runtime/lib/pmt/qa_pmt_prims.h b/gnuradio-runtime/lib/pmt/qa_pmt_prims.h
index 8c3f5c6220..f2f3dd77f7 100644
--- a/gnuradio-runtime/lib/pmt/qa_pmt_prims.h
+++ b/gnuradio-runtime/lib/pmt/qa_pmt_prims.h
@@ -22,13 +22,13 @@
#ifndef INCLUDED_QA_PMT_PRIMS_H
#define INCLUDED_QA_PMT_PRIMS_H
-#include <attributes.h>
+#include <gnuradio/attributes.h>
#include <pmt/api.h> //reason: suppress warnings
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class __GR_ATTR_EXPORT qa_pmt_prims : public CppUnit::TestCase {
-
+class __GR_ATTR_EXPORT qa_pmt_prims : public CppUnit::TestCase
+{
CPPUNIT_TEST_SUITE(qa_pmt_prims);
CPPUNIT_TEST(test_symbols);
CPPUNIT_TEST(test_booleans);
diff --git a/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t b/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
index a04d532b4e..ea675cee16 100644
--- a/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
+++ b/gnuradio-runtime/lib/pmt/unv_qa_template.cc.t
@@ -2,7 +2,7 @@ void
qa_pmt_unv::test_@TAG@vector()
{
static const size_t N = 3;
- pmt_t v1 = pmt::make_@TAG@vector(N, 0);
+ pmt::pmt_t v1 = pmt::make_@TAG@vector(N, 0);
CPPUNIT_ASSERT_EQUAL(N, pmt::length(v1));
@TYPE@ s0 = @TYPE@(10);
@TYPE@ s1 = @TYPE@(20);
diff --git a/gnuradio-runtime/lib/posix_memalign.cc b/gnuradio-runtime/lib/posix_memalign.cc
index aaeff78042..a08e9e127a 100644
--- a/gnuradio-runtime/lib/posix_memalign.cc
+++ b/gnuradio-runtime/lib/posix_memalign.cc
@@ -36,7 +36,7 @@
/* emulate posix_memalign functionality, to some degree */
#include <errno.h>
-#include "gr_pagesize.h"
+#include "pagesize.h"
int posix_memalign
(void **memptr, size_t alignment, size_t size)
@@ -86,7 +86,7 @@ int posix_memalign
/* 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 ()) {
+ if (alignment <= (size_t) gr::pagesize ()) {
*memptr = valloc (size);
}
}
diff --git a/gnuradio-runtime/lib/prefs.cc b/gnuradio-runtime/lib/prefs.cc
new file mode 100644
index 0000000000..468532f33b
--- /dev/null
+++ b/gnuradio-runtime/lib/prefs.cc
@@ -0,0 +1,401 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gnuradio/prefs.h>
+#include <gnuradio/sys_paths.h>
+#include <gnuradio/constants.h>
+#include <algorithm>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/fstream.hpp>
+namespace fs = boost::filesystem;
+
+namespace gr {
+
+ /*
+ * Stub implementations
+ */
+ static prefs s_default_singleton;
+ static prefs *s_singleton = &s_default_singleton;
+
+ prefs *
+ prefs::singleton()
+ {
+ return s_singleton;
+ }
+
+ void
+ prefs::set_singleton(prefs *p)
+ {
+ s_singleton = p;
+ }
+
+ prefs::prefs()
+ {
+ _read_files();
+ }
+
+ prefs::~prefs()
+ {
+ // nop
+ }
+
+ std::vector<std::string>
+ prefs::_sys_prefs_filenames()
+ {
+ std::vector<std::string> fnames;
+
+ fs::path dir = prefsdir();
+ if(!fs::is_directory(dir))
+ return fnames;
+
+ fs::directory_iterator diritr(dir);
+ while(diritr != fs::directory_iterator()) {
+ fs::path p = *diritr++;
+ if(p.extension() != ".swp")
+ fnames.push_back(p.string());
+ }
+ std::sort(fnames.begin(), fnames.end());
+
+ // Find if there is a ~/.gnuradio/config.conf file and add this to
+ // the end of the file list to override any preferences in the
+ // installed path config files.
+ fs::path homedir = fs::path(gr::appdata_path());
+ homedir = homedir/".gnuradio/config.conf";
+ if(fs::exists(homedir)) {
+ fnames.push_back(homedir.string());
+ }
+
+ return fnames;
+ }
+
+ void
+ prefs::_read_files()
+ {
+ std::string config;
+
+ std::vector<std::string> filenames = _sys_prefs_filenames();
+ std::vector<std::string>::iterator sitr;
+ char tmp[1024];
+ for(sitr = filenames.begin(); sitr != filenames.end(); sitr++) {
+ fs::ifstream fin(*sitr);
+ while(!fin.eof()) {
+ fin.getline(tmp, 1024);
+ std::string t(tmp);
+ // ignore empty lines or lines of just comments
+ if((t.size() > 0) && (t[0] != '#')) {
+ // remove any comments in the line
+ size_t hash = t.find("#");
+
+ // Use hash marks at the end of each segment as a delimiter
+ config += t.substr(0, hash) + '#';
+ }
+ }
+ fin.close();
+ }
+
+ // Remove all whitespace.
+ config.erase(std::remove_if(config.begin(), config.end(),
+ ::isspace), config.end());
+
+ // Convert the string into a map
+ _convert_to_map(config);
+ }
+
+ void
+ prefs::_convert_to_map(const std::string &conf)
+ {
+ // Convert the string into an map of maps
+ // Map is structured as {section name: map of options}
+ // And options map is simply: {option name: option value}
+ std::string sub = conf;
+ size_t sec_start = sub.find("[");
+ while(sec_start != std::string::npos) {
+ sub = sub.substr(sec_start);
+
+ size_t sec_end = sub.find("]");
+ if(sec_end == std::string::npos)
+ throw std::runtime_error("Config file error: Mismatched section label.\n");
+
+ std::string sec = sub.substr(1, sec_end-1);
+ size_t next_sec_start = sub.find("[", sec_end);
+ std::string subsec = sub.substr(sec_end+1, next_sec_start-sec_end-2);
+
+ std::transform(sec.begin(), sec.end(), sec.begin(), ::tolower);
+
+ std::map<std::string, std::string> options_map = d_config_map[sec];
+ size_t next_opt = 0;
+ size_t next_val = 0;
+ next_opt = subsec.find("#");
+ while(next_opt < subsec.size()-1) {
+ next_val = subsec.find("=", next_opt);
+ std::string option = subsec.substr(next_opt+1, next_val-next_opt-1);
+
+ next_opt = subsec.find("#", next_val);
+ std::string value = subsec.substr(next_val+1, next_opt-next_val-1);
+
+ std::transform(option.begin(), option.end(), option.begin(), ::tolower);
+ options_map[option] = value;
+ }
+
+ d_config_map[sec] = options_map;
+
+ sec_start = sub.find("[", sec_end);
+ }
+ }
+
+ std::string
+ prefs::to_string()
+ {
+ config_map_itr sections;
+ config_map_elem_itr options;
+ std::stringstream s;
+
+ for(sections = d_config_map.begin(); sections != d_config_map.end(); sections++) {
+ s << "[" << sections->first << "]" << std::endl;
+ for(options = sections->second.begin(); options != sections->second.end(); options++) {
+ s << options->first << " = " << options->second << std::endl;
+ }
+ s << std::endl;
+ }
+
+ return s.str();
+ }
+
+ void
+ prefs::save()
+ {
+ std::string conf = to_string();
+
+ fs::path homedir = fs::path(gr::appdata_path());
+ homedir = homedir/".gnuradio/config.conf";
+ fs::ofstream fout(homedir);
+ fout << conf;
+ fout.close();
+ }
+
+ char *
+ prefs::option_to_env(std::string section, std::string option)
+ {
+ std::stringstream envname;
+ std::string secname=section, optname=option;
+
+ std::transform(section.begin(), section.end(), secname.begin(), ::toupper);
+ std::transform(option.begin(), option.end(), optname.begin(), ::toupper);
+ envname << "GR_CONF_" << secname << "_" << optname;
+
+ return getenv(envname.str().c_str());
+ }
+
+ bool
+ prefs::has_section(const std::string &section)
+ {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+ return d_config_map.count(s) > 0;
+ }
+
+ bool
+ prefs::has_option(const std::string &section, const std::string &option)
+ {
+ if(option_to_env(section, option))
+ return true;
+
+ if(has_section(section)) {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ config_map_itr sec = d_config_map.find(s);
+ return sec->second.count(o) > 0;
+ }
+ else {
+ return false;
+ }
+ }
+
+ const std::string
+ prefs::get_string(const std::string &section, const std::string &option,
+ const std::string &default_val)
+ {
+ char *env = option_to_env(section, option);
+ if(env)
+ return std::string(env);
+
+ if(has_option(section, option)) {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ config_map_itr sec = d_config_map.find(s);
+ config_map_elem_itr opt = sec->second.find(o);
+ return opt->second;
+ }
+ else {
+ return default_val;
+ }
+ }
+
+ void
+ prefs::set_string(const std::string &section, const std::string &option,
+ const std::string &val)
+ {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ std::map<std::string, std::string> opt_map = d_config_map[s];
+
+ opt_map[o] = val;
+
+ d_config_map[s] = opt_map;
+ }
+
+ bool
+ prefs::get_bool(const std::string &section, const std::string &option,
+ bool default_val)
+ {
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+ if((str == "true") || (str == "on") || (str == "1"))
+ return true;
+ else if((str == "false") || (str == "off") || (str == "0"))
+ return false;
+ else
+ return default_val;
+ }
+ else {
+ return default_val;
+ }
+ }
+
+ void
+ prefs::set_bool(const std::string &section, const std::string &option,
+ bool val)
+ {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ std::map<std::string, std::string> opt_map = d_config_map[s];
+
+ std::stringstream sstr;
+ sstr << (val == true);
+ opt_map[o] = sstr.str();
+
+ d_config_map[s] = opt_map;
+ }
+
+ long
+ prefs::get_long(const std::string &section, const std::string &option,
+ long default_val)
+ {
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::stringstream sstr(str);
+ long n;
+ sstr >> n;
+ return n;
+ }
+ else {
+ return default_val;
+ }
+ }
+
+ void
+ prefs::set_long(const std::string &section, const std::string &option,
+ long val)
+ {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ std::map<std::string, std::string> opt_map = d_config_map[s];
+
+ std::stringstream sstr;
+ sstr << val;
+ opt_map[o] = sstr.str();
+
+ d_config_map[s] = opt_map;
+ }
+
+ double
+ prefs::get_double(const std::string &section, const std::string &option,
+ double default_val)
+ {
+ if(has_option(section, option)) {
+ std::string str = get_string(section, option, "");
+ if(str == "") {
+ return default_val;
+ }
+ std::stringstream sstr(str);
+ double n;
+ sstr >> n;
+ return n;
+ }
+ else {
+ return default_val;
+ }
+ }
+
+ void
+ prefs::set_double(const std::string &section, const std::string &option,
+ double val)
+ {
+ std::string s = section;
+ std::transform(section.begin(), section.end(), s.begin(), ::tolower);
+
+ std::string o = option;
+ std::transform(option.begin(), option.end(), o.begin(), ::tolower);
+
+ std::map<std::string, std::string> opt_map = d_config_map[s];
+
+ std::stringstream sstr;
+ sstr << val;
+ opt_map[o] = sstr.str();
+
+ d_config_map[s] = opt_map;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/qa_buffer.cc b/gnuradio-runtime/lib/qa_buffer.cc
new file mode 100644
index 0000000000..5f1dece0ad
--- /dev/null
+++ b/gnuradio-runtime/lib/qa_buffer.cc
@@ -0,0 +1,304 @@
+/* -*- 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 <qa_buffer.h>
+#include <gnuradio/buffer.h>
+#include <cppunit/TestAssert.h>
+#include <stdlib.h>
+#include <gnuradio/random.h>
+
+static void
+leak_check(void f())
+{
+ long buffer_count = gr::buffer_ncurrently_allocated();
+ long buffer_reader_count = gr::buffer_reader_ncurrently_allocated();
+
+ f();
+
+ CPPUNIT_ASSERT_EQUAL(buffer_reader_count, gr::buffer_reader_ncurrently_allocated());
+ CPPUNIT_ASSERT_EQUAL(buffer_count, gr::buffer_ncurrently_allocated());
+}
+
+
+// ----------------------------------------------------------------------------
+// test single writer, no readers...
+//
+
+static void
+t0_body()
+{
+ int nitems = 4000 / sizeof(int);
+ int counter = 0;
+
+ gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr()));
+
+ int last_sa;
+ int sa;
+
+ sa = buf->space_available();
+ CPPUNIT_ASSERT(sa > 0);
+ last_sa = sa;
+
+ for(int i = 0; i < 5; i++) {
+ sa = buf->space_available();
+ CPPUNIT_ASSERT_EQUAL(last_sa, sa);
+ last_sa = sa;
+
+ int *p = (int*)buf->write_pointer();
+ CPPUNIT_ASSERT(p != 0);
+
+ for(int j = 0; j < sa; j++)
+ *p++ = counter++;
+
+ buf->update_write_pointer(sa);
+ }
+}
+
+// ----------------------------------------------------------------------------
+// test single writer, single reader
+//
+
+static void
+t1_body()
+{
+ int nitems = 4000 / sizeof(int);
+ int write_counter = 0;
+ int read_counter = 0;
+
+ gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr()));
+ gr::buffer_reader_sptr r1(gr::buffer_add_reader(buf, 0, gr::block_sptr()));
+
+ int sa;
+
+ // write 1/3 of buffer
+
+ sa = buf->space_available();
+ CPPUNIT_ASSERT(sa > 0);
+
+ int *p = (int*)buf->write_pointer();
+ CPPUNIT_ASSERT(p != 0);
+
+ for(int j = 0; j < sa/3; j++) {
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer(sa/3);
+
+ // write the next 1/3 (1/2 of what's left)
+
+ sa = buf->space_available();
+ CPPUNIT_ASSERT(sa > 0);
+
+ p = (int*)buf->write_pointer();
+ CPPUNIT_ASSERT(p != 0);
+
+ for(int j = 0; j < sa/2; j++) {
+ *p++ = write_counter++;
+ }
+ buf->update_write_pointer(sa/2);
+
+ // check that we can read it OK
+
+ int ia = r1->items_available();
+ CPPUNIT_ASSERT_EQUAL(write_counter, ia);
+
+ int *rp = (int*)r1->read_pointer();
+ CPPUNIT_ASSERT(rp != 0);
+
+ for(int i = 0; i < ia/2; i++) {
+ CPPUNIT_ASSERT_EQUAL(read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer(ia/2);
+
+ // read the rest
+
+ ia = r1->items_available();
+ rp = (int *) r1->read_pointer();
+ CPPUNIT_ASSERT(rp != 0);
+
+ for(int i = 0; i < ia; i++) {
+ CPPUNIT_ASSERT_EQUAL(read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer(ia);
+}
+
+// ----------------------------------------------------------------------------
+// single writer, single reader: check wrap-around
+//
+
+static void
+t2_body()
+{
+ // 64K is the largest granularity we've seen so far (MS windows file mapping).
+ // This allows a bit of "white box testing"
+
+ int nitems = (64 * (1L << 10)) / sizeof(int); // 64K worth of ints
+
+ gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr()));
+ gr::buffer_reader_sptr r1(gr::buffer_add_reader(buf, 0, gr::block_sptr()));
+
+ int read_counter = 0;
+ int write_counter = 0;
+ int n;
+ int *wp = 0;
+ int *rp = 0;
+
+ // Write 3/4 of buffer
+
+ n = (int)(buf->space_available() * 0.75);
+ wp = (int*)buf->write_pointer();
+
+ for(int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer(n);
+
+ // Now read it all
+
+ int m = r1->items_available();
+ CPPUNIT_ASSERT_EQUAL(n, m);
+ rp = (int*)r1->read_pointer();
+
+ for(int i = 0; i < m; i++) {
+ CPPUNIT_ASSERT_EQUAL(read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer(m);
+
+ // Now write as much as we can.
+ // This will wrap around the buffer
+
+ n = buf->space_available();
+ CPPUNIT_ASSERT_EQUAL(nitems - 1, n); // white box test
+ wp = (int*)buf->write_pointer();
+
+ for(int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+ buf->update_write_pointer(n);
+
+ // now read it all
+
+ m = r1->items_available();
+ CPPUNIT_ASSERT_EQUAL(n, m);
+ rp = (int*)r1->read_pointer();
+
+ for(int i = 0; i < m; i++) {
+ CPPUNIT_ASSERT_EQUAL(read_counter, *rp);
+ read_counter++;
+ rp++;
+ }
+ r1->update_read_pointer(m);
+}
+
+// ----------------------------------------------------------------------------
+// single writer, N readers, randomized order and lengths
+// ----------------------------------------------------------------------------
+
+static void
+t3_body()
+{
+ int nitems = (64 * (1L << 10)) / sizeof(int);
+
+ static const int N = 5;
+ gr::buffer_sptr buf(gr::make_buffer(nitems, sizeof(int), gr::block_sptr()));
+ gr::buffer_reader_sptr reader[N];
+ int read_counter[N];
+ int write_counter = 0;
+ gr::random random;
+
+ for(int i = 0; i < N; i++) {
+ read_counter[i] = 0;
+ reader[i] = buffer_add_reader(buf, 0, gr::block_sptr());
+ }
+
+ for(int lc = 0; lc < 1000; lc++) {
+
+ // write some
+
+ int n = (int)(buf->space_available() * random.ran1());
+ int *wp = (int*)buf->write_pointer();
+
+ for(int i = 0; i < n; i++)
+ *wp++ = write_counter++;
+
+ buf->update_write_pointer(n);
+
+ // pick a random reader and read some
+
+ int r = (int)(N * random.ran1());
+ CPPUNIT_ASSERT(0 <= r && r < N);
+
+ int m = reader[r]->items_available();
+ int *rp = (int*)reader[r]->read_pointer();
+
+ for(int i = 0; i < m; i++) {
+ CPPUNIT_ASSERT_EQUAL(read_counter[r], *rp);
+ read_counter[r]++;
+ rp++;
+ }
+ reader[r]->update_read_pointer (m);
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+
+void
+qa_buffer::t0()
+{
+ leak_check(t0_body);
+}
+
+void
+qa_buffer::t1()
+{
+ leak_check(t1_body);
+}
+
+void
+qa_buffer::t2()
+{
+ leak_check(t2_body);
+}
+
+void
+qa_buffer::t3()
+{
+ leak_check(t3_body);
+}
+
+void
+qa_buffer::t4()
+{
+}
+
+void
+qa_buffer::t5()
+{
+}
diff --git a/gnuradio-runtime/lib/qa_gr_buffer.h b/gnuradio-runtime/lib/qa_buffer.h
index 2937c24b68..a41e69dd48 100644
--- a/gnuradio-runtime/lib/qa_gr_buffer.h
+++ b/gnuradio-runtime/lib/qa_buffer.h
@@ -26,28 +26,24 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_buffer : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_buffer);
- CPPUNIT_TEST (t0);
- CPPUNIT_TEST (t1);
- CPPUNIT_TEST (t2);
- CPPUNIT_TEST (t3);
- CPPUNIT_TEST (t4);
- CPPUNIT_TEST (t5);
- CPPUNIT_TEST_SUITE_END ();
-
+class qa_buffer : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_buffer);
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST(t4);
+ CPPUNIT_TEST(t5);
+ CPPUNIT_TEST_SUITE_END();
private:
-
- void t0 ();
- void t1 ();
- void t2 ();
- void t3 ();
- void t4 ();
- void t5 ();
+ void t0();
+ void t1();
+ void t2();
+ void t3();
+ void t4();
+ void t5();
};
-
-
#endif /* INCLUDED_QA_GR_BUFFER_H */
diff --git a/gnuradio-runtime/lib/qa_gr_circular_file.cc b/gnuradio-runtime/lib/qa_circular_file.cc
index 243e44784b..d80831b4b9 100644
--- a/gnuradio-runtime/lib/qa_gr_circular_file.cc
+++ b/gnuradio-runtime/lib/qa_circular_file.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2002 Free Software Foundation, Inc.
+ * Copyright 2002,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -23,8 +23,9 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <qa_gr_circular_file.h>
-#include <gr_circular_file.h>
+
+#include "qa_circular_file.h"
+#include "circular_file.h"
#include <cppunit/TestAssert.h>
#include <iostream>
#include <stdio.h>
@@ -35,38 +36,37 @@ static const int BUFFER_SIZE = 8192;
static const int NWRITE = 8192 * 9 / 8;
void
-qa_gr_circular_file::t1 ()
+qa_circular_file::t1()
{
#ifdef HAVE_MMAP
- gr_circular_file *cf_writer;
- gr_circular_file *cf_reader;
+ gr::circular_file *cf_writer;
+ gr::circular_file *cf_reader;
// write the data...
-
- cf_writer = new gr_circular_file (test_file, true, BUFFER_SIZE * sizeof (short));
+ cf_writer = new gr::circular_file(test_file, true,
+ BUFFER_SIZE * sizeof(short));
short sd;
- for (int i = 0; i < NWRITE; i++){
+ for(int i = 0; i < NWRITE; i++) {
sd = i;
- cf_writer->write (&sd, sizeof (sd));
+ cf_writer->write(&sd, sizeof (sd));
}
delete cf_writer;
// now read it back...
-
- cf_reader = new gr_circular_file (test_file);
- for (int i = 0; i < BUFFER_SIZE; i++){
- int n = cf_reader->read (&sd, sizeof (sd));
- CPPUNIT_ASSERT_EQUAL ((int) sizeof (sd), n);
- CPPUNIT_ASSERT_EQUAL (NWRITE - BUFFER_SIZE + i, (int) sd);
+ cf_reader = new gr::circular_file(test_file);
+ for(int i = 0; i < BUFFER_SIZE; i++) {
+ int n = cf_reader->read (&sd, sizeof(sd));
+ CPPUNIT_ASSERT_EQUAL((int) sizeof (sd), n);
+ CPPUNIT_ASSERT_EQUAL(NWRITE - BUFFER_SIZE + i, (int)sd);
}
- int n = cf_reader->read (&sd, sizeof (sd));
- CPPUNIT_ASSERT_EQUAL (0, n);
+ int n = cf_reader->read(&sd, sizeof(sd));
+ CPPUNIT_ASSERT_EQUAL(0, n);
delete cf_reader;
- unlink (test_file);
+ unlink(test_file);
#endif // HAVE_MMAP
}
diff --git a/gnuradio-runtime/lib/qa_gr_vmcircbuf.h b/gnuradio-runtime/lib/qa_circular_file.h
index 3576660d5a..fd5c156b56 100644
--- a/gnuradio-runtime/lib/qa_gr_vmcircbuf.h
+++ b/gnuradio-runtime/lib/qa_circular_file.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2002,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,21 +19,21 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef _QA_GR_VMCIRCBUF_H_
-#define _QA_GR_VMCIRCBUF_H_
+
+#ifndef QA_GR_CIRCULAR_FILE_H
+#define QA_GR_CIRCULAR_FILE_H
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_vmcircbuf : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_vmcircbuf);
- CPPUNIT_TEST (test_all);
- CPPUNIT_TEST_SUITE_END ();
+class qa_circular_file : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_circular_file);
+ CPPUNIT_TEST(t1);
+ CPPUNIT_TEST_SUITE_END();
- private:
- void test_all ();
+private:
+ void t1();
};
-
-#endif /* _QA_GR_VMCIRCBUF_H_ */
+#endif /* QA_GR_CIRCULAR_FILE_H */
diff --git a/gnuradio-runtime/lib/qa_gr_buffer.cc b/gnuradio-runtime/lib/qa_gr_buffer.cc
deleted file mode 100644
index c74baf398e..0000000000
--- a/gnuradio-runtime/lib/qa_gr_buffer.cc
+++ /dev/null
@@ -1,307 +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 <qa_gr_buffer.h>
-#include <gr_buffer.h>
-#include <cppunit/TestAssert.h>
-#include <stdlib.h>
-#include <gr_random.h>
-
-static void
-leak_check (void f ())
-{
- long buffer_count = gr_buffer_ncurrently_allocated ();
- long buffer_reader_count = gr_buffer_reader_ncurrently_allocated ();
-
- f ();
-
- CPPUNIT_ASSERT_EQUAL (buffer_reader_count, gr_buffer_reader_ncurrently_allocated ());
- CPPUNIT_ASSERT_EQUAL (buffer_count, gr_buffer_ncurrently_allocated ());
-}
-
-
-// ----------------------------------------------------------------------------
-// test single writer, no readers...
-//
-
-static void
-t0_body ()
-{
- int nitems = 4000 / sizeof (int);
- int counter = 0;
-
- gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr()));
-
- int last_sa;
- int sa;
-
- sa = buf->space_available ();
- CPPUNIT_ASSERT (sa > 0);
- last_sa = sa;
-
- for (int i = 0; i < 5; i++){
- sa = buf->space_available ();
- CPPUNIT_ASSERT_EQUAL (last_sa, sa);
- last_sa = sa;
-
- int *p = (int *) buf->write_pointer ();
- CPPUNIT_ASSERT (p != 0);
-
- for (int j = 0; j < sa; j++)
- *p++ = counter++;
-
- buf->update_write_pointer (sa);
- }
-}
-
-// ----------------------------------------------------------------------------
-// test single writer, single reader
-//
-
-static void
-t1_body ()
- {
- int nitems = 4000 / sizeof (int);
- int write_counter = 0;
- int read_counter = 0;
-
- gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr()));
- gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr()));
-
-
- int sa;
-
- // write 1/3 of buffer
-
- sa = buf->space_available ();
- CPPUNIT_ASSERT (sa > 0);
-
- int *p = (int *) buf->write_pointer ();
- CPPUNIT_ASSERT (p != 0);
-
- for (int j = 0; j < sa/3; j++){
- *p++ = write_counter++;
- }
- buf->update_write_pointer (sa/3);
-
-
- // write the next 1/3 (1/2 of what's left)
-
- sa = buf->space_available ();
- CPPUNIT_ASSERT (sa > 0);
-
- p = (int *) buf->write_pointer ();
- CPPUNIT_ASSERT (p != 0);
-
- for (int j = 0; j < sa/2; j++){
- *p++ = write_counter++;
- }
- buf->update_write_pointer (sa/2);
-
-
- // check that we can read it OK
-
- int ia = r1->items_available ();
- CPPUNIT_ASSERT_EQUAL (write_counter, ia);
-
- int *rp = (int *) r1->read_pointer ();
- CPPUNIT_ASSERT (rp != 0);
-
- for (int i = 0; i < ia/2; i++){
- CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
- read_counter++;
- rp++;
- }
- r1->update_read_pointer (ia/2);
-
- // read the rest
-
- ia = r1->items_available ();
- rp = (int *) r1->read_pointer ();
- CPPUNIT_ASSERT (rp != 0);
-
- for (int i = 0; i < ia; i++){
- CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
- read_counter++;
- rp++;
- }
- r1->update_read_pointer (ia);
-}
-
-// ----------------------------------------------------------------------------
-// single writer, single reader: check wrap-around
-//
-
-static void
-t2_body ()
-{
- // 64K is the largest granularity we've seen so far (MS windows file mapping).
- // This allows a bit of "white box testing"
-
- int nitems = (64 * (1L << 10)) / sizeof (int); // 64K worth of ints
-
- gr_buffer_sptr buf(gr_make_buffer (nitems, sizeof (int), gr_block_sptr()));
- gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr()));
-
- int read_counter = 0;
- int write_counter = 0;
- int n;
- int *wp = 0;
- int *rp = 0;
-
- // Write 3/4 of buffer
-
- n = (int) (buf->space_available () * 0.75);
- wp = (int *) buf->write_pointer ();
-
- for (int i = 0; i < n; i++)
- *wp++ = write_counter++;
- buf->update_write_pointer (n);
-
- // Now read it all
-
- int m = r1->items_available ();
- CPPUNIT_ASSERT_EQUAL (n, m);
- rp = (int *) r1->read_pointer ();
-
- for (int i = 0; i < m; i++){
- CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
- read_counter++;
- rp++;
- }
- r1->update_read_pointer (m);
-
- // Now write as much as we can.
- // This will wrap around the buffer
-
- n = buf->space_available ();
- CPPUNIT_ASSERT_EQUAL (nitems - 1, n); // white box test
- wp = (int *) buf->write_pointer ();
-
- for (int i = 0; i < n; i++)
- *wp++ = write_counter++;
- buf->update_write_pointer (n);
-
- // now read it all
-
- m = r1->items_available ();
- CPPUNIT_ASSERT_EQUAL (n, m);
- rp = (int *) r1->read_pointer ();
-
- for (int i = 0; i < m; i++){
- CPPUNIT_ASSERT_EQUAL (read_counter, *rp);
- read_counter++;
- rp++;
- }
- r1->update_read_pointer (m);
-
-}
-
-// ----------------------------------------------------------------------------
-// single writer, N readers, randomized order and lengths
-// ----------------------------------------------------------------------------
-
-static void
-t3_body ()
-{
- int nitems = (64 * (1L << 10)) / sizeof (int);
-
- static const int N = 5;
- gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr()));
- gr_buffer_reader_sptr reader[N];
- int read_counter[N];
- int write_counter = 0;
- gr_random random;
-
- for (int i = 0; i < N; i++){
- read_counter[i] = 0;
- reader[i] = gr_buffer_add_reader (buf, 0, gr_block_sptr());
- }
-
- for (int lc = 0; lc < 1000; lc++){
-
- // write some
-
- int n = (int) (buf->space_available () * random.ran1 ());
- int *wp = (int *) buf->write_pointer ();
-
- for (int i = 0; i < n; i++)
- *wp++ = write_counter++;
-
- buf->update_write_pointer (n);
-
- // pick a random reader and read some
-
- int r = (int) (N * random.ran1 ());
- CPPUNIT_ASSERT (0 <= r && r < N);
-
- int m = reader[r]->items_available ();
- int *rp = (int *) reader[r]->read_pointer ();
-
- for (int i = 0; i < m; i++){
- CPPUNIT_ASSERT_EQUAL (read_counter[r], *rp);
- read_counter[r]++;
- rp++;
- }
- reader[r]->update_read_pointer (m);
- }
-}
-
-
-// ----------------------------------------------------------------------------
-
-void
-qa_gr_buffer::t0 ()
-{
- leak_check (t0_body);
-}
-
-void
-qa_gr_buffer::t1 ()
-{
- leak_check (t1_body);
-}
-
-void
-qa_gr_buffer::t2 ()
-{
- leak_check (t2_body);
-}
-
-void
-qa_gr_buffer::t3 ()
-{
- leak_check (t3_body);
-}
-
-void
-qa_gr_buffer::t4 ()
-{
-}
-
-void
-qa_gr_buffer::t5 ()
-{
-}
diff --git a/gnuradio-runtime/lib/qa_gr_fxpt.cc b/gnuradio-runtime/lib/qa_gr_fxpt.cc
deleted file mode 100644
index 7eac0d8964..0000000000
--- a/gnuradio-runtime/lib/qa_gr_fxpt.cc
+++ /dev/null
@@ -1,103 +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 <qa_gr_fxpt.h>
-#include <gr_fxpt.h>
-#include <cppunit/TestAssert.h>
-#include <iostream>
-#include <stdio.h>
-#include <unistd.h>
-#include <math.h>
-
-static const float SIN_COS_TOLERANCE = 1e-5;
-
-void
-qa_gr_fxpt::t0 ()
-{
- CPPUNIT_ASSERT_DOUBLES_EQUAL (M_PI/2, gr_fxpt::fixed_to_float (0x40000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (0.0, gr_fxpt::fixed_to_float (0x00000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (-M_PI, gr_fxpt::fixed_to_float (0x80000000), SIN_COS_TOLERANCE);
-
- if (0){
- /*
- * These are disabled because of some precision issues.
- *
- * Different compilers seem to have different opinions on whether
- * the calulations are done single or double (or extended)
- * precision. Any of the answers are fine for our real purpose, but
- * sometimes the answer is off by a few bits at the bottom.
- * Hence, the disabled check.
- */
- CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x40000000, gr_fxpt::float_to_fixed (M_PI/2));
- CPPUNIT_ASSERT_EQUAL ((gr_int32) 0, gr_fxpt::float_to_fixed (0));
- CPPUNIT_ASSERT_EQUAL ((gr_int32) 0x80000000, gr_fxpt::float_to_fixed (-M_PI));
- }
-}
-
-void
-qa_gr_fxpt::t1 ()
-{
-
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x00000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x20000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 1, gr_fxpt::sin (0x40000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0.707106781, gr_fxpt::sin (0x60000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x7fffffff), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x80000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL ( 0, gr_fxpt::sin (0x80000001), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (-1, gr_fxpt::sin (-0x40000000), SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (-0.707106781, gr_fxpt::sin (-0x20000000), SIN_COS_TOLERANCE);
-
-
- for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
- float expected = sin (p);
- float actual = gr_fxpt::sin (gr_fxpt::float_to_fixed (p));
- CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
- }
-}
-
-void
-qa_gr_fxpt::t2 ()
-{
- for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
- float expected = cos (p);
- float actual = gr_fxpt::cos (gr_fxpt::float_to_fixed (p));
- CPPUNIT_ASSERT_DOUBLES_EQUAL (expected, actual, SIN_COS_TOLERANCE);
- }
-}
-
-void
-qa_gr_fxpt::t3 ()
-{
- for (float p = -M_PI; p < M_PI; p += 2 * M_PI / 3600){
- float expected_sin = sin (p);
- float expected_cos = cos (p);
- float actual_sin;
- float actual_cos;
- gr_fxpt::sincos (gr_fxpt::float_to_fixed (p), &actual_sin, &actual_cos);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_sin, actual_sin, SIN_COS_TOLERANCE);
- CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_cos, actual_cos, SIN_COS_TOLERANCE);
- }
-}
diff --git a/gnuradio-runtime/lib/qa_gr_io_signature.cc b/gnuradio-runtime/lib/qa_gr_io_signature.cc
deleted file mode 100644
index c1737ffb8e..0000000000
--- a/gnuradio-runtime/lib/qa_gr_io_signature.cc
+++ /dev/null
@@ -1,64 +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 <qa_gr_io_signature.h>
-#include <gr_io_signature.h>
-
-void
-qa_gr_io_signature::t0 ()
-{
- gr_make_io_signature (1, 1, sizeof (int));
-}
-
-void
-qa_gr_io_signature::t1 ()
-{
- gr_make_io_signature (3, 1, sizeof (int)); // throws std::invalid_argument
-}
-
-void
-qa_gr_io_signature::t2 ()
-{
- gr_io_signature_sptr p =
- gr_make_io_signature (3, gr_io_signature::IO_INFINITE, sizeof (int));
-
- CPPUNIT_ASSERT_EQUAL (p->min_streams (), 3);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item (0), (int) sizeof (int));
-}
-
-void
-qa_gr_io_signature::t3 ()
-{
- gr_io_signature_sptr p =
- gr_make_io_signature3 (0, 5, 1, 2, 3);
-
- CPPUNIT_ASSERT_EQUAL (p->min_streams (), 0);
- CPPUNIT_ASSERT_EQUAL (p->max_streams (), 5);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(0), 1);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(1), 2);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(2), 3);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(3), 3);
- CPPUNIT_ASSERT_EQUAL (p->sizeof_stream_item(4), 3);
-}
diff --git a/gnuradio-runtime/lib/qa_io_signature.cc b/gnuradio-runtime/lib/qa_io_signature.cc
new file mode 100644
index 0000000000..bc3509a260
--- /dev/null
+++ b/gnuradio-runtime/lib/qa_io_signature.cc
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_io_signature.h>
+#include <gnuradio/io_signature.h>
+
+void
+qa_io_signature::t0()
+{
+ gr::io_signature::make(1, 1, sizeof(int));
+}
+
+void
+qa_io_signature::t1()
+{
+ gr::io_signature::make(3, 1, sizeof(int)); // throws std::invalid_argument
+}
+
+void
+qa_io_signature::t2()
+{
+ gr::io_signature::sptr p =
+ gr::io_signature::make(3, gr::io_signature::IO_INFINITE, sizeof(int));
+
+ CPPUNIT_ASSERT_EQUAL(p->min_streams(), 3);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(0), (int)sizeof(int));
+}
+
+void
+qa_io_signature::t3()
+{
+ gr::io_signature::sptr p =
+ gr::io_signature::make3(0, 5, 1, 2, 3);
+
+ CPPUNIT_ASSERT_EQUAL(p->min_streams(), 0);
+ CPPUNIT_ASSERT_EQUAL(p->max_streams(), 5);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(0), 1);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(1), 2);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(2), 3);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(3), 3);
+ CPPUNIT_ASSERT_EQUAL(p->sizeof_stream_item(4), 3);
+}
diff --git a/gnuradio-runtime/lib/qa_gr_io_signature.h b/gnuradio-runtime/lib/qa_io_signature.h
index 9cd6bb5247..981ad03b59 100644
--- a/gnuradio-runtime/lib/qa_gr_io_signature.h
+++ b/gnuradio-runtime/lib/qa_io_signature.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -27,20 +27,20 @@
#include <cppunit/TestCase.h>
#include <stdexcept>
-class qa_gr_io_signature : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_io_signature);
- CPPUNIT_TEST (t0);
- CPPUNIT_TEST_EXCEPTION (t1, std::invalid_argument);
- CPPUNIT_TEST (t2);
- CPPUNIT_TEST (t3);
- CPPUNIT_TEST_SUITE_END ();
+class qa_io_signature : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_io_signature);
+ CPPUNIT_TEST(t0);
+ CPPUNIT_TEST_EXCEPTION(t1, std::invalid_argument);
+ CPPUNIT_TEST(t2);
+ CPPUNIT_TEST(t3);
+ CPPUNIT_TEST_SUITE_END();
private:
- void t0 ();
- void t1 ();
- void t2 ();
- void t3 ();
+ void t0();
+ void t1();
+ void t2();
+ void t3();
};
#endif /* INCLUDED_QA_GR_IO_SIGNATURE_H */
diff --git a/gnuradio-runtime/lib/qa_gr_logger.cc b/gnuradio-runtime/lib/qa_logger.cc
index a8e4a1d766..b147b36da1 100644
--- a/gnuradio-runtime/lib/qa_gr_logger.cc
+++ b/gnuradio-runtime/lib/qa_logger.cc
@@ -29,11 +29,11 @@
#include <config.h>
#endif
-#include <qa_gr_logger.h>
-#include <gr_logger.h>
+#include <qa_logger.h>
+#include <gnuradio/logger.h>
void
-qa_gr_logger::t1()
+qa_logger::t1()
{
#ifdef ENABLE_GR_LOG
// This doesn't really test anything, more just
diff --git a/gnuradio-runtime/lib/qa_gr_logger.h b/gnuradio-runtime/lib/qa_logger.h
index b0d3711523..35f7f1f6c4 100644
--- a/gnuradio-runtime/lib/qa_gr_logger.h
+++ b/gnuradio-runtime/lib/qa_logger.h
@@ -28,15 +28,15 @@
//! collect all the tests for the example directory
-class qa_gr_logger : public CppUnit::TestCase {
- public:
- CPPUNIT_TEST_SUITE(qa_gr_logger);
+class qa_logger : public CppUnit::TestCase
+{
+public:
+ CPPUNIT_TEST_SUITE(qa_logger);
CPPUNIT_TEST(t1);
CPPUNIT_TEST_SUITE_END();
private:
void t1();
-
};
#endif /* INCLUDED_QA_GR_LOG_H */
diff --git a/gnuradio-runtime/lib/qa_runtime.cc b/gnuradio-runtime/lib/qa_runtime.cc
index b15051c2ad..dbf7e5bb9a 100644
--- a/gnuradio-runtime/lib/qa_runtime.cc
+++ b/gnuradio-runtime/lib/qa_runtime.cc
@@ -30,32 +30,32 @@
#endif
#include <qa_runtime.h>
-#include <qa_gr_buffer.h>
-#include <qa_gr_circular_file.h>
-#include <qa_gr_fxpt.h>
-#include <qa_gr_fxpt_nco.h>
-#include <qa_gr_fxpt_vco.h>
-#include <qa_gr_io_signature.h>
-#include <qa_gr_logger.h>
-#include <qa_gr_math.h>
-#include <qa_gr_vmcircbuf.h>
+#include <qa_buffer.h>
+#include <qa_io_signature.h>
+#include <qa_circular_file.h>
+#include <qa_fxpt.h>
+#include <qa_fxpt_nco.h>
+#include <qa_fxpt_vco.h>
+#include <qa_logger.h>
+#include <qa_math.h>
+#include <qa_vmcircbuf.h>
#include <qa_sincos.h>
CppUnit::TestSuite *
-qa_runtime::suite ()
+qa_runtime::suite()
{
- CppUnit::TestSuite *s = new CppUnit::TestSuite ("runtime");
+ CppUnit::TestSuite *s = new CppUnit::TestSuite("runtime");
- s->addTest (qa_gr_buffer::suite ());
- s->addTest (qa_gr_circular_file::suite ());
- s->addTest (qa_gr_fxpt::suite ());
- s->addTest (qa_gr_fxpt_nco::suite ());
- s->addTest (qa_gr_fxpt_vco::suite ());
- s->addTest (qa_gr_io_signature::suite ());
- s->addTest (qa_gr_logger::suite ());
- s->addTest (qa_gr_math::suite ());
- s->addTest (qa_gr_vmcircbuf::suite ());
- s->addTest (qa_sincos::suite ());
+ s->addTest(qa_buffer::suite());
+ s->addTest(qa_io_signature::suite());
+ s->addTest(qa_circular_file::suite());
+ s->addTest(qa_fxpt::suite());
+ s->addTest(qa_fxpt_nco::suite());
+ s->addTest(qa_fxpt_vco::suite());
+ s->addTest(qa_logger::suite());
+ s->addTest(qa_math::suite());
+ s->addTest(qa_vmcircbuf::suite());
+ s->addTest(qa_sincos::suite());
return s;
}
diff --git a/gnuradio-runtime/lib/qa_runtime.h b/gnuradio-runtime/lib/qa_runtime.h
index b03e3db721..a1e58190d6 100644
--- a/gnuradio-runtime/lib/qa_runtime.h
+++ b/gnuradio-runtime/lib/qa_runtime.h
@@ -23,7 +23,7 @@
#ifndef _QA_RUNTIME_H_
#define _QA_RUNTIME_H_
-#include <attributes.h>
+#include <gnuradio/attributes.h>
#include <cppunit/TestSuite.h>
//! collect all the tests for the runtime directory
diff --git a/gnuradio-runtime/lib/qa_gr_vmcircbuf.cc b/gnuradio-runtime/lib/qa_vmcircbuf.cc
index e3b36d8829..7301b4cf17 100644
--- a/gnuradio-runtime/lib/qa_gr_vmcircbuf.cc
+++ b/gnuradio-runtime/lib/qa_vmcircbuf.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2002 Free Software Foundation, Inc.
+ * Copyright 2002,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,17 +24,17 @@
#include <config.h>
#endif
-#include <qa_gr_vmcircbuf.h>
+#include <qa_vmcircbuf.h>
#include <cppunit/TestAssert.h>
-#include <gr_vmcircbuf.h>
+#include "vmcircbuf.h"
#include <stdio.h>
void
-qa_gr_vmcircbuf::test_all ()
+qa_vmcircbuf::test_all()
{
- int verbose = 1; // summary
+ int verbose = 1; // summary
- bool ok = gr_vmcircbuf_sysconfig::test_all_factories (verbose);
+ bool ok = gr::vmcircbuf_sysconfig::test_all_factories(verbose);
- CPPUNIT_ASSERT_EQUAL (true, ok);
+ CPPUNIT_ASSERT_EQUAL(true, ok);
}
diff --git a/gnuradio-runtime/lib/qa_gr_circular_file.h b/gnuradio-runtime/lib/qa_vmcircbuf.h
index df35ab077b..93f46cf4a8 100644
--- a/gnuradio-runtime/lib/qa_gr_circular_file.h
+++ b/gnuradio-runtime/lib/qa_vmcircbuf.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2002 Free Software Foundation, Inc.
+ * Copyright 2004,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,22 +19,21 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
-#ifndef _QA_GR_CIRCULAR_FILE_H_
-#define _QA_GR_CIRCULAR_FILE_H_
+
+#ifndef QA_GR_VMCIRCBUF_H
+#define QA_GR_VMCIRCBUF_H
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
-class qa_gr_circular_file : public CppUnit::TestCase {
-
- CPPUNIT_TEST_SUITE (qa_gr_circular_file);
- CPPUNIT_TEST (t1);
- CPPUNIT_TEST_SUITE_END ();
-
- private:
- void t1 ();
+class qa_vmcircbuf : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_vmcircbuf);
+ CPPUNIT_TEST(test_all);
+ CPPUNIT_TEST_SUITE_END();
+private:
+ void test_all();
};
-
-#endif /* _QA_GR_CIRCULAR_FILE_H_ */
+#endif /* QA_GR_VMCIRCBUF_H */
diff --git a/gnuradio-runtime/lib/random.h b/gnuradio-runtime/lib/random.h
deleted file mode 100644
index c643c3e422..0000000000
--- a/gnuradio-runtime/lib/random.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2003, 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 _RANDOM_H_
-#define _RANDOM_H_
-
-// While rand(3) specifies RAND_MAX, random(3) says that the output
-// ranges from 0 to 2^31-1 but does not specify a macro to denote
-// this. We define RANDOM_MAX for cleanliness. We must omit the
-// definition for systems that have made the same choice. (Note that
-// random(3) is from 4.2BSD, and not specified by POSIX.)
-
-#ifndef RANDOM_MAX
-static const int RANDOM_MAX = 2147483647; // 2^31-1
-#endif /* RANDOM_MAX */
-
-#include <stdlib.h>
-
-#endif // _RANDOM_H_
diff --git a/gnuradio-runtime/lib/realtime.cc b/gnuradio-runtime/lib/realtime.cc
index 5dadc26bbd..81f92ae488 100644
--- a/gnuradio-runtime/lib/realtime.cc
+++ b/gnuradio-runtime/lib/realtime.cc
@@ -24,155 +24,14 @@
#include <config.h>
#endif
-#include <realtime.h>
-
-#ifdef HAVE_SCHED_H
-#include <sched.h>
-#endif
-
-#include <algorithm>
-#include <math.h>
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-
-#if defined(HAVE_PTHREAD_SETSCHEDPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
-#include <pthread.h>
-
-namespace gr {
-
- /*!
- * Rescale our virtual priority so that it maps to the middle 1/2 of
- * the priorities given by min_real_pri and max_real_pri.
- */
- static int
- rescale_virtual_pri(int virtual_pri, int min_real_pri, int max_real_pri)
- {
- float rmin = min_real_pri + (0.25 * (max_real_pri - min_real_pri));
- float rmax = min_real_pri + (0.75 * (max_real_pri - min_real_pri));
- float m = (rmax - rmin) / (rt_priority_max() - rt_priority_min());
- float y = m * (virtual_pri - rt_priority_min()) + rmin;
- int y_int = static_cast<int>(rint(y));
- return std::max(min_real_pri, std::min(max_real_pri, y_int));
- }
-
-} // namespace gr
-
-#endif
-
-
-#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
-
-namespace gr {
-
- rt_status_t
- enable_realtime_scheduling(rt_sched_param p)
- {
- int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR;
- int min_real_pri = sched_get_priority_min(policy);
- int max_real_pri = sched_get_priority_max(policy);
- int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri);
-
- // FIXME check hard and soft limits with getrlimit, and limit the value we ask for.
- // fprintf(stderr, "pthread_setschedparam: policy = %d, pri = %d\n", policy, pri);
-
- struct sched_param param;
- memset (&param, 0, sizeof (param));
- param.sched_priority = pri;
- int result = pthread_setschedparam (pthread_self(), policy, &param);
- if (result != 0) {
- if (result == EPERM) // N.B., return value, not errno
- return RT_NO_PRIVS;
- else {
- fprintf(stderr,
- "pthread_setschedparam: failed to set real time priority: %s\n",
- strerror(result));
- return RT_OTHER_ERROR;
- }
- }
-
- //printf("SCHED_FIFO enabled with priority = %d\n", pri);
- return RT_OK;
- }
-} // namespace gr
-
-
-#elif defined(HAVE_SCHED_SETSCHEDULER)
-
-namespace gr {
-
- rt_status_t
- enable_realtime_scheduling(rt_sched_param p)
- {
- int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR;
- int min_real_pri = sched_get_priority_min(policy);
- int max_real_pri = sched_get_priority_max(policy);
- int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri);
-
- // FIXME check hard and soft limits with getrlimit, and limit the value we ask for.
- // fprintf(stderr, "sched_setscheduler: policy = %d, pri = %d\n", policy, pri);
-
- int pid = 0; // this process
- struct sched_param param;
- memset(&param, 0, sizeof(param));
- param.sched_priority = pri;
- int result = sched_setscheduler(pid, policy, &param);
- if (result != 0){
- if (errno == EPERM)
- return RT_NO_PRIVS;
- else {
- perror ("sched_setscheduler: failed to set real time priority");
- return RT_OTHER_ERROR;
- }
- }
-
- //printf("SCHED_FIFO enabled with priority = %d\n", pri);
- return RT_OK;
- }
-
-} // namespace gr
-
-#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-
-#include <windows.h>
-
-namespace gr {
-
- rt_status_t enable_realtime_scheduling(rt_sched_param p){
-
- //set the priority class on the process
- int pri_class = (true)? REALTIME_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
- if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0)
- return RT_OTHER_ERROR;
-
- //scale the priority value to the constants
- int priorities[] = {
- THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL,
- THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL
- };
- const double priority = double(p.priority)/(rt_priority_max() - rt_priority_min());
- size_t pri_index = size_t((priority+1.0)*6/2.0); // -1 -> 0, +1 -> 6
- pri_index %= sizeof(priorities)/sizeof(*priorities); //range check
-
- //set the thread priority on the thread
- if (SetThreadPriority(GetCurrentThread(), priorities[pri_index]) == 0)
- return RT_OTHER_ERROR;
-
- //printf("SetPriorityClass + SetThreadPriority\n");
- return RT_OK;
- }
-
-} // namespace gr
-
-#else
+#include <gnuradio/realtime.h>
namespace gr {
-
+
rt_status_t
- enable_realtime_scheduling(rt_sched_param p)
+ enable_realtime_scheduling()
{
- return RT_NOT_IMPLEMENTED;
+ return enable_realtime_scheduling();
}
-} // namespace gr
-#endif
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/realtime_impl.cc b/gnuradio-runtime/lib/realtime_impl.cc
new file mode 100644
index 0000000000..5dadc26bbd
--- /dev/null
+++ b/gnuradio-runtime/lib/realtime_impl.cc
@@ -0,0 +1,178 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <realtime.h>
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#include <algorithm>
+#include <math.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
+#include <pthread.h>
+
+namespace gr {
+
+ /*!
+ * Rescale our virtual priority so that it maps to the middle 1/2 of
+ * the priorities given by min_real_pri and max_real_pri.
+ */
+ static int
+ rescale_virtual_pri(int virtual_pri, int min_real_pri, int max_real_pri)
+ {
+ float rmin = min_real_pri + (0.25 * (max_real_pri - min_real_pri));
+ float rmax = min_real_pri + (0.75 * (max_real_pri - min_real_pri));
+ float m = (rmax - rmin) / (rt_priority_max() - rt_priority_min());
+ float y = m * (virtual_pri - rt_priority_min()) + rmin;
+ int y_int = static_cast<int>(rint(y));
+ return std::max(min_real_pri, std::min(max_real_pri, y_int));
+ }
+
+} // namespace gr
+
+#endif
+
+
+#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
+
+namespace gr {
+
+ rt_status_t
+ enable_realtime_scheduling(rt_sched_param p)
+ {
+ int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR;
+ int min_real_pri = sched_get_priority_min(policy);
+ int max_real_pri = sched_get_priority_max(policy);
+ int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri);
+
+ // FIXME check hard and soft limits with getrlimit, and limit the value we ask for.
+ // fprintf(stderr, "pthread_setschedparam: policy = %d, pri = %d\n", policy, pri);
+
+ struct sched_param param;
+ memset (&param, 0, sizeof (param));
+ param.sched_priority = pri;
+ int result = pthread_setschedparam (pthread_self(), policy, &param);
+ if (result != 0) {
+ if (result == EPERM) // N.B., return value, not errno
+ return RT_NO_PRIVS;
+ else {
+ fprintf(stderr,
+ "pthread_setschedparam: failed to set real time priority: %s\n",
+ strerror(result));
+ return RT_OTHER_ERROR;
+ }
+ }
+
+ //printf("SCHED_FIFO enabled with priority = %d\n", pri);
+ return RT_OK;
+ }
+} // namespace gr
+
+
+#elif defined(HAVE_SCHED_SETSCHEDULER)
+
+namespace gr {
+
+ rt_status_t
+ enable_realtime_scheduling(rt_sched_param p)
+ {
+ int policy = p.policy == RT_SCHED_FIFO ? SCHED_FIFO : SCHED_RR;
+ int min_real_pri = sched_get_priority_min(policy);
+ int max_real_pri = sched_get_priority_max(policy);
+ int pri = rescale_virtual_pri(p.priority, min_real_pri, max_real_pri);
+
+ // FIXME check hard and soft limits with getrlimit, and limit the value we ask for.
+ // fprintf(stderr, "sched_setscheduler: policy = %d, pri = %d\n", policy, pri);
+
+ int pid = 0; // this process
+ struct sched_param param;
+ memset(&param, 0, sizeof(param));
+ param.sched_priority = pri;
+ int result = sched_setscheduler(pid, policy, &param);
+ if (result != 0){
+ if (errno == EPERM)
+ return RT_NO_PRIVS;
+ else {
+ perror ("sched_setscheduler: failed to set real time priority");
+ return RT_OTHER_ERROR;
+ }
+ }
+
+ //printf("SCHED_FIFO enabled with priority = %d\n", pri);
+ return RT_OK;
+ }
+
+} // namespace gr
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+
+#include <windows.h>
+
+namespace gr {
+
+ rt_status_t enable_realtime_scheduling(rt_sched_param p){
+
+ //set the priority class on the process
+ int pri_class = (true)? REALTIME_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS;
+ if (SetPriorityClass(GetCurrentProcess(), pri_class) == 0)
+ return RT_OTHER_ERROR;
+
+ //scale the priority value to the constants
+ int priorities[] = {
+ THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL, THREAD_PRIORITY_NORMAL,
+ THREAD_PRIORITY_ABOVE_NORMAL, THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL
+ };
+ const double priority = double(p.priority)/(rt_priority_max() - rt_priority_min());
+ size_t pri_index = size_t((priority+1.0)*6/2.0); // -1 -> 0, +1 -> 6
+ pri_index %= sizeof(priorities)/sizeof(*priorities); //range check
+
+ //set the thread priority on the thread
+ if (SetThreadPriority(GetCurrentThread(), priorities[pri_index]) == 0)
+ return RT_OTHER_ERROR;
+
+ //printf("SetPriorityClass + SetThreadPriority\n");
+ return RT_OK;
+ }
+
+} // namespace gr
+
+#else
+
+namespace gr {
+
+ rt_status_t
+ enable_realtime_scheduling(rt_sched_param p)
+ {
+ return RT_NOT_IMPLEMENTED;
+ }
+} // namespace gr
+
+#endif
diff --git a/gnuradio-runtime/lib/runtime_block_gateway.cc b/gnuradio-runtime/lib/runtime_block_gateway.cc
deleted file mode 100644
index 11d16af41e..0000000000
--- a/gnuradio-runtime/lib/runtime_block_gateway.cc
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright 2011-2012 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 <runtime_block_gateway.h>
-#include <gr_io_signature.h>
-#include <iostream>
-#include <boost/bind.hpp>
-
-/***********************************************************************
- * Helper routines
- **********************************************************************/
-template <typename OutType, typename InType>
-void copy_pointers(OutType &out, const InType &in){
- out.resize(in.size());
- for (size_t i = 0; i < in.size(); i++){
- out[i] = (void *)(in[i]);
- }
-}
-
-/***********************************************************************
- * The gr_block gateway implementation class
- **********************************************************************/
-class runtime_block_gateway_impl : public runtime_block_gateway{
-public:
- runtime_block_gateway_impl(
- gr_feval_ll *handler,
- const std::string &name,
- gr_io_signature_sptr in_sig,
- gr_io_signature_sptr out_sig,
- const gr_block_gw_work_type work_type,
- const unsigned factor
- ):
- gr_block(name, in_sig, out_sig),
- _handler(handler),
- _work_type(work_type)
- {
- switch(_work_type){
- case GR_BLOCK_GW_WORK_GENERAL:
- _decim = 1; //not relevant, but set anyway
- _interp = 1; //not relevant, but set anyway
- break;
-
- case GR_BLOCK_GW_WORK_SYNC:
- _decim = 1;
- _interp = 1;
- this->set_fixed_rate(true);
- break;
-
- case GR_BLOCK_GW_WORK_DECIM:
- _decim = factor;
- _interp = 1;
- break;
-
- case GR_BLOCK_GW_WORK_INTERP:
- _decim = 1;
- _interp = factor;
- this->set_output_multiple(_interp);
- break;
- }
- }
-
- /*******************************************************************
- * Overloads for various scheduler-called functions
- ******************************************************************/
- void forecast(
- int noutput_items,
- gr_vector_int &ninput_items_required
- ){
- switch(_work_type){
- case GR_BLOCK_GW_WORK_GENERAL:
- _message.action = gr_block_gw_message_type::ACTION_FORECAST;
- _message.forecast_args_noutput_items = noutput_items;
- _message.forecast_args_ninput_items_required = ninput_items_required;
- _handler->calleval(0);
- ninput_items_required = _message.forecast_args_ninput_items_required;
- return;
-
- default:
- unsigned ninputs = ninput_items_required.size();
- for (unsigned i = 0; i < ninputs; i++)
- ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
- return;
- }
- }
-
- int general_work(
- int noutput_items,
- gr_vector_int &ninput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items
- ){
- switch(_work_type){
- case GR_BLOCK_GW_WORK_GENERAL:
- _message.action = gr_block_gw_message_type::ACTION_GENERAL_WORK;
- _message.general_work_args_noutput_items = noutput_items;
- _message.general_work_args_ninput_items = ninput_items;
- copy_pointers(_message.general_work_args_input_items, input_items);
- _message.general_work_args_output_items = output_items;
- _handler->calleval(0);
- return _message.general_work_args_return_value;
-
- default:
- int r = work (noutput_items, input_items, output_items);
- if (r > 0) consume_each(r*_decim/_interp);
- return r;
- }
- }
-
- int work(
- int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items
- ){
- _message.action = gr_block_gw_message_type::ACTION_WORK;
- _message.work_args_ninput_items = fixed_rate_noutput_to_ninput(noutput_items);
- if (_message.work_args_ninput_items == 0) return -1;
- _message.work_args_noutput_items = noutput_items;
- copy_pointers(_message.work_args_input_items, input_items);
- _message.work_args_output_items = output_items;
- _handler->calleval(0);
- return _message.work_args_return_value;
- }
-
- int fixed_rate_noutput_to_ninput(int noutput_items){
- return (noutput_items*_decim/_interp) + history() - 1;
- }
-
- int fixed_rate_ninput_to_noutput(int ninput_items){
- return std::max(0, ninput_items - (int)history() + 1)*_interp/_decim;
- }
-
- bool start(void){
- _message.action = gr_block_gw_message_type::ACTION_START;
- _handler->calleval(0);
- return _message.start_args_return_value;
- }
-
- bool stop(void){
- _message.action = gr_block_gw_message_type::ACTION_STOP;
- _handler->calleval(0);
- return _message.stop_args_return_value;
- }
-
- gr_block_gw_message_type &gr_block_message(void){
- return _message;
- }
-
-private:
- gr_feval_ll *_handler;
- gr_block_gw_message_type _message;
- const gr_block_gw_work_type _work_type;
- unsigned _decim, _interp;
-};
-
-boost::shared_ptr<runtime_block_gateway> runtime_make_block_gateway(
- gr_feval_ll *handler,
- const std::string &name,
- gr_io_signature_sptr in_sig,
- gr_io_signature_sptr out_sig,
- const gr_block_gw_work_type work_type,
- const unsigned factor
-){
- return boost::shared_ptr<runtime_block_gateway>(
- new runtime_block_gateway_impl(handler, name, in_sig, out_sig,
- work_type, factor)
- );
-}
diff --git a/gnuradio-runtime/lib/gr_scheduler.cc b/gnuradio-runtime/lib/scheduler.cc
index c691f5d99f..38d95e6fb2 100644
--- a/gnuradio-runtime/lib/gr_scheduler.cc
+++ b/gnuradio-runtime/lib/scheduler.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -22,12 +22,18 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <gr_scheduler.h>
-gr_scheduler::gr_scheduler(gr_flat_flowgraph_sptr ffg, int max_noutput_items)
-{
-}
+#include "scheduler.h"
-gr_scheduler::~gr_scheduler()
-{
-}
+namespace gr {
+
+ scheduler::scheduler(flat_flowgraph_sptr ffg,
+ int max_noutput_items)
+ {
+ }
+
+ scheduler::~scheduler()
+ {
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/scheduler.h b/gnuradio-runtime/lib/scheduler.h
new file mode 100644
index 0000000000..575862b27d
--- /dev/null
+++ b/gnuradio-runtime/lib/scheduler.h
@@ -0,0 +1,68 @@
+/* -*- 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_H
+#define INCLUDED_GR_SCHEDULER_H
+
+#include <gnuradio/api.h>
+#include <boost/utility.hpp>
+#include <gnuradio/block.h>
+#include "flat_flowgraph.h"
+
+namespace gr {
+
+ class scheduler;
+ typedef boost::shared_ptr<scheduler> scheduler_sptr;
+
+ /*!
+ * \brief Abstract scheduler that takes a flattened flow graph and
+ * runs it.
+ *
+ * Preconditions: details, buffers and buffer readers have been
+ * assigned.
+ */
+ class GR_RUNTIME_API scheduler : boost::noncopyable
+ {
+ public:
+ /*!
+ * \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(flat_flowgraph_sptr ffg, int max_noutput_items);
+
+ virtual ~scheduler();
+
+ /*!
+ * \brief Tell the scheduler to stop executing.
+ */
+ virtual void stop() = 0;
+
+ /*!
+ * \brief Block until the graph is done.
+ */
+ virtual void wait() = 0;
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_SCHEDULER_H */
diff --git a/gnuradio-runtime/lib/scheduler_sts.cc b/gnuradio-runtime/lib/scheduler_sts.cc
new file mode 100644
index 0000000000..cc60b55f02
--- /dev/null
+++ b/gnuradio-runtime/lib/scheduler_sts.cc
@@ -0,0 +1,90 @@
+/* -*- 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 <gnuradio/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
new file mode 100644
index 0000000000..b4cddb4614
--- /dev/null
+++ b/gnuradio-runtime/lib/scheduler_sts.h
@@ -0,0 +1,66 @@
+/* -*- 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/scheduler_tpb.cc b/gnuradio-runtime/lib/scheduler_tpb.cc
new file mode 100644
index 0000000000..d35c37fb34
--- /dev/null
+++ b/gnuradio-runtime/lib/scheduler_tpb.cc
@@ -0,0 +1,106 @@
+/* -*- 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_tpb.h"
+#include "tpb_thread_body.h"
+#include <gnuradio/thread/thread_body_wrapper.h>
+#include <sstream>
+
+namespace gr {
+
+ class tpb_container
+ {
+ block_sptr d_block;
+ int d_max_noutput_items;
+
+ public:
+ tpb_container(block_sptr block, int max_noutput_items)
+ : d_block(block), d_max_noutput_items(max_noutput_items) {}
+
+ void operator()()
+ {
+ tpb_thread_body body(d_block, d_max_noutput_items);
+ }
+ };
+
+ scheduler_sptr
+ scheduler_tpb::make(flat_flowgraph_sptr ffg, int max_noutput_items)
+ {
+ return scheduler_sptr(new scheduler_tpb(ffg, max_noutput_items));
+ }
+
+ scheduler_tpb::scheduler_tpb(flat_flowgraph_sptr ffg,
+ int max_noutput_items)
+ : scheduler(ffg, max_noutput_items)
+ {
+ // Get a topologically sorted vector of all the blocks in use.
+ // Being topologically sorted probably isn't going to matter, but
+ // there's a non-zero chance it might help...
+
+ basic_block_vector_t used_blocks = ffg->calc_used_blocks();
+ used_blocks = ffg->topological_sort(used_blocks);
+ block_vector_t blocks = flat_flowgraph::make_block_vector(used_blocks);
+
+ // Ensure that the done flag is clear on all blocks
+
+ for(size_t i = 0; i < blocks.size(); i++) {
+ blocks[i]->detail()->set_done(false);
+ }
+
+ // Fire off a thead for each block
+
+ for(size_t i = 0; i < blocks.size(); i++) {
+ std::stringstream name;
+ name << "thread-per-block[" << i << "]: " << blocks[i];
+
+ // If set, use internal value instead of global value
+ if(blocks[i]->is_set_max_noutput_items())
+ max_noutput_items = blocks[i]->max_noutput_items();
+
+ d_threads.create_thread(
+ gr::thread::thread_body_wrapper<tpb_container>
+ (tpb_container(blocks[i], max_noutput_items),
+ name.str()));
+ }
+ }
+
+ scheduler_tpb::~scheduler_tpb()
+ {
+ stop();
+ }
+
+ void
+ scheduler_tpb::stop()
+ {
+ d_threads.interrupt_all();
+ }
+
+ void
+ scheduler_tpb::wait()
+ {
+ d_threads.join_all();
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/scheduler_tpb.h b/gnuradio-runtime/lib/scheduler_tpb.h
new file mode 100644
index 0000000000..f5ab21f269
--- /dev/null
+++ b/gnuradio-runtime/lib/scheduler_tpb.h
@@ -0,0 +1,66 @@
+/* -*- 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_TPB_H
+#define INCLUDED_GR_SCHEDULER_TPB_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/thread/thread_group.h>
+#include "scheduler.h"
+
+namespace gr {
+
+ /*!
+ * \brief Concrete scheduler that uses a kernel thread-per-block
+ */
+ class GR_RUNTIME_API scheduler_tpb : 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_tpb(flat_flowgraph_sptr ffg, int max_noutput_items);
+
+ public:
+ static scheduler_sptr make(flat_flowgraph_sptr ffg,
+ int max_noutput_items=100000);
+
+ ~scheduler_tpb();
+
+ /*!
+ * \brief Tell the scheduler to stop executing.
+ */
+ void stop();
+
+ /*!
+ * \brief Block until the graph is done.
+ */
+ void wait();
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_SCHEDULER_TPB_H */
diff --git a/gnuradio-runtime/lib/gr_select_handler.cc b/gnuradio-runtime/lib/select_handler.cc
index 0fc86354a6..ca99ce6ce8 100644
--- a/gnuradio-runtime/lib/gr_select_handler.cc
+++ b/gnuradio-runtime/lib/select_handler.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2005 Free Software Foundation, Inc.
+ * Copyright 2005,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -24,13 +24,17 @@
#include "config.h"
#endif
-#include <gr_select_handler.h>
+#include <gnuradio/select_handler.h>
-gr_select_handler::gr_select_handler(int fd)
- : d_fd(fd)
-{
-}
+namespace gr {
-gr_select_handler::~gr_select_handler()
-{
-}
+ select_handler::select_handler(int fd)
+ : d_fd(fd)
+ {
+ }
+
+ select_handler::~select_handler()
+ {
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/single_threaded_scheduler.cc b/gnuradio-runtime/lib/single_threaded_scheduler.cc
new file mode 100644
index 0000000000..0d7f91670b
--- /dev/null
+++ b/gnuradio-runtime/lib/single_threaded_scheduler.cc
@@ -0,0 +1,363 @@
+/* -*- 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 <gnuradio/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++) {
+ int n = round_down (d->output(i)->space_available (), output_multiple);
+ if(n == 0) { // We're blocked on output.
+ if(d->output(i)->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++) {
+ ninput_items[i] = d->input(i)->items_available();
+ //if (ninput_items[i] == 0 && d->input(i)->done())
+ if(ninput_items[i] < m->output_multiple() && d->input(i)->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
+ LOG(*d_log << " BLKD_IN\n");
+ if(d->input(i)->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] > d->input(i)->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 = "
+ << d->input(i)->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/gr_sptr_magic.cc b/gnuradio-runtime/lib/sptr_magic.cc
index 2073701422..70596abb05 100644
--- a/gnuradio-runtime/lib/gr_sptr_magic.cc
+++ b/gnuradio-runtime/lib/sptr_magic.cc
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008,2009 Free Software Foundation, Inc.
+ * Copyright 2008,2009,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -18,54 +18,54 @@
* 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 <gr_sptr_magic.h>
-#include <gr_hier_block2.h>
+
+#include <gnuradio/sptr_magic.h>
+#include <gnuradio/hier_block2.h>
#include <map>
#include <stdexcept>
-
-#include <thread/thread.h>
+#include <gnuradio/thread/thread.h>
namespace gnuradio {
- static gr::thread::mutex s_mutex;
- typedef std::map<gr_basic_block*, gr_basic_block_sptr> sptr_map;
- static sptr_map s_map;
+ static gr::thread::mutex s_mutex;
+ typedef std::map<gr::basic_block*, gr::basic_block_sptr> sptr_map;
+ static sptr_map s_map;
void
- detail::sptr_magic::create_and_stash_initial_sptr(gr_hier_block2 *p)
+ detail::sptr_magic::create_and_stash_initial_sptr(gr::hier_block2 *p)
{
- gr_basic_block_sptr sptr(p);
+ gr::basic_block_sptr sptr(p);
gr::thread::scoped_lock guard(s_mutex);
- s_map.insert(sptr_map::value_type(static_cast<gr_basic_block *>(p), sptr));
+ s_map.insert(sptr_map::value_type(static_cast<gr::basic_block *>(p), sptr));
}
-
- gr_basic_block_sptr
- detail::sptr_magic::fetch_initial_sptr(gr_basic_block *p)
+ gr::basic_block_sptr
+ detail::sptr_magic::fetch_initial_sptr(gr::basic_block *p)
{
/*
- * If p isn't a subclass of gr_hier_block2, just create the
+ * If p isn't a subclass of gr::hier_block2, just create the
* shared ptr and return it.
*/
- gr_hier_block2 *hb2 = dynamic_cast<gr_hier_block2 *>(p);
- if (!hb2){
- return gr_basic_block_sptr(p);
+ gr::hier_block2 *hb2 = dynamic_cast<gr::hier_block2 *>(p);
+ if(!hb2) {
+ return gr::basic_block_sptr(p);
}
/*
- * p is a subclass of gr_hier_block2, thus we've already created the shared pointer
+ * p is a subclass of gr::hier_block2, thus we've already created the shared pointer
* and stashed it away. Fish it out and return it.
*/
gr::thread::scoped_lock guard(s_mutex);
- sptr_map::iterator pos = s_map.find(static_cast<gr_basic_block *>(p));
- if (pos == s_map.end())
- throw std::invalid_argument("gr_sptr_magic: invalid pointer!");
+ sptr_map::iterator pos = s_map.find(static_cast<gr::basic_block *>(p));
+ if(pos == s_map.end())
+ throw std::invalid_argument("sptr_magic: invalid pointer!");
- gr_basic_block_sptr sptr = pos->second;
+ gr::basic_block_sptr sptr = pos->second;
s_map.erase(pos);
return sptr;
}
diff --git a/gnuradio-runtime/lib/sync_block.cc b/gnuradio-runtime/lib/sync_block.cc
new file mode 100644
index 0000000000..e00b80c79e
--- /dev/null
+++ b/gnuradio-runtime/lib/sync_block.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/sync_block.h>
+
+namespace gr {
+
+ sync_block::sync_block(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature)
+ : block(name, input_signature, output_signature)
+ {
+ set_fixed_rate(true);
+ }
+
+ void
+ sync_block::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ }
+
+ int
+ sync_block::fixed_rate_noutput_to_ninput(int noutput_items)
+ {
+ return noutput_items + history() - 1;
+ }
+
+ int
+ sync_block::fixed_rate_ninput_to_noutput(int ninput_items)
+ {
+ return std::max(0, ninput_items - (int)history() + 1);
+ }
+
+ int
+ sync_block::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ int r = work(noutput_items, input_items, output_items);
+ if(r > 0)
+ consume_each(r);
+ return r;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/sync_decimator.cc b/gnuradio-runtime/lib/sync_decimator.cc
new file mode 100644
index 0000000000..a9c2d1eeff
--- /dev/null
+++ b/gnuradio-runtime/lib/sync_decimator.cc
@@ -0,0 +1,72 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gnuradio/sync_decimator.h>
+
+namespace gr {
+
+ sync_decimator::sync_decimator(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature,
+ unsigned decimation)
+ : sync_block(name, input_signature, output_signature)
+ {
+ set_decimation(decimation);
+ }
+
+ void
+ sync_decimator::forecast(int noutput_items, gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ }
+
+ int
+ sync_decimator::fixed_rate_noutput_to_ninput(int noutput_items)
+ {
+ return noutput_items * decimation() + history() - 1;
+ }
+
+ int
+ sync_decimator::fixed_rate_ninput_to_noutput(int ninput_items)
+ {
+ return std::max(0, ninput_items - (int)history() + 1) / decimation();
+ }
+
+ int
+ sync_decimator::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ int r = work(noutput_items, input_items, output_items);
+ if(r > 0)
+ consume_each(r * decimation ());
+ return r;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/sync_interpolator.cc b/gnuradio-runtime/lib/sync_interpolator.cc
new file mode 100644
index 0000000000..5721f24f0f
--- /dev/null
+++ b/gnuradio-runtime/lib/sync_interpolator.cc
@@ -0,0 +1,73 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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 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 <gnuradio/sync_interpolator.h>
+
+namespace gr {
+
+ sync_interpolator::sync_interpolator(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature,
+ unsigned interpolation)
+ : sync_block(name, input_signature, output_signature)
+ {
+ set_interpolation(interpolation);
+ }
+
+ void
+ sync_interpolator::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = fixed_rate_noutput_to_ninput(noutput_items);
+ }
+
+ int
+ sync_interpolator::fixed_rate_noutput_to_ninput(int noutput_items)
+ {
+ return noutput_items / interpolation() + history() - 1;
+ }
+
+ int
+ sync_interpolator::fixed_rate_ninput_to_noutput(int ninput_items)
+ {
+ return std::max(0, ninput_items - (int)history() + 1) * interpolation();
+ }
+
+ int
+ sync_interpolator::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ int r = work(noutput_items, input_items, output_items);
+ if(r > 0)
+ consume_each(r / interpolation());
+ return r;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_sys_paths.cc b/gnuradio-runtime/lib/sys_paths.cc
index b4918af33d..64853c68b2 100644
--- a/gnuradio-runtime/lib/gr_sys_paths.cc
+++ b/gnuradio-runtime/lib/sys_paths.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Free Software Foundation, Inc.
+ * Copyright 2011,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,37 +19,47 @@
* Boston, MA 02110-1301, USA.
*/
-#include <gr_sys_paths.h>
+#include <gnuradio/sys_paths.h>
#include <cstdlib> //getenv
#include <cstdio> //P_tmpdir (maybe)
-const char *gr_tmp_path(){
+namespace gr {
+
+ const char *tmp_path()
+ {
const char *path;
//first case, try TMP environment variable
path = getenv("TMP");
- if (path) return path;
+ if(path)
+ return path;
//second case, try P_tmpdir when its defined
#ifdef P_tmpdir
- if (P_tmpdir) return P_tmpdir;
+ if(P_tmpdir)
+ return P_tmpdir;
#endif /*P_tmpdir*/
//fall-through case, nothing worked
return "/tmp";
-}
+ }
-const char *gr_appdata_path(){
+ const char *appdata_path()
+ {
const char *path;
//first case, try HOME environment variable (unix)
path = getenv("HOME");
- if (path) return path;
+ if(path)
+ return path;
//second case, try APPDATA environment variable (windows)
path = getenv("APPDATA");
- if (path) return path;
+ if(path)
+ return path;
//fall-through case, nothing worked
- return gr_tmp_path();
-}
+ return tmp_path();
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/tagged_stream_block.cc b/gnuradio-runtime/lib/tagged_stream_block.cc
new file mode 100644
index 0000000000..40febfdeca
--- /dev/null
+++ b/gnuradio-runtime/lib/tagged_stream_block.cc
@@ -0,0 +1,144 @@
+/* -*- 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <boost/format.hpp>
+#include <gnuradio/tagged_stream_block.h>
+
+namespace gr {
+
+ tagged_stream_block::tagged_stream_block(const std::string &name,
+ io_signature::sptr input_signature,
+ io_signature::sptr output_signature,
+ const std::string &length_tag_key)
+ : block(name, input_signature, output_signature),
+ d_length_tag_key(pmt::string_to_symbol(length_tag_key)),
+ d_n_input_items_reqd(input_signature->min_streams(), 0),
+ d_length_tag_key_str(length_tag_key)
+ {
+ }
+
+ // This is evil hackery: We trick the scheduler into creating the right number of input items
+ void
+ tagged_stream_block::forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++) {
+ if (i < d_n_input_items_reqd.size() && d_n_input_items_reqd[i] != 0) {
+ ninput_items_required[i] = d_n_input_items_reqd[i];
+ }
+ else {
+ // If there's no item, there's no tag--so there must at least be one!
+ ninput_items_required[i] = std::max(1, (int)std::floor((double) noutput_items / relative_rate() + 0.5));
+ }
+ }
+ }
+
+ void
+ tagged_stream_block::parse_length_tags(const std::vector<std::vector<tag_t> > &tags,
+ gr_vector_int &n_input_items_reqd)
+ {
+ for(unsigned i = 0; i < tags.size(); i++) {
+ for(unsigned k = 0; k < tags[i].size(); k++) {
+ if(tags[i][k].key == d_length_tag_key) {
+ n_input_items_reqd[i] = pmt::to_long(tags[i][k].value);
+ remove_item_tag(i, tags[i][k]);
+ }
+ }
+ }
+ }
+
+ int
+ tagged_stream_block::calculate_output_stream_length(const gr_vector_int &ninput_items)
+ {
+ int noutput_items = *std::max_element(ninput_items.begin(), ninput_items.end());
+ return (int)std::floor(relative_rate() * noutput_items + 0.5);
+ }
+
+ void
+ tagged_stream_block::update_length_tags(int n_produced, int n_ports)
+ {
+ for(int i = 0; i < n_ports; i++) {
+ add_item_tag(i, nitems_written(i),
+ d_length_tag_key,
+ pmt::from_long(n_produced));
+ }
+ return;
+ }
+
+ int
+ tagged_stream_block::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ if(d_length_tag_key_str.empty()) {
+ return work(noutput_items, ninput_items, input_items, output_items);
+ }
+
+ if(d_n_input_items_reqd[0] == 0) { // Otherwise, it's already set from a previous call
+ std::vector<std::vector<tag_t> > tags(input_items.size(), std::vector<tag_t>());
+ for(unsigned i = 0; i < input_items.size(); i++) {
+ get_tags_in_range(tags[i], i, nitems_read(i), nitems_read(i)+1);
+ }
+ d_n_input_items_reqd.assign(input_items.size(), -1);
+ parse_length_tags(tags, d_n_input_items_reqd);
+ }
+ for(unsigned i = 0; i < input_items.size(); i++) {
+ if(d_n_input_items_reqd[i] == -1) {
+ GR_LOG_FATAL(d_logger, boost::format("Missing a required length tag on port %1% at item #%2%") % i % nitems_read(i));
+ throw std::runtime_error("Missing length tag.");
+ }
+ if(d_n_input_items_reqd[i] > ninput_items[i]) {
+ return 0;
+ }
+ }
+
+ int min_output_size = calculate_output_stream_length(d_n_input_items_reqd);
+ if(noutput_items < min_output_size) {
+ set_min_noutput_items(min_output_size);
+ return 0;
+ }
+ set_min_noutput_items(1);
+
+ // WORK CALLED HERE //
+ int n_produced = work(noutput_items, d_n_input_items_reqd, input_items, output_items);
+ //////////////////////
+
+ if(n_produced == WORK_DONE) {
+ return n_produced;
+ }
+ for(int i = 0; i < (int) d_n_input_items_reqd.size(); i++) {
+ consume(i, d_n_input_items_reqd[i]);
+ }
+ update_length_tags(n_produced, output_items.size());
+
+ d_n_input_items_reqd.assign(input_items.size(), 0);
+
+ return n_produced;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/test.cc b/gnuradio-runtime/lib/test.cc
new file mode 100644
index 0000000000..775dc2bde4
--- /dev/null
+++ b/gnuradio-runtime/lib/test.cc
@@ -0,0 +1,181 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2008,2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "test.h"
+#include <gnuradio/io_signature.h>
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+
+namespace gr {
+
+ test_sptr
+ make_test(const std::string &name,
+ int min_inputs, int max_inputs, unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history, unsigned int output_multiple, double relative_rate,
+ bool fixed_rate, consume_type_t cons_type, produce_type_t prod_type)
+ {
+ return gnuradio::get_initial_sptr
+ (new test(name, min_inputs, max_inputs, sizeof_input_item,
+ min_outputs, max_outputs, sizeof_output_item,
+ history, output_multiple, relative_rate,
+ fixed_rate,cons_type, prod_type));
+ }
+
+ test::test(const std::string &name,
+ int min_inputs, int max_inputs,
+ unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs,
+ unsigned int sizeof_output_item,
+ unsigned int history,
+ unsigned int output_multiple,
+ double relative_rate,
+ bool fixed_rate,
+ consume_type_t cons_type, produce_type_t prod_type)
+ : block (name,
+ io_signature::make(min_inputs, max_inputs, sizeof_input_item),
+ io_signature::make(min_outputs, max_outputs, sizeof_output_item)),
+ d_sizeof_input_item(sizeof_input_item),
+ d_sizeof_output_item(sizeof_output_item),
+ d_check_topology(true),
+ d_consume_type(cons_type),
+ d_min_consume(0),
+ d_max_consume(0),
+ d_produce_type(prod_type),
+ d_min_produce(0),
+ d_max_produce(0)
+ {
+ set_history(history);
+ set_output_multiple(output_multiple);
+ set_relative_rate(relative_rate);
+ set_fixed_rate(fixed_rate);
+ }
+
+ int
+ test::general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ //touch all inputs and outputs to detect segfaults
+ unsigned ninputs = input_items.size ();
+ unsigned noutputs= output_items.size();
+ for(unsigned i = 0; i < ninputs; i++) {
+ char * in=(char *)input_items[i];
+ if(ninput_items[i]< (int)(noutput_items+history())) {
+ std::cerr << "ERROR: ninput_items[" << i << "] < noutput_items+history()" << std::endl;
+ std::cerr << "ninput_items[" << i << "] = " << ninput_items[i] << std::endl;
+ std::cerr << "noutput_items+history() = " << noutput_items+history() << std::endl;
+ std::cerr << "noutput_items = " << noutput_items << std::endl;
+ std::cerr << "history() = " << history() << std::endl;
+ throw std::runtime_error ("test");
+ }
+ else {
+ for (int j = 0; j < ninput_items[i]; j++) {
+ //Touch every available input_item
+ //We use a class variable to avoid the compiler to optimize this away
+ for(unsigned int k = 0; k < d_sizeof_input_item; k++)
+ d_temp= in[j*d_sizeof_input_item+k];
+ }
+ switch(d_consume_type){
+ case CONSUME_NOUTPUT_ITEMS:
+ consume(i,noutput_items);
+ break;
+ case CONSUME_NOUTPUT_ITEMS_LIMIT_MAX:
+ consume(i,std::min(noutput_items,d_max_consume));
+ break;
+ case CONSUME_NOUTPUT_ITEMS_LIMIT_MIN:
+ consume(i,std::min(std::max(noutput_items,d_min_consume),ninput_items[i]));
+ break;
+ case CONSUME_ALL_AVAILABLE:
+ consume(i,ninput_items[i]);
+ break;
+ case CONSUME_ALL_AVAILABLE_LIMIT_MAX:
+ consume(i,std::min(ninput_items[i],d_max_consume));
+ break;
+/* //This could result in segfault, uncomment if you want to test this
+ case CONSUME_ALL_AVAILABLE_LIMIT_MIN:
+ consume(i,std::max(ninput_items[i],d_max_consume));
+ break;*/
+ case CONSUME_ZERO:
+ consume(i,0);
+ break;
+ case CONSUME_ONE:
+ consume(i,1);
+ break;
+ case CONSUME_MINUS_ONE:
+ consume(i,-1);
+ break;
+ default:
+ consume(i,noutput_items);
+ }
+ }
+ }
+ for(unsigned i = 0; i < noutputs; i++) {
+ char * out=(char *)output_items[i];
+ {
+ for(int j=0;j<noutput_items;j++) {
+ //Touch every available output_item
+ for(unsigned int k=0;k<d_sizeof_output_item;k++)
+ out[j*d_sizeof_input_item+k]=0;
+ }
+ }
+ }
+ //Now copy input to output until max ninputs or max noutputs is reached
+ int common_nports=std::min(ninputs,noutputs);
+ if(d_sizeof_output_item==d_sizeof_input_item)
+ for(int i = 0; i < common_nports; i++) {
+ memcpy(output_items[i],input_items[i],noutput_items*d_sizeof_input_item);
+ }
+ int noutput_items_produced=0;
+ switch(d_produce_type) {
+ case PRODUCE_NOUTPUT_ITEMS:
+ noutput_items_produced=noutput_items;
+ break;
+ case PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX:
+ noutput_items_produced=std::min(noutput_items,d_max_produce);
+ break;
+/* //This could result in segfault, uncomment if you want to test this
+ case PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN:
+ noutput_items_produced=std::max(noutput_items,d_min_produce);
+ break;*/
+ case PRODUCE_ZERO:
+ noutput_items_produced=0;
+ break;
+ case PRODUCE_ONE:
+ noutput_items_produced=1;
+ break;
+ case PRODUCE_MINUS_ONE:
+ noutput_items_produced=-1;
+ break;
+ default:
+ noutput_items_produced=noutput_items;
+ }
+ return noutput_items_produced;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/test.h b/gnuradio-runtime/lib/test.h
new file mode 100644
index 0000000000..cbe42f94e8
--- /dev/null
+++ b/gnuradio-runtime/lib/test.h
@@ -0,0 +1,225 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,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.
+ */
+
+#ifndef INCLUDED_GR_TEST_H
+#define INCLUDED_GR_TEST_H
+
+#include <gnuradio/api.h>
+#include <gnuradio/block.h>
+#include <string>
+#include "test_types.h"
+
+namespace gr {
+
+ class test;
+ typedef boost::shared_ptr<test> test_sptr;
+
+ // public constructor
+ GR_RUNTIME_API test_sptr
+ make_test(const std::string &name=std::string("test"),
+ int min_inputs=1, int max_inputs=1, unsigned int sizeof_input_item=1,
+ int min_outputs=1, int max_outputs=1, unsigned int sizeof_output_item=1,
+ unsigned int history=1,unsigned int output_multiple=1,double relative_rate=1.0,
+ bool fixed_rate=true,consume_type_t cons_type=CONSUME_NOUTPUT_ITEMS,
+ produce_type_t prod_type=PRODUCE_NOUTPUT_ITEMS);
+
+ /*!
+ * \brief Test class for testing runtime system (setting up buffers and such.)
+ * \ingroup misc
+ *
+ * This block does not do any usefull actual data processing. It
+ * just exposes setting all standard block parameters using the
+ * contructor or public methods.
+ *
+ * This block can be usefull when testing the runtime system.
+ * You can force this block to have a large history, decimation
+ * factor and/or large output_multiple.
+ * The runtime system should detect this and create large enough buffers
+ * all through the signal chain.
+ */
+ class GR_RUNTIME_API test : public block
+ {
+ public:
+ ~test() {}
+
+ int general_work(int noutput_items,
+ gr_vector_int &ninput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items);
+
+ // ----------------------------------------------------------------
+ // override these to define your behavior
+ // ----------------------------------------------------------------
+
+ /*!
+ * \brief Estimate input requirements given output request
+ *
+ * \param noutput_items number of output items to produce
+ * \param ninput_items_required number of input items required on each input stream
+ *
+ * Given a request to product \p noutput_items, estimate the
+ * number of data items required on each input stream. The
+ * estimate doesn't have to be exact, but should be close.
+ */
+ void forecast(int noutput_items,
+ gr_vector_int &ninput_items_required)
+ {
+ unsigned ninputs = ninput_items_required.size();
+ for(unsigned i = 0; i < ninputs; i++)
+ ninput_items_required[i] = (int)((double)noutput_items / relative_rate()) + (int)history();
+ }
+
+ /*!
+ * \brief Force check topology to return true or false.
+ *
+ * \param check_topology value to return when check_topology is
+ * called (true or false) default check_topology returns true
+ */
+ void set_check_topology(bool check_topology) {
+ d_check_topology=check_topology;
+ }
+
+ /*!
+ * \brief Confirm that ninputs and noutputs is an acceptable combination.
+ *
+ * \param ninputs number of input streams connected
+ * \param noutputs number of output streams connected
+ *
+ * \returns true if this is a valid configuration for this block.
+ *
+ * This function is called by the runtime system whenever the
+ * topology changes. Most classes do not need to override this.
+ * This check is in addition to the constraints specified by the
+ * input and output gr::io_signatures.
+ */
+ bool check_topology(int ninputs, int noutputs) {
+ return d_check_topology;
+ }
+
+ // ----------------------------------------------------------------
+ /*
+ * The following two methods provide special case info to the
+ * scheduler in the event that a block has a fixed input to output
+ * ratio. gr::sync_block, gr::sync_decimator and
+ * gr::sync_interpolator override these. If you're fixed rate,
+ * subclass one of those.
+ */
+ /*!
+ * \brief Given ninput samples, return number of output samples
+ * that will be produced. N.B. this is only defined if fixed_rate
+ * returns true. Generally speaking, you don't need to override
+ * this.
+ */
+ int fixed_rate_ninput_to_noutput(int ninput) {
+ return (int)((double)ninput/relative_rate());
+ }
+
+ /*!
+ * \brief Given noutput samples, return number of input samples
+ * required to produce noutput. N.B. this is only defined if
+ * fixed_rate returns true.
+ */
+ int fixed_rate_noutput_to_ninput(int noutput) {
+ return (int)((double)noutput*relative_rate());
+ }
+
+ /*!
+ * \brief Set if fixed rate should return true.
+ * N.B. This is normally a private method but we make it available here as public.
+ */
+ void set_fixed_rate_public(bool fixed_rate) {
+ set_fixed_rate(fixed_rate);
+ }
+
+ /*!
+ * \brief Set the consume pattern.
+ *
+ * \param cons_type which consume pattern to use
+ */
+ void set_consume_type(consume_type_t cons_type) {
+ d_consume_type=cons_type;
+ }
+
+ /*!
+ * \brief Set the consume limit.
+ *
+ * \param limit min or maximum items to consume (depending on
+ * consume_type)
+ */
+ void set_consume_limit(unsigned int limit) {
+ d_min_consume=limit; d_max_consume=limit;
+ }
+
+ /*!
+ * \brief Set the produce pattern.
+ *
+ * \param prod_type which produce pattern to use
+ */
+ void set_produce_type(produce_type_t prod_type) {
+ d_produce_type=prod_type;
+ }
+
+ /*!
+ * \brief Set the produce limit.
+ *
+ * \param limit min or maximum items to produce (depending on
+ * produce_type)
+ */
+ void set_produce_limit(unsigned int limit) {
+ d_min_produce=limit; d_max_produce=limit;
+ }
+
+ // ----------------------------------------------------------------------------
+
+ protected:
+ unsigned int d_sizeof_input_item;
+ unsigned int d_sizeof_output_item;
+ bool d_check_topology;
+ char d_temp;
+ consume_type_t d_consume_type;
+ int d_min_consume;
+ int d_max_consume;
+ produce_type_t d_produce_type;
+ int d_min_produce;
+ int d_max_produce;
+ test(const std::string &name,int min_inputs, int max_inputs,
+ unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs, unsigned int sizeof_output_item,
+ unsigned int history, unsigned int output_multiple, double relative_rate,
+ bool fixed_rate, consume_type_t cons_type, produce_type_t prod_type);
+
+ friend GR_RUNTIME_API test_sptr make_test(const std::string &name,
+ int min_inputs, int max_inputs,
+ unsigned int sizeof_input_item,
+ int min_outputs, int max_outputs,
+ unsigned int sizeof_output_item,
+ unsigned int history,
+ unsigned int output_multiple,
+ double relative_rate,
+ bool fixed_rate,
+ consume_type_t cons_type,
+ produce_type_t prod_type);
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_TEST_H */
diff --git a/gnuradio-runtime/lib/test_runtime.cc b/gnuradio-runtime/lib/test_runtime.cc
index 7dc7b17ea0..c85d325174 100644
--- a/gnuradio-runtime/lib/test_runtime.cc
+++ b/gnuradio-runtime/lib/test_runtime.cc
@@ -27,7 +27,7 @@
#include <cppunit/TextTestRunner.h>
#include <cppunit/XmlOutputter.h>
-#include <gr_unittests.h>
+#include <gnuradio/unittests.h>
#include <qa_runtime.h>
#include <pmt/qa_pmt.h>
diff --git a/gnuradio-runtime/lib/gr_test_types.h b/gnuradio-runtime/lib/test_types.h
index 04f38f7b26..868a9e62a3 100644
--- a/gnuradio-runtime/lib/gr_test_types.h
+++ b/gnuradio-runtime/lib/test_types.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2006 Free Software Foundation, Inc.
+ * Copyright 2006,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -19,28 +19,33 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+
#ifndef INCLUDED_GR_TEST_TYPES_H
#define INCLUDED_GR_TEST_TYPES_H
-typedef enum {
- CONSUME_NOUTPUT_ITEMS=0,
- CONSUME_NOUTPUT_ITEMS_LIMIT_MAX=1,
- CONSUME_NOUTPUT_ITEMS_LIMIT_MIN=2,
- CONSUME_ALL_AVAILABLE=3,
- CONSUME_ALL_AVAILABLE_LIMIT_MAX=4,
- /*CONSUME_ALL_AVAILABLE_LIMIT_MIN=5,*/
- CONSUME_ZERO=6,
- CONSUME_ONE=7,
- CONSUME_MINUS_ONE=8
- } gr_consume_type_t;
+namespace gr {
+
+ typedef enum {
+ CONSUME_NOUTPUT_ITEMS=0,
+ CONSUME_NOUTPUT_ITEMS_LIMIT_MAX=1,
+ CONSUME_NOUTPUT_ITEMS_LIMIT_MIN=2,
+ CONSUME_ALL_AVAILABLE=3,
+ CONSUME_ALL_AVAILABLE_LIMIT_MAX=4,
+ /*CONSUME_ALL_AVAILABLE_LIMIT_MIN=5,*/
+ CONSUME_ZERO=6,
+ CONSUME_ONE=7,
+ CONSUME_MINUS_ONE=8
+ } consume_type_t;
+
+ typedef enum {
+ PRODUCE_NOUTPUT_ITEMS=0,
+ PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX=1,
+ /*PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN=2,*/
+ PRODUCE_ZERO=6,
+ PRODUCE_ONE=7,
+ PRODUCE_MINUS_ONE=8
+ } produce_type_t;
-typedef enum {
- PRODUCE_NOUTPUT_ITEMS=0,
- PRODUCE_NOUTPUT_ITEMS_LIMIT_MAX=1,
- /*PRODUCE_NOUTPUT_ITEMS_LIMIT_MIN=2,*/
- PRODUCE_ZERO=6,
- PRODUCE_ONE=7,
- PRODUCE_MINUS_ONE=8
- } gr_produce_type_t;
+} /* namespace gr */
#endif /* INCLUDED_GR_TEST_TYPES_H */
diff --git a/gnuradio-runtime/lib/thread/thread.cc b/gnuradio-runtime/lib/thread/thread.cc
index af0822445d..1727dc6621 100644
--- a/gnuradio-runtime/lib/thread/thread.cc
+++ b/gnuradio-runtime/lib/thread/thread.cc
@@ -23,7 +23,7 @@
#include <config.h>
#endif
-#include <thread/thread.h>
+#include <gnuradio/thread/thread.h>
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
diff --git a/gnuradio-runtime/lib/thread/thread_body_wrapper.cc b/gnuradio-runtime/lib/thread/thread_body_wrapper.cc
index 47feafdd42..e23b7d15d0 100644
--- a/gnuradio-runtime/lib/thread/thread_body_wrapper.cc
+++ b/gnuradio-runtime/lib/thread/thread_body_wrapper.cc
@@ -23,7 +23,7 @@
#include <config.h>
#endif
-#include <thread/thread_body_wrapper.h>
+#include <gnuradio/thread/thread_body_wrapper.h>
#ifdef HAVE_SIGNAL_H
#include <signal.h>
diff --git a/gnuradio-runtime/lib/thread/thread_group.cc b/gnuradio-runtime/lib/thread/thread_group.cc
index 034fe82e75..e467dfda5a 100644
--- a/gnuradio-runtime/lib/thread/thread_group.cc
+++ b/gnuradio-runtime/lib/thread/thread_group.cc
@@ -12,7 +12,7 @@
* This was extracted from Boost 1.35.0 and fixed.
*/
-#include <thread/thread_group.h>
+#include <gnuradio/thread/thread_group.h>
namespace gr {
namespace thread {
diff --git a/gnuradio-runtime/lib/top_block.cc b/gnuradio-runtime/lib/top_block.cc
new file mode 100644
index 0000000000..8d2e42bb12
--- /dev/null
+++ b/gnuradio-runtime/lib/top_block.cc
@@ -0,0 +1,167 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "top_block_impl.h"
+#include <gnuradio/top_block.h>
+#include <gnuradio/io_signature.h>
+#include <gnuradio/prefs.h>
+#include <unistd.h>
+#include <iostream>
+
+namespace gr {
+ top_block_sptr
+ make_top_block(const std::string &name)
+ {
+ return gnuradio::get_initial_sptr
+ (new top_block(name));
+ }
+
+ top_block::top_block(const std::string &name)
+ : hier_block2(name,
+ io_signature::make(0,0,0),
+ io_signature::make(0,0,0))
+ {
+ d_impl = new top_block_impl(this);
+ }
+
+ top_block::~top_block()
+ {
+ stop();
+ wait();
+
+ delete d_impl;
+ }
+
+ void
+ top_block::start(int max_noutput_items)
+ {
+ d_impl->start(max_noutput_items);
+
+ if(prefs::singleton()->get_bool("ControlPort", "on", false)) {
+ setup_rpc();
+ }
+ }
+
+ void
+ top_block::stop()
+ {
+ d_impl->stop();
+ }
+
+ void
+ top_block::wait()
+ {
+ d_impl->wait();
+ }
+
+ void
+ top_block::run(int max_noutput_items)
+ {
+ start(max_noutput_items);
+ wait();
+ }
+
+ void
+ top_block::lock()
+ {
+ d_impl->lock();
+ }
+
+ void
+ top_block::unlock()
+ {
+ d_impl->unlock();
+ }
+
+ std::string
+ top_block::edge_list()
+ {
+ return d_impl->edge_list();
+ }
+
+ void
+ top_block::dump()
+ {
+ d_impl->dump();
+ }
+
+ int
+ top_block::max_noutput_items()
+ {
+ return d_impl->max_noutput_items();
+ }
+
+ void
+ top_block::set_max_noutput_items(int nmax)
+ {
+ d_impl->set_max_noutput_items(nmax);
+ }
+
+ top_block_sptr
+ top_block::to_top_block()
+ {
+ return cast_to_top_block_sptr(shared_from_this());
+ }
+
+ void
+ top_block::setup_rpc()
+ {
+#ifdef GR_CTRLPORT
+ if(is_rpc_set())
+ return;
+
+ // Getters
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<top_block, int>(
+ alias(), "max noutput_items",
+ &top_block::max_noutput_items,
+ pmt::mp(0), pmt::mp(8192), pmt::mp(8192),
+ "items", "Max number of output items",
+ RPC_PRIVLVL_MIN, DISPNULL)));
+
+ if(prefs::singleton()->get_bool("ControlPort", "edges_list", false)) {
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_get<top_block, std::string>(
+ alias(), "edge list",
+ &top_block::edge_list,
+ pmt::mp(""), pmt::mp(""), pmt::mp(""),
+ "edges", "List of edges in the graph",
+ RPC_PRIVLVL_MIN, DISPNULL)));
+ }
+
+ // Setters
+ add_rpc_variable(
+ rpcbasic_sptr(new rpcbasic_register_set<top_block, int>(
+ alias(), "max noutput_items",
+ &top_block::set_max_noutput_items,
+ pmt::mp(0), pmt::mp(8192), pmt::mp(8192),
+ "items", "Max number of output items",
+ RPC_PRIVLVL_MIN, DISPNULL)));
+ rpc_set();
+#endif /* GR_CTRLPORT */
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/top_block_impl.cc b/gnuradio-runtime/lib/top_block_impl.cc
new file mode 100644
index 0000000000..9d377f469f
--- /dev/null
+++ b/gnuradio-runtime/lib/top_block_impl.cc
@@ -0,0 +1,212 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 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 "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>
+
+#include <stdexcept>
+#include <iostream>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+namespace gr {
+
+#define GR_TOP_BLOCK_IMPL_DEBUG 0
+
+ typedef scheduler_sptr(*scheduler_maker)(flat_flowgraph_sptr ffg,
+ int max_noutput_items);
+
+ static struct scheduler_table {
+ const char *name;
+ scheduler_maker f;
+ } scheduler_table[] = {
+ { "TPB", scheduler_tpb::make }, // first entry is default
+ { "STS", scheduler_sts::make }
+ };
+
+ static scheduler_sptr
+ make_scheduler(flat_flowgraph_sptr ffg, int max_noutput_items)
+ {
+ static scheduler_maker factory = 0;
+
+ if(factory == 0) {
+ char *v = getenv("GR_SCHEDULER");
+ if(!v)
+ factory = scheduler_table[0].f; // use default
+ else {
+ for(size_t i = 0; i < sizeof(scheduler_table)/sizeof(scheduler_table[0]); i++) {
+ if(strcmp(v, scheduler_table[i].name) == 0) {
+ factory = scheduler_table[i].f;
+ break;
+ }
+ }
+ if(factory == 0) {
+ std::cerr << "warning: Invalid GR_SCHEDULER environment variable value \""
+ << v << "\". Using \"" << scheduler_table[0].name << "\"\n";
+ factory = scheduler_table[0].f;
+ }
+ }
+ }
+ return factory(ffg, max_noutput_items);
+ }
+
+ top_block_impl::top_block_impl(top_block *owner)
+ : d_owner(owner), d_ffg(),
+ d_state(IDLE), d_lock_count(0)
+ {
+ }
+
+ top_block_impl::~top_block_impl()
+ {
+ d_owner = 0;
+ }
+
+ void
+ top_block_impl::start(int max_noutput_items)
+ {
+ gr::thread::scoped_lock l(d_mutex);
+
+ d_max_noutput_items = max_noutput_items;
+
+ if(d_state != IDLE)
+ throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()");
+
+ if(d_lock_count > 0)
+ throw std::runtime_error("top_block::start: can't start with flow graph locked");
+
+ // Create new flat flow graph by flattening hierarchy
+ d_ffg = d_owner->flatten();
+
+ // Validate new simple flow graph and wire it up
+ d_ffg->validate();
+ d_ffg->setup_connections();
+
+ // Only export perf. counters if ControlPort config param is
+ // enabled and if the PerfCounter option 'export' is turned on.
+ prefs *p = prefs::singleton();
+ if(p->get_bool("ControlPort", "on", false) && p->get_bool("PerfCounters", "export", false))
+ d_ffg->enable_pc_rpc();
+
+ d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
+ d_state = RUNNING;
+ }
+
+ void
+ top_block_impl::stop()
+ {
+ if(d_scheduler)
+ d_scheduler->stop();
+ }
+
+ void
+ top_block_impl::wait()
+ {
+ if(d_scheduler)
+ d_scheduler->wait();
+
+ d_state = IDLE;
+ }
+
+ // N.B. lock() and unlock() cannot be called from a flow graph
+ // thread or deadlock will occur when reconfiguration happens
+ void
+ top_block_impl::lock()
+ {
+ gr::thread::scoped_lock lock(d_mutex);
+ d_lock_count++;
+ }
+
+ void
+ top_block_impl::unlock()
+ {
+ gr::thread::scoped_lock lock(d_mutex);
+
+ if(d_lock_count <= 0) {
+ d_lock_count = 0; // fix it, then complain
+ throw std::runtime_error("unpaired unlock() call");
+ }
+
+ d_lock_count--;
+ if(d_lock_count > 0 || d_state == IDLE) // nothing to do
+ return;
+
+ restart();
+ }
+
+ /*
+ * restart is called with d_mutex held
+ */
+ void
+ top_block_impl::restart()
+ {
+ stop(); // Stop scheduler and wait for completion
+ wait();
+
+ // Create new simple flow graph
+ flat_flowgraph_sptr new_ffg = d_owner->flatten();
+ new_ffg->validate(); // check consistency, sanity, etc
+ new_ffg->merge_connections(d_ffg); // reuse buffers, etc
+ d_ffg = new_ffg;
+
+ // Create a new scheduler to execute it
+ d_scheduler = make_scheduler(d_ffg, d_max_noutput_items);
+ d_state = RUNNING;
+ }
+
+ std::string
+ top_block_impl::edge_list()
+ {
+ if(d_ffg)
+ return d_ffg->edge_list();
+ else
+ return "";
+ }
+
+ void
+ top_block_impl::dump()
+ {
+ if(d_ffg)
+ d_ffg->dump();
+ }
+
+ int
+ top_block_impl::max_noutput_items()
+ {
+ return d_max_noutput_items;
+ }
+
+ void
+ top_block_impl::set_max_noutput_items(int nmax)
+ {
+ d_max_noutput_items = nmax;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/top_block_impl.h b/gnuradio-runtime/lib/top_block_impl.h
new file mode 100644
index 0000000000..9e0e661a02
--- /dev/null
+++ b/gnuradio-runtime/lib/top_block_impl.h
@@ -0,0 +1,90 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007,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 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_TOP_BLOCK_IMPL_H
+#define INCLUDED_GR_TOP_BLOCK_IMPL_H
+
+#include <gnuradio/api.h>
+#include "scheduler.h"
+#include <gnuradio/thread/thread.h>
+
+namespace gr {
+
+ /*!
+ *\brief Abstract implementation details of top_block
+ * \ingroup internal
+ *
+ * The actual implementation of top_block. Separate class allows
+ * decoupling of changes from dependent classes.
+ */
+ class GR_RUNTIME_API top_block_impl
+ {
+ public:
+ top_block_impl(top_block *owner);
+ ~top_block_impl();
+
+ // Create and start scheduler threads
+ void start(int max_noutput_items=100000000);
+
+ // Signal scheduler threads to stop
+ void stop();
+
+ // Wait for scheduler threads to exit
+ void wait();
+
+ // Lock the top block to allow reconfiguration
+ void lock();
+
+ // Unlock the top block at end of reconfiguration
+ void unlock();
+
+ // Return a string list of edges
+ std::string edge_list();
+
+ // Dump the flowgraph to stdout
+ void dump();
+
+ // Get the number of max noutput_items in the flowgraph
+ int max_noutput_items();
+
+ // Set the maximum number of noutput_items in the flowgraph
+ void set_max_noutput_items(int nmax);
+
+ protected:
+ enum tb_state { IDLE, RUNNING };
+
+ top_block *d_owner;
+ flat_flowgraph_sptr d_ffg;
+ scheduler_sptr d_scheduler;
+
+ gr::thread::mutex d_mutex; // protects d_state and d_lock_count
+ tb_state d_state;
+ int d_lock_count;
+ int d_max_noutput_items;
+
+ private:
+ void restart();
+ };
+
+} /* namespace gr */
+
+#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_H */
diff --git a/gnuradio-runtime/lib/tpb_detail.cc b/gnuradio-runtime/lib/tpb_detail.cc
new file mode 100644
index 0000000000..cf05c2b102
--- /dev/null
+++ b/gnuradio-runtime/lib/tpb_detail.cc
@@ -0,0 +1,71 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,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 <gnuradio/tpb_detail.h>
+#include <gnuradio/block.h>
+#include <gnuradio/block_detail.h>
+#include <gnuradio/buffer.h>
+
+namespace gr {
+
+ /*
+ * We assume that no worker threads are ever running when the graph
+ * structure is being manipulated, thus it's safe for us to poke
+ * around in our neighbors w/o holding any locks.
+ */
+ void
+ tpb_detail::notify_upstream(block_detail *d)
+ {
+ // For each of our inputs, tell the guy upstream that we've
+ // consumed some input, and that he most likely has more output
+ // buffer space available.
+
+ for(size_t i = 0; i < d->d_input.size(); i++) {
+ // Can you say, "pointer chasing?"
+ d->d_input[i]->buffer()->link()->detail()->d_tpb.set_output_changed();
+ }
+ }
+
+ void
+ tpb_detail::notify_downstream(block_detail *d)
+ {
+ // For each of our outputs, tell the guys downstream that they
+ // have new input available.
+
+ for(size_t i = 0; i < d->d_output.size(); i++) {
+ buffer_sptr buf = d->d_output[i];
+ for(size_t j = 0, k = buf->nreaders(); j < k; j++)
+ buf->reader(j)->link()->detail()->d_tpb.set_input_changed();
+ }
+ }
+
+ void
+ tpb_detail::notify_neighbors(block_detail *d)
+ {
+ notify_downstream(d);
+ notify_upstream(d);
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/tpb_thread_body.cc b/gnuradio-runtime/lib/tpb_thread_body.cc
new file mode 100644
index 0000000000..ceb94fbb2a
--- /dev/null
+++ b/gnuradio-runtime/lib/tpb_thread_body.cc
@@ -0,0 +1,151 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008,2009,2011,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 "tpb_thread_body.h"
+#include <gnuradio/prefs.h>
+#include <boost/thread.hpp>
+#include <boost/foreach.hpp>
+#include <pmt/pmt.h>
+#include <iostream>
+
+namespace gr {
+
+ tpb_thread_body::tpb_thread_body(block_sptr block, int max_noutput_items)
+ : d_exec(block, max_noutput_items)
+ {
+ //std::cerr << "tpb_thread_body: " << block << std::endl;
+
+ block_detail *d = block->detail().get();
+ block_executor::state s;
+ pmt::pmt_t msg;
+
+ d->threaded = true;
+ d->thread = gr::thread::get_current_thread_id();
+
+ prefs *p = prefs::singleton();
+ size_t max_nmsgs = static_cast<size_t>(p->get_long("DEFAULT", "max_messages", 100));
+
+ // Set thread affinity if it was set before fg was started.
+ if(block->processor_affinity().size() > 0) {
+ gr::thread::thread_bind_to_processor(d->thread, block->processor_affinity());
+ }
+
+ while(1) {
+ boost::this_thread::interruption_point();
+
+ // handle any queued up messages
+ //BOOST_FOREACH( pmt::pmt_t port, block->msg_queue.keys() )
+
+ BOOST_FOREACH(basic_block::msg_queue_map_t::value_type &i, block->msg_queue) {
+ // Check if we have a message handler attached before getting
+ // any messages. This is mostly a protection for the unknown
+ // startup sequence of the threads.
+ if(block->has_msg_handler(i.first)) {
+ while((msg = block->delete_head_nowait(i.first))) {
+ block->dispatch_msg(i.first,msg);
+ }
+ }
+ else {
+ // If we don't have a handler but are building up messages,
+ // prune the queue from the front to keep memory in check.
+ if(block->nmsgs(i.first) > max_nmsgs)
+ msg = block->delete_head_nowait(i.first);
+ }
+ }
+
+ 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;
+ }
+
+ switch(s){
+ 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
+ d->d_tpb.notify_upstream(d);
+ break;
+
+ case block_executor::DONE: // Game over.
+ d->d_tpb.notify_neighbors(d);
+ return;
+
+ 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_p())
+ d->d_tpb.input_cond.wait(guard);
+
+ // handle all pending messages
+ BOOST_FOREACH(basic_block::msg_queue_map_t::value_type &i, block->msg_queue) {
+ while((msg = block->delete_head_nowait(i.first))) {
+ guard.unlock(); // release lock while processing msg
+ block->dispatch_msg(i.first, msg);
+ guard.lock();
+ }
+ }
+ }
+ }
+ break;
+
+ 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_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) {
+ while((msg = block->delete_head_nowait(i.first))) {
+ guard.unlock(); // release lock while processing msg
+ block->dispatch_msg(i.first,msg);
+ guard.lock();
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+ }
+
+ tpb_thread_body::~tpb_thread_body()
+ {
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gr_tpb_thread_body.h b/gnuradio-runtime/lib/tpb_thread_body.h
index 6ecb022f69..9859b125dd 100644
--- a/gnuradio-runtime/lib/gr_tpb_thread_body.h
+++ b/gnuradio-runtime/lib/tpb_thread_body.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2008 Free Software Foundation, Inc.
+ * Copyright 2008,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -21,26 +21,29 @@
#ifndef INCLUDED_GR_TPB_THREAD_BODY_H
#define INCLUDED_GR_TPB_THREAD_BODY_H
-#include <gr_runtime_api.h>
-#include <gr_block_executor.h>
-#include <gr_block.h>
-#include <gr_block_detail.h>
+#include <gnuradio/api.h>
+#include <gnuradio/block.h>
+#include <gnuradio/block_detail.h>
+#include "block_executor.h"
-/*!
- * \brief The body of each thread-per-block thread.
- *
- * One of these is instantiated in its own thread for each block. The
- * constructor turns into the main loop which returns when the block is
- * done or is interrupted.
- */
+namespace gr {
-class GR_RUNTIME_API gr_tpb_thread_body {
- gr_block_executor d_exec;
+ /*!
+ * \brief The body of each thread-per-block thread.
+ *
+ * One of these is instantiated in its own thread for each block.
+ * The constructor turns into the main loop which returns when the
+ * block is done or is interrupted.
+ */
+ class GR_RUNTIME_API tpb_thread_body
+ {
+ block_executor d_exec;
-public:
- gr_tpb_thread_body(gr_block_sptr block, int max_noutput_items=100000);
- ~gr_tpb_thread_body();
-};
+ public:
+ tpb_thread_body(block_sptr block, int max_noutput_items=100000);
+ ~tpb_thread_body();
+ };
+} /* namespace gr */
#endif /* INCLUDED_GR_TPB_THREAD_BODY_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf.cc b/gnuradio-runtime/lib/vmcircbuf.cc
new file mode 100644
index 0000000000..0fccb3d914
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf.cc
@@ -0,0 +1,299 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdexcept>
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+#include <boost/format.hpp>
+#include "vmcircbuf.h"
+#include "vmcircbuf_prefs.h"
+#include "local_sighandler.h"
+
+// all the factories we know about
+#include "vmcircbuf_createfilemapping.h"
+#include "vmcircbuf_sysv_shm.h"
+#include "vmcircbuf_mmap_shm_open.h"
+#include "vmcircbuf_mmap_tmpfile.h"
+
+namespace gr {
+
+ static const char *FACTORY_PREF_KEY = "vmcircbuf_default_factory";
+
+ vmcircbuf::~vmcircbuf()
+ {
+ }
+
+ vmcircbuf_factory::~vmcircbuf_factory()
+ {
+ }
+
+ // ----------------------------------------------------------------
+
+ static vmcircbuf_factory *s_default_factory = 0;
+
+ vmcircbuf_factory *
+ vmcircbuf_sysconfig::get_default_factory()
+ {
+ if(s_default_factory)
+ return s_default_factory;
+
+ bool verbose = false;
+
+ std::vector<gr::vmcircbuf_factory *> all = all_factories ();
+
+ const char *name = gr::vmcircbuf_prefs::get(FACTORY_PREF_KEY);
+
+ if(name) {
+ for(unsigned int i = 0; i < all.size (); i++) {
+ if(strcmp(name, all[i]->name ()) == 0) {
+ s_default_factory = all[i];
+ if(verbose)
+ fprintf(stderr, "gr::vmcircbuf_sysconfig: using %s\n",
+ s_default_factory->name());
+ return s_default_factory;
+ }
+ }
+ }
+
+ // either we don't have a default, or the default named is not in our
+ // list of factories. Find the first factory that works.
+
+ if(verbose)
+ fprintf(stderr, "gr::vmcircbuf_sysconfig: finding a working factory...\n");
+
+ for(unsigned int i = 0; i < all.size (); i++) {
+ if(test_factory(all[i], verbose)) {
+ set_default_factory(all[i]);
+ return s_default_factory;
+ }
+ }
+
+ // We're screwed!
+ fprintf(stderr, "gr::vmcircbuf_sysconfig: unable to find a working factory!\n");
+ throw std::runtime_error("gr::vmcircbuf_sysconfig");
+ }
+
+ std::vector<vmcircbuf_factory *>
+ vmcircbuf_sysconfig::all_factories()
+ {
+ std::vector<vmcircbuf_factory*> result;
+
+ result.push_back(gr::vmcircbuf_createfilemapping_factory::singleton());
+#ifdef TRY_SHM_VMCIRCBUF
+ result.push_back(gr::vmcircbuf_sysv_shm_factory::singleton());
+ result.push_back(gr::vmcircbuf_mmap_shm_open_factory::singleton());
+#endif
+ result.push_back (gr::vmcircbuf_mmap_tmpfile_factory::singleton());
+
+ return result;
+ }
+
+ void
+ vmcircbuf_sysconfig::set_default_factory(vmcircbuf_factory *f)
+ {
+ gr::vmcircbuf_prefs::set(FACTORY_PREF_KEY, f->name());
+ s_default_factory = f;
+ }
+
+
+ // ------------------------------------------------------------------------
+ // test code for vmcircbuf factories
+ // ------------------------------------------------------------------------
+
+ static void
+ init_buffer(vmcircbuf *c, int counter, int size)
+ {
+ unsigned int *p = (unsigned int*)c->pointer_to_first_copy();
+ for(unsigned int i = 0; i < size / sizeof(int); i++)
+ p[i] = counter + i;
+ }
+
+ static bool
+ check_mapping(vmcircbuf *c, int counter, int size, const char *msg, bool verbose)
+ {
+ bool ok = true;
+
+ if(verbose)
+ fprintf(stderr, "... %s", msg);
+
+ unsigned int *p1 = (unsigned int *)c->pointer_to_first_copy();
+ unsigned int *p2 = (unsigned int *)c->pointer_to_second_copy();
+
+ // fprintf(stderr, "p1 = %p, p2 = %p\n", p1, p2);
+
+ for(unsigned int i = 0; i < size / sizeof (int); i++) {
+ if(p1[i] != counter + i) {
+ ok = false;
+ if(verbose)
+ fprintf(stderr, " p1[%d] == %u, expected %u\n", i, p1[i], counter + i);
+ break;
+ }
+ if(p2[i] != counter + i) {
+ if(verbose)
+ fprintf(stderr, " p2[%d] == %u, expected %u\n", i, p2[i], counter + i);
+ ok = false;
+ break;
+ }
+ }
+
+ if(ok && verbose) {
+ fprintf(stderr, " OK\n");
+ }
+ return ok;
+ }
+
+ static const char *
+ memsize(int size)
+ {
+ static std::string buf;
+ if(size >= (1 << 20)) {
+ buf = str(boost::format("%dMB") % (size / (1 << 20)));
+ }
+ else if(size >= (1 << 10)){
+ buf = str(boost::format("%dKB") % (size / (1 << 10)));
+ }
+ else {
+ buf = str(boost::format("%d") % size);
+ }
+ return buf.c_str();
+ }
+
+ static bool
+ test_a_bunch(vmcircbuf_factory *factory, int n, int size, int *start_ptr, bool verbose)
+ {
+ bool ok = true;
+ std::vector<int> counter(n);
+ std::vector<vmcircbuf*> c(n);
+ int cum_size = 0;
+
+ for(int i = 0; i < n; i++) {
+ counter[i] = *start_ptr;
+ *start_ptr += size;
+ if((c[i] = factory->make (size)) == 0) {
+ if(verbose)
+ fprintf(stderr,
+ "Failed to allocate gr::vmcircbuf number %d of size %d (cum = %s)\n",
+ i + 1, size, memsize(cum_size));
+ return false;
+ }
+ init_buffer(c[i], counter[i], size);
+ cum_size += size;
+ }
+
+ for(int i = 0; i < n; i++) {
+ std::string msg = str(boost::format("test_a_bunch_%dx%s[%d]") % n % memsize(size) % i);
+ ok &= check_mapping(c[i], counter[i], size, msg.c_str(), verbose);
+ }
+
+ for(int i = 0; i < n; i++) {
+ delete c[i];
+ c[i] = 0;
+ }
+
+ return ok;
+ }
+
+ static bool
+ standard_tests(vmcircbuf_factory *f, int verbose)
+ {
+ if(verbose >= 1)
+ fprintf(stderr, "Testing %s...\n", f->name());
+
+ bool v = verbose >= 2;
+ int granularity = f->granularity();
+ int start = 0;
+ bool ok = true;
+
+ ok &= test_a_bunch(f, 1, 1 * granularity, &start, v); // 1 x 4KB = 4KB
+
+ if(ok) {
+ ok &= test_a_bunch(f, 64, 4 * granularity, &start, v); // 64 x 16KB = 1MB
+ ok &= test_a_bunch(f, 4, 4 * (1L << 20), &start, v); // 4 x 4MB = 16MB
+ // ok &= test_a_bunch(f, 256, 256 * (1L << 10), &start, v); // 256 x 256KB = 64MB
+ }
+
+ if(verbose >= 1)
+ fprintf(stderr, "....... %s: %s", f->name(), ok ? "OK\n" : "Doesn't work\n");
+
+ return ok;
+ }
+
+ bool
+ vmcircbuf_sysconfig::test_factory(vmcircbuf_factory *f, int verbose)
+ {
+ // Install local signal handlers for SIGSEGV and SIGBUS.
+ // If something goes wrong, these signals may be invoked.
+
+#ifdef SIGSEGV
+ gr::local_sighandler sigsegv (SIGSEGV, gr::local_sighandler::throw_signal);
+#endif
+#ifdef SIGBUS
+ gr::local_sighandler sigbus (SIGBUS, gr::local_sighandler::throw_signal);
+#endif
+#ifdef SIGSYS
+ gr::local_sighandler sigsys (SIGSYS, gr::local_sighandler::throw_signal);
+#endif
+
+ try {
+ return standard_tests (f, verbose);
+ }
+ catch(gr::signal &sig) {
+ if(verbose) {
+ fprintf(stderr, "....... %s: %s", f->name(), "Doesn't work\n");
+ fprintf(stderr,
+ "gr::vmcircbuf_factory::test_factory (%s): caught %s\n",
+ f->name(), sig.name().c_str());
+ return false;
+ }
+ }
+ catch (...) {
+ if(verbose) {
+ fprintf(stderr, "....... %s: %s", f->name(), "Doesn't work\n");
+ fprintf(stderr,
+ "gr::vmcircbuf_factory::test_factory (%s): some kind of uncaught exception\n",
+ f->name());
+ }
+ return false;
+ }
+ return false; // never gets here. shut compiler up.
+ }
+
+ bool
+ vmcircbuf_sysconfig::test_all_factories(int verbose)
+ {
+ bool ok = false;
+
+ std::vector<vmcircbuf_factory *> all = all_factories();
+
+ for(unsigned int i = 0; i < all.size (); i++)
+ ok |= test_factory(all[i], verbose);
+
+ return ok;
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/vmcircbuf.h b/gnuradio-runtime/lib/vmcircbuf.h
new file mode 100644
index 0000000000..c3ddfe0043
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf.h
@@ -0,0 +1,125 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef GR_VMCIRCBUF_H
+#define GR_VMCIRCBUF_H
+
+#include <gnuradio/api.h>
+#include <vector>
+
+namespace gr {
+
+ /*!
+ * \brief abstract class to implement doubly mapped virtual memory circular buffers
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API vmcircbuf
+ {
+ protected:
+ int d_size;
+ char *d_base;
+
+ // CREATORS
+ vmcircbuf(int size) : d_size(size), d_base(0) {};
+
+ public:
+ virtual ~vmcircbuf();
+
+ // ACCESSORS
+ void *pointer_to_first_copy() const{ return d_base; }
+ void *pointer_to_second_copy() const{ return d_base + d_size; }
+ };
+
+ /*!
+ * \brief abstract factory for creating circular buffers
+ */
+ class GR_RUNTIME_API vmcircbuf_factory
+ {
+ protected:
+ vmcircbuf_factory() {};
+ virtual ~vmcircbuf_factory();
+
+ public:
+
+ /*!
+ * \brief return name of this factory
+ */
+ virtual const char *name() const = 0;
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity() = 0;
+
+ /*!
+ * \brief return a gr::vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual vmcircbuf *make(int size) = 0;
+ };
+
+ /*
+ * \brief pulls together all implementations of gr::vmcircbuf
+ */
+ class GR_RUNTIME_API vmcircbuf_sysconfig
+ {
+ public:
+ /*
+ * \brief return the single instance of the default factory.
+ *
+ * returns the default factory to use if it's already defined,
+ * else find the first working factory and use it.
+ */
+ static vmcircbuf_factory *get_default_factory();
+
+ static int granularity() { return get_default_factory()->granularity(); }
+ static vmcircbuf *make(int size) { return get_default_factory()->make(size); }
+
+ // N.B. not all factories are guaranteed to work.
+ // It's too hard to check everything at config time, so we check at runtime
+ static std::vector<vmcircbuf_factory*> all_factories();
+
+ // make this factory the default
+ static void set_default_factory(vmcircbuf_factory *f);
+
+ /*!
+ * \brief Does this factory really work?
+ *
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_factory(vmcircbuf_factory *f, int verbose);
+
+ /*!
+ * \brief Test all factories, return true if at least one of them works
+ * verbose = 0: silent
+ * verbose = 1: names of factories tested and results
+ * verbose = 2: all intermediate results
+ */
+ static bool test_all_factories(int verbose);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_VMCIRCBUF_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf_createfilemapping.cc b/gnuradio-runtime/lib/vmcircbuf_createfilemapping.cc
new file mode 100644
index 0000000000..2d345a29b1
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_createfilemapping.cc
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include "pagesize.h"
+#include "vmcircbuf_createfilemapping.h"
+#include <boost/format.hpp>
+
+namespace gr {
+
+#ifdef HAVE_CREATEFILEMAPPING
+ // Print Windows error (could/should be global?)
+ static void
+ werror(char *where, DWORD last_error)
+ {
+ char buf[1024];
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ last_error,
+ 0, // default language
+ buf,
+ sizeof(buf)/sizeof(TCHAR), // buffer size
+ NULL);
+ fprintf(stderr, "%s: Error %d: %s", where, last_error, buf);
+ return;
+ }
+#endif
+
+
+ vmcircbuf_createfilemapping::vmcircbuf_createfilemapping(int size)
+ : gr::vmcircbuf(size)
+ {
+#if !defined(HAVE_CREATEFILEMAPPING)
+ fprintf(stderr, "%s: createfilemapping is not available\n", __FUNCTION__);
+ throw std::runtime_error("gr::vmcircbuf_createfilemapping");
+#else
+ static int s_seg_counter = 0;
+
+ if(size <= 0 || (size % gr::pagesize ()) != 0) {
+ fprintf(stderr, "gr::vmcircbuf_createfilemapping: invalid size = %d\n", size);
+ throw std::runtime_error ("gr::vmcircbuf_createfilemapping");
+ }
+
+ std::string seg_name = str(boost::format("/gnuradio-%d-%d") % getpid() % s_seg_counter);
+
+ d_handle = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
+ NULL, // default security
+ PAGE_READWRITE, // read/write access
+ 0, // max. object size
+ size, // buffer size
+ seg_name.c_str()); // name of mapping object
+
+ s_seg_counter++;
+ if(d_handle == NULL || d_handle == INVALID_HANDLE_VALUE) {
+ std::string msg = str(boost::format(
+ "gr::vmcircbuf_mmap_createfilemapping: CreateFileMapping [%s]") %
+ seg_name);
+ werror((char*)msg.c_str(), GetLastError());
+ throw std::runtime_error("gr::vmcircbuf_mmap_createfilemapping");
+ }
+
+ // Allocate virtual memory of the needed size, then free it so we can use it
+ LPVOID first_tmp;
+ first_tmp = VirtualAlloc( NULL, 2*size, MEM_RESERVE, PAGE_NOACCESS );
+ if(first_tmp == NULL) {
+ werror("gr::vmcircbuf_mmap_createfilemapping: VirtualAlloc", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error("gr::vmcircbuf_mmap_createfilemapping");
+ }
+
+ if(VirtualFree(first_tmp, 0, MEM_RELEASE) == 0) {
+ werror("gr::vmcircbuf_mmap_createfilemapping: VirtualFree", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error("gr::vmcircbuf_mmap_createfilemapping");
+ }
+
+ d_first_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ first_tmp);
+ if(d_first_copy != first_tmp) {
+ werror( "gr::vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(1)", GetLastError());
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr::vmcircbuf_mmap_createfilemapping");
+ }
+
+ d_second_copy = MapViewOfFileEx((HANDLE)d_handle, // handle to map object
+ FILE_MAP_WRITE, // read/write permission
+ 0,
+ 0,
+ size,
+ (char*)first_tmp + size);//(LPVOID) ((char *)d_first_copy + size));
+
+ if(d_second_copy != (char *)first_tmp + size) {
+ werror( "gr::vmcircbuf_mmap_createfilemapping: MapViewOfFileEx(2)", GetLastError());
+ UnmapViewOfFile(d_first_copy);
+ CloseHandle(d_handle); // cleanup
+ throw std::runtime_error ("gr::vmcircbuf_mmap_createfilemapping");
+ }
+
+#ifdef DEBUG
+ fprintf(stderr,"gr::vmcircbuf_mmap_createfilemapping: contiguous? mmap %p %p %p %p\n",
+ (char*)d_first_copy, (char*)d_second_copy, size, (char*)d_first_copy + size);
+#endif
+
+ // Now remember the important stuff
+ d_base = (char*)d_first_copy;
+ d_size = size;
+#endif /*HAVE_CREATEFILEMAPPING*/
+ }
+
+ vmcircbuf_createfilemapping::~vmcircbuf_createfilemapping()
+ {
+#ifdef HAVE_CREATEFILEMAPPING
+ if(UnmapViewOfFile(d_first_copy) == 0) {
+ werror("gr::vmcircbuf_createfilemapping: UnmapViewOfFile(d_first_copy)", GetLastError());
+ }
+ d_base=NULL;
+ if(UnmapViewOfFile(d_second_copy) == 0) {
+ werror("gr::vmcircbuf_createfilemapping: UnmapViewOfFile(d_second_copy)", GetLastError());
+ }
+ //d_second=NULL;
+ CloseHandle(d_handle);
+#endif
+ }
+
+ // ----------------------------------------------------------------
+ // The factory interface
+ // ----------------------------------------------------------------
+
+ gr::vmcircbuf_factory *vmcircbuf_createfilemapping_factory::s_the_factory = 0;
+
+ gr::vmcircbuf_factory *
+ vmcircbuf_createfilemapping_factory::singleton()
+ {
+ if(s_the_factory)
+ return s_the_factory;
+ s_the_factory = new vmcircbuf_createfilemapping_factory();
+ return s_the_factory;
+ }
+
+ int
+ vmcircbuf_createfilemapping_factory::granularity()
+ {
+#ifdef HAVE_CREATEFILEMAPPING
+ // return 65536;//TODO, check, is this needed or can we just use gr::pagesize()
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ //fprintf(stderr,"win32 AllocationGranularity %p\n",(int)system_info.dwAllocationGranularity);
+ return (int)system_info.dwAllocationGranularity;
+#else
+ return gr::pagesize();
+#endif
+ }
+
+ gr::vmcircbuf *
+ vmcircbuf_createfilemapping_factory::make(int size)
+ {
+ try {
+ return new vmcircbuf_createfilemapping(size);
+ }
+ catch(...) {
+ return 0;
+ }
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/vmcircbuf_createfilemapping.h b/gnuradio-runtime/lib/vmcircbuf_createfilemapping.h
new file mode 100644
index 0000000000..0513112f23
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_createfilemapping.h
@@ -0,0 +1,81 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2005,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.
+ */
+
+#ifndef GR_VMCIRCBUF_CREATEFILEMAPPING_H
+#define GR_VMCIRCBUF_CREATEFILEMAPPING_H
+
+#include <gnuradio/api.h>
+#include "vmcircbuf.h"
+
+#ifdef HAVE_CREATEFILEMAPPING
+#include <windows.h>
+#endif
+
+namespace gr {
+
+ /*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API vmcircbuf_createfilemapping : public gr::vmcircbuf
+ {
+ public:
+ // CREATORS
+ vmcircbuf_createfilemapping(int size);
+ virtual ~vmcircbuf_createfilemapping();
+#ifdef HAVE_CREATEFILEMAPPING
+ private:
+ HANDLE d_handle;
+ LPVOID d_first_copy;
+ LPVOID d_second_copy;
+#endif
+ };
+
+ /*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+ class GR_RUNTIME_API vmcircbuf_createfilemapping_factory : public gr::vmcircbuf_factory
+ {
+ private:
+ static gr::vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr::vmcircbuf_factory *singleton();
+
+ virtual const char *name() const { return "gr::vmcircbuf_createfilemapping_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity();
+
+ /*!
+ * \brief return a gr::vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr::vmcircbuf *make(int size);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_VMCIRCBUF_CREATEFILEMAPPING_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc
new file mode 100644
index 0000000000..7b461bc26b
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.cc
@@ -0,0 +1,204 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmcircbuf_mmap_shm_open.h"
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include "pagesize.h"
+#include <gnuradio/sys_paths.h>
+
+namespace gr {
+
+ vmcircbuf_mmap_shm_open::vmcircbuf_mmap_shm_open(int size)
+ : gr::vmcircbuf(size)
+ {
+#if !defined(HAVE_MMAP) || !defined(HAVE_SHM_OPEN)
+ fprintf(stderr, "gr::vmcircbuf_mmap_shm_open: mmap or shm_open is not available\n");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+#else
+ static int s_seg_counter = 0;
+
+ if(size <= 0 || (size % gr::pagesize ()) != 0) {
+ fprintf(stderr, "gr::vmcircbuf_mmap_shm_open: invalid size = %d\n", size);
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+ int shm_fd = -1;
+ char seg_name[1024];
+ static bool portable_format = true;
+
+ // open a new named shared memory segment
+ while(1) {
+ if(portable_format) {
+
+ // This is the POSIX recommended "portable format".
+ // Of course the "portable format" doesn't work on some systems...
+
+ snprintf(seg_name, sizeof(seg_name),
+ "/gnuradio-%d-%d", getpid(), s_seg_counter);
+ }
+ else {
+
+ // Where the "portable format" doesn't work, we try building
+ // a full filesystem pathname pointing into a suitable temporary directory.
+
+ snprintf(seg_name, sizeof(seg_name),
+ "%s/gnuradio-%d-%d", gr::tmp_path(), getpid(), s_seg_counter);
+ }
+
+ shm_fd = shm_open(seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if(shm_fd == -1 && errno == EACCES && portable_format) {
+ portable_format = false;
+ continue; // try again using "non-portable format"
+ }
+
+ s_seg_counter++;
+
+ if(shm_fd == -1) {
+ if(errno == EEXIST) // Named segment already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf(msg, sizeof(msg), "gr::vmcircbuf_mmap_shm_open: shm_open [%s]", seg_name);
+ perror(msg);
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+ break;
+ }
+
+ // We've got a new shared memory segment fd open.
+ // Now set it's length to 2x what we really want and mmap it in.
+ if(ftruncate(shm_fd, (off_t)2 * size) == -1) {
+ close(shm_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_shm_open: ftruncate (1)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+ void *first_copy = mmap(0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t) 0);
+
+ if(first_copy == MAP_FAILED) {
+ close(shm_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_shm_open: mmap (1)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+ // unmap the 2nd half
+ if(munmap ((char *) first_copy + size, size) == -1) {
+ close(shm_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_shm_open: munmap (1)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+ void *second_copy = mmap((char*)first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ shm_fd, (off_t)0);
+
+ if(second_copy == MAP_FAILED) {
+ close(shm_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_shm_open: mmap (2)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+#if 0 // OS/X doesn't allow you to resize the segment
+
+ // cut the shared memory segment down to size
+ if(ftruncate(shm_fd, (off_t)size) == -1) {
+ close(shm_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_shm_open: ftruncate (2)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+#endif
+
+ close(shm_fd); // fd no longer needed. The mapping is retained.
+
+ if(shm_unlink(seg_name) == -1) { // unlink the seg_name.
+ perror("gr::vmcircbuf_mmap_shm_open: shm_unlink");
+ throw std::runtime_error("gr::vmcircbuf_mmap_shm_open");
+ }
+
+ // Now remember the important stuff
+ d_base = (char*)first_copy;
+ d_size = size;
+#endif
+ }
+
+ vmcircbuf_mmap_shm_open::~vmcircbuf_mmap_shm_open()
+ {
+#if defined(HAVE_MMAP)
+ if(munmap (d_base, 2 * d_size) == -1) {
+ perror("gr::vmcircbuf_mmap_shm_open: munmap (2)");
+ }
+#endif
+ }
+
+ // ----------------------------------------------------------------
+ // The factory interface
+ // ----------------------------------------------------------------
+
+ gr::vmcircbuf_factory *vmcircbuf_mmap_shm_open_factory::s_the_factory = 0;
+
+ gr::vmcircbuf_factory *
+ vmcircbuf_mmap_shm_open_factory::singleton()
+ {
+ if(s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr::vmcircbuf_mmap_shm_open_factory();
+ return s_the_factory;
+ }
+
+ int
+ vmcircbuf_mmap_shm_open_factory::granularity()
+ {
+ return gr::pagesize();
+ }
+
+ gr::vmcircbuf *
+ vmcircbuf_mmap_shm_open_factory::make(int size)
+ {
+ try {
+ return new vmcircbuf_mmap_shm_open(size);
+ }
+ catch (...) {
+ return 0;
+ }
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.h b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.h
new file mode 100644
index 0000000000..60654ee46e
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_mmap_shm_open.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef GR_VMCIRCBUF_MMAP_SHM_OPEN_H
+#define GR_VMCIRCBUF_MMAP_SHM_OPEN_H
+
+#include <gnuradio/api.h>
+#include "vmcircbuf.h"
+
+namespace gr {
+
+ /*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API vmcircbuf_mmap_shm_open : public gr::vmcircbuf
+ {
+ public:
+ vmcircbuf_mmap_shm_open(int size);
+ virtual ~vmcircbuf_mmap_shm_open();
+ };
+
+ /*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+ class GR_RUNTIME_API vmcircbuf_mmap_shm_open_factory : public gr::vmcircbuf_factory
+ {
+ private:
+ static gr::vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr::vmcircbuf_factory *singleton();
+
+ virtual const char *name() const { return "gr::vmcircbuf_mmap_shm_open_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity();
+
+ /*!
+ * \brief return a gr::vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr::vmcircbuf *make(int size);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_VMCIRCBUF_MMAP_SHM_OPEN_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.cc b/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.cc
new file mode 100644
index 0000000000..ffe2a3d2c2
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.cc
@@ -0,0 +1,197 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmcircbuf_mmap_tmpfile.h"
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include "pagesize.h"
+#include <gnuradio/sys_paths.h>
+
+namespace gr {
+
+ vmcircbuf_mmap_tmpfile::vmcircbuf_mmap_tmpfile (int size)
+ : gr::vmcircbuf (size)
+ {
+#if !defined(HAVE_MMAP)
+ fprintf(stderr, "gr::vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+#else
+
+ if(size <= 0 || (size % gr::pagesize ()) != 0) {
+ fprintf(stderr, "gr::vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ int seg_fd = -1;
+ char seg_name[1024];
+
+ static int s_seg_counter = 0;
+
+ // open a temporary file that we'll map in a bit later
+ while(1) {
+ snprintf(seg_name, sizeof(seg_name),
+ "%s/gnuradio-%d-%d-XXXXXX", gr::tmp_path(), getpid(), s_seg_counter);
+ s_seg_counter++;
+
+ seg_fd = open(seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+ if(seg_fd == -1) {
+ if(errno == EEXIST) // File already exists (shouldn't happen). Try again
+ continue;
+
+ char msg[1024];
+ snprintf(msg, sizeof (msg),
+ "gr::vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
+ perror(msg);
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+ break;
+ }
+
+ if(unlink (seg_name) == -1) {
+ perror("gr::vmcircbuf_mmap_tmpfile: unlink");
+ throw std::runtime_error ("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ // We've got a valid file descriptor to a tmp file.
+ // Now set it's length to 2x what we really want and mmap it in.
+ if(ftruncate (seg_fd, (off_t) 2 * size) == -1) {
+ close(seg_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_tmpfile: ftruncate (1)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ void *first_copy = mmap(0, 2 * size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t)0);
+
+ if(first_copy == MAP_FAILED) {
+ close(seg_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_tmpfile: mmap (1)");
+ throw std::runtime_error ("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ // unmap the 2nd half
+ if(munmap ((char *) first_copy + size, size) == -1) {
+ close(seg_fd); // cleanup
+ perror("gr::vmcircbuf_mmap_tmpfile: munmap (1)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ // map the first half into the now available hole where the
+ // second half used to be.
+ void *second_copy = mmap((char*)first_copy + size, size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ seg_fd, (off_t)0);
+
+ if(second_copy == MAP_FAILED) {
+ munmap(first_copy, size); // cleanup
+ close(seg_fd);
+ perror("gr::vmcircbuf_mmap_tmpfile: mmap(2)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ // check for contiguity
+ if((char*)second_copy != (char*)first_copy + size) {
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close(seg_fd);
+ perror("gr::vmcircbuf_mmap_tmpfile: non-contiguous second copy");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ // cut the tmp file down to size
+ if(ftruncate (seg_fd, (off_t) size) == -1) {
+ munmap(first_copy, size); // cleanup
+ munmap(second_copy, size);
+ close(seg_fd);
+ perror("gr::vmcircbuf_mmap_tmpfile: ftruncate (2)");
+ throw std::runtime_error("gr::vmcircbuf_mmap_tmpfile");
+ }
+
+ close(seg_fd); // fd no longer needed. The mapping is retained.
+
+ // Now remember the important stuff
+
+ d_base = (char*)first_copy;
+ d_size = size;
+#endif
+ }
+
+ vmcircbuf_mmap_tmpfile::~vmcircbuf_mmap_tmpfile()
+ {
+#if defined(HAVE_MMAP)
+ if(munmap(d_base, 2 * d_size) == -1) {
+ perror("gr::vmcircbuf_mmap_tmpfile: munmap(2)");
+ }
+#endif
+ }
+
+ // ----------------------------------------------------------------
+ // The factory interface
+ // ----------------------------------------------------------------
+
+ gr::vmcircbuf_factory *vmcircbuf_mmap_tmpfile_factory::s_the_factory = 0;
+
+ gr::vmcircbuf_factory *
+ vmcircbuf_mmap_tmpfile_factory::singleton()
+ {
+ if(s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr::vmcircbuf_mmap_tmpfile_factory();
+ return s_the_factory;
+ }
+
+ int
+ vmcircbuf_mmap_tmpfile_factory::granularity()
+ {
+ return gr::pagesize();
+ }
+
+ gr::vmcircbuf *
+ vmcircbuf_mmap_tmpfile_factory::make(int size)
+ {
+ try {
+ return new vmcircbuf_mmap_tmpfile(size);
+ }
+ catch (...) {
+ return 0;
+ }
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.h b/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.h
new file mode 100644
index 0000000000..f8959c5736
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_mmap_tmpfile.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifndef GR_VMCIRCBUF_MMAP_TMPFILE_H
+#define GR_VMCIRCBUF_MMAP_TMPFILE_H
+
+#include <gnuradio/api.h>
+#include "vmcircbuf.h"
+
+namespace gr {
+
+ /*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API vmcircbuf_mmap_tmpfile : public gr::vmcircbuf
+ {
+ public:
+ vmcircbuf_mmap_tmpfile(int size);
+ virtual ~vmcircbuf_mmap_tmpfile();
+ };
+
+ /*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+ class GR_RUNTIME_API vmcircbuf_mmap_tmpfile_factory : public gr::vmcircbuf_factory
+ {
+ private:
+ static gr::vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr::vmcircbuf_factory *singleton();
+
+ virtual const char *name() const { return "gr::vmcircbuf_mmap_tmpfile_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity();
+
+ /*!
+ * \brief return a gr::vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr::vmcircbuf *make(int size);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_VMCIRCBUF_MMAP_TMPFILE_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf_prefs.cc b/gnuradio-runtime/lib/vmcircbuf_prefs.cc
new file mode 100644
index 0000000000..1fa6350385
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_prefs.cc
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,2010,2011,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmcircbuf_prefs.h"
+#include <gnuradio/sys_paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+namespace fs = boost::filesystem;
+
+namespace gr {
+
+ /*
+ * The simplest thing that could possibly work:
+ * the key is the filename; the value is the file contents.
+ */
+ static const char *
+ pathname(const char *key)
+ {
+ static fs::path path;
+ path = fs::path(gr::appdata_path()) / ".gnuradio" / "prefs" / key;
+ return path.string().c_str();
+ }
+
+ static void
+ ensure_dir_path()
+ {
+ fs::path path = fs::path(gr::appdata_path()) / ".gnuradio";
+ if(!fs::is_directory(path))
+ fs::create_directory(path);
+
+ path = path / "prefs";
+ if(!fs::is_directory(path))
+ fs::create_directory(path);
+ }
+
+ const char *
+ vmcircbuf_prefs::get(const char *key)
+ {
+ static char buf[1024];
+
+ FILE *fp = fopen(pathname (key), "r");
+ if(fp == 0) {
+ perror(pathname (key));
+ return 0;
+ }
+
+ memset(buf, 0, sizeof (buf));
+ size_t ret = fread(buf, 1, sizeof(buf) - 1, fp);
+ if(ret == 0) {
+ if(ferror(fp) != 0) {
+ perror(pathname (key));
+ fclose(fp);
+ return 0;
+ }
+ }
+ fclose(fp);
+ return buf;
+ }
+
+ void
+ vmcircbuf_prefs::set(const char *key, const char *value)
+ {
+ ensure_dir_path();
+
+ FILE *fp = fopen(pathname(key), "w");
+ if(fp == 0) {
+ perror(pathname (key));
+ return;
+ }
+
+ size_t ret = fwrite(value, 1, strlen(value), fp);
+ if(ret == 0) {
+ if(ferror(fp) != 0) {
+ perror(pathname (key));
+ fclose(fp);
+ return;
+ }
+ }
+ fclose(fp);
+ };
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/gri_debugger_hook.h b/gnuradio-runtime/lib/vmcircbuf_prefs.h
index 6d31ed1b2c..709b8ff459 100644
--- a/gnuradio-runtime/lib/gri_debugger_hook.h
+++ b/gnuradio-runtime/lib/vmcircbuf_prefs.h
@@ -1,6 +1,6 @@
/* -*- c++ -*- */
/*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2003,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -20,11 +20,20 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GRI_DEBUGGER_HOOK_H
-#define INCLUDED_GRI_DEBUGGER_HOOK_H
+#ifndef GR_PREFERENCES_H
+#define GR_PREFERENCES_H
-#include <gr_runtime_api.h>
+#include <gnuradio/api.h>
-GR_RUNTIME_API void gri_debugger_hook ();
+namespace gr {
-#endif /* INCLUDED_GRI_DEBUGGER_HOOK_H */ \ No newline at end of file
+ class GR_RUNTIME_API vmcircbuf_prefs
+ {
+ public:
+ static const char *get(const char *key);
+ static void set(const char *key, const char *value);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_PREFERENCES_H */
diff --git a/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc
new file mode 100644
index 0000000000..0d7e9b7d34
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.cc
@@ -0,0 +1,196 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vmcircbuf_sysv_shm.h"
+#include <stdexcept>
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_IPC_H
+#include <sys/ipc.h>
+#endif
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include "pagesize.h"
+
+
+namespace gr {
+
+ vmcircbuf_sysv_shm::vmcircbuf_sysv_shm(int size)
+ : gr::vmcircbuf(size)
+ {
+#if !defined(HAVE_SYS_SHM_H)
+ fprintf(stderr, "gr::vmcircbuf_sysv_shm: sysv shared memory is not available\n");
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+#else
+
+ int pagesize = gr::pagesize();
+
+ if(size <= 0 || (size % pagesize) != 0) {
+ fprintf(stderr, "gr::vmcircbuf_sysv_shm: invalid size = %d\n", size);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ int shmid_guard = -1;
+ int shmid1 = -1;
+ int shmid2 = -1;
+
+ // We use this as a guard page. We'll map it read-only on both ends of the buffer.
+ // Ideally we'd map it no access, but I don't think that's possible with SysV
+ if((shmid_guard = shmget(IPC_PRIVATE, pagesize, IPC_CREAT | 0400)) == -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmget (0)");
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ if((shmid2 = shmget(IPC_PRIVATE, 2 * size + 2 * pagesize, IPC_CREAT | 0700)) == -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmget(1)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ throw std::runtime_error ("gr::vmcircbuf_sysv_shm");
+ }
+
+ if((shmid1 = shmget(IPC_PRIVATE, size, IPC_CREAT | 0700)) == -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmget (2)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid2, IPC_RMID, 0);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ void *first_copy = shmat (shmid2, 0, 0);
+ if(first_copy == (void *) -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmat(1)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid2, IPC_RMID, 0);
+ shmctl(shmid1, IPC_RMID, 0);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ shmctl(shmid2, IPC_RMID, 0);
+
+ // There may be a race between our detach and attach.
+ //
+ // If the system allocates all shared memory segments at the same
+ // virtual addresses in all processes and if the system allocates
+ // some other segment to first_copy or first_copoy + size between
+ // our detach and attach, the attaches below could fail [I've never
+ // seen it fail for this reason].
+ shmdt(first_copy);
+
+ // first read-only guard page
+ if(shmat(shmid_guard, first_copy, SHM_RDONLY) == (void *) -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmat(2)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid1, IPC_RMID, 0);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ // first copy
+ if(shmat (shmid1, (char*)first_copy + pagesize, 0) == (void *) -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmat (3)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid1, IPC_RMID, 0);
+ shmdt(first_copy);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ // second copy
+ if(shmat (shmid1, (char*)first_copy + pagesize + size, 0) == (void *) -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmat (4)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid1, IPC_RMID, 0);
+ shmdt((char *)first_copy + pagesize);
+ throw std::runtime_error("gr::vmcircbuf_sysv_shm");
+ }
+
+ // second read-only guard page
+ if(shmat(shmid_guard, (char*)first_copy + pagesize + 2 * size, SHM_RDONLY) == (void *) -1) {
+ perror("gr::vmcircbuf_sysv_shm: shmat(5)");
+ shmctl(shmid_guard, IPC_RMID, 0);
+ shmctl(shmid1, IPC_RMID, 0);
+ shmdt(first_copy);
+ shmdt((char *)first_copy + pagesize);
+ shmdt((char *)first_copy + pagesize + size);
+ throw std::runtime_error ("gr::vmcircbuf_sysv_shm");
+ }
+
+ shmctl(shmid1, IPC_RMID, 0);
+ shmctl(shmid_guard, IPC_RMID, 0);
+
+ // Now remember the important stuff
+ d_base = (char*)first_copy + pagesize;
+ d_size = size;
+#endif
+ }
+
+ vmcircbuf_sysv_shm::~vmcircbuf_sysv_shm()
+ {
+#if defined(HAVE_SYS_SHM_H)
+ if(shmdt(d_base - gr::pagesize()) == -1
+ || shmdt(d_base) == -1
+ || shmdt(d_base + d_size) == -1
+ || shmdt(d_base + 2 * d_size) == -1){
+ perror("gr::vmcircbuf_sysv_shm: shmdt(2)");
+ }
+#endif
+ }
+
+ // ----------------------------------------------------------------
+ // The factory interface
+ // ----------------------------------------------------------------
+
+ gr::vmcircbuf_factory *vmcircbuf_sysv_shm_factory::s_the_factory = 0;
+
+ gr::vmcircbuf_factory *
+ vmcircbuf_sysv_shm_factory::singleton()
+ {
+ if(s_the_factory)
+ return s_the_factory;
+
+ s_the_factory = new gr::vmcircbuf_sysv_shm_factory();
+ return s_the_factory;
+ }
+
+ int
+ vmcircbuf_sysv_shm_factory::granularity()
+ {
+ return gr::pagesize();
+ }
+
+ gr::vmcircbuf *
+ vmcircbuf_sysv_shm_factory::make(int size)
+ {
+ try {
+ return new vmcircbuf_sysv_shm(size);
+ }
+ catch (...) {
+ return 0;
+ }
+ }
+
+} /* namespace gr */
diff --git a/gnuradio-runtime/lib/vmcircbuf_sysv_shm.h b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.h
new file mode 100644
index 0000000000..08e0040bf1
--- /dev/null
+++ b/gnuradio-runtime/lib/vmcircbuf_sysv_shm.h
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2003 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 GR_VMCIRCBUF_SYSV_SHM_H
+#define GR_VMCIRCBUF_SYSV_SHM_H
+
+#include <gnuradio/api.h>
+#include "vmcircbuf.h"
+
+namespace gr {
+
+ /*!
+ * \brief concrete class to implement circular buffers with mmap and shm_open
+ * \ingroup internal
+ */
+ class GR_RUNTIME_API vmcircbuf_sysv_shm : public gr::vmcircbuf
+ {
+ public:
+ vmcircbuf_sysv_shm(int size);
+ virtual ~vmcircbuf_sysv_shm();
+ };
+
+ /*!
+ * \brief concrete factory for circular buffers built using mmap and shm_open
+ */
+ class GR_RUNTIME_API vmcircbuf_sysv_shm_factory : public gr::vmcircbuf_factory
+ {
+ private:
+ static gr::vmcircbuf_factory *s_the_factory;
+
+ public:
+ static gr::vmcircbuf_factory *singleton();
+
+ virtual const char *name() const { return "gr::vmcircbuf_sysv_shm_factory"; }
+
+ /*!
+ * \brief return granularity of mapping, typically equal to page size
+ */
+ virtual int granularity();
+
+ /*!
+ * \brief return a gr::vmcircbuf, or 0 if unable.
+ *
+ * Call this to create a doubly mapped circular buffer.
+ */
+ virtual gr::vmcircbuf *make(int size);
+ };
+
+} /* namespace gr */
+
+#endif /* GR_VMCIRCBUF_SYSV_SHM_H */