runtime: import minimal gr runtime for standalone mode (wip)
stripped pmt and message infrastructure, no logging, no nothing...
This commit is contained in:
parent
9dfe3a6354
commit
be1314af10
|
@ -97,6 +97,7 @@ MESSAGE(STATUS "Configuring Boost C++ Libraries...")
|
|||
SET(BOOST_REQUIRED_COMPONENTS
|
||||
thread
|
||||
system
|
||||
filesystem
|
||||
)
|
||||
|
||||
if(UNIX AND NOT BOOST_ROOT AND EXISTS "/usr/lib64")
|
||||
|
@ -140,6 +141,26 @@ set(GR_LIBEXEC_DIR libexec)
|
|||
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
|
||||
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
|
||||
|
||||
# Special exception if prefix is /usr so we don't make a /usr/etc.
|
||||
string(COMPARE EQUAL ${CMAKE_INSTALL_PREFIX} "/usr" isusr)
|
||||
if(isusr)
|
||||
set(SYSCONFDIR "/${GR_CONF_DIR}" CACHE PATH "System configuration directory")
|
||||
else(isusr)
|
||||
set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/${GR_CONF_DIR}" CACHE PATH "System configuration directory" FORCE)
|
||||
endif(isusr)
|
||||
|
||||
set(GR_PREFSDIR ${SYSCONFDIR}/${CMAKE_PROJECT_NAME}/conf.d)
|
||||
|
||||
########################################################################
|
||||
# Variables replaced when configuring the package config files
|
||||
########################################################################
|
||||
file(TO_NATIVE_PATH "${CMAKE_INSTALL_PREFIX}" prefix)
|
||||
file(TO_NATIVE_PATH "\${prefix}" exec_prefix)
|
||||
file(TO_NATIVE_PATH "\${exec_prefix}/${GR_LIBRARY_DIR}" libdir)
|
||||
file(TO_NATIVE_PATH "\${prefix}/${GR_INCLUDE_DIR}" includedir)
|
||||
file(TO_NATIVE_PATH "${SYSCONFDIR}" SYSCONFDIR)
|
||||
file(TO_NATIVE_PATH "${GR_PREFSDIR}" GR_PREFSDIR)
|
||||
|
||||
########################################################################
|
||||
# Find build dependencies
|
||||
########################################################################
|
||||
|
@ -157,9 +178,41 @@ find_package(LibHackRF)
|
|||
find_package(LibbladeRF)
|
||||
find_package(Doxygen)
|
||||
|
||||
set(PYTHON_RUNTIME_CHECK TRUE)
|
||||
|
||||
if(NOT GNURADIO_RUNTIME_FOUND)
|
||||
message(FATAL_ERROR "GnuRadio Runtime required to build " ${CMAKE_PROJECT_NAME})
|
||||
endif()
|
||||
message(STATUS "Enabling built-in GNU Radio runtime...")
|
||||
set(RUNTIME_MODE TRUE CACHE INTERNAL "Built-in GNU Radio runtime")
|
||||
|
||||
add_subdirectory(include/osmosdr/runtime)
|
||||
|
||||
set(GNURADIO_RUNTIME_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/include/osmosdr/runtime)
|
||||
set(GNURADIO_RUNTIME_LIBRARY_DIRS "")
|
||||
set(GNURADIO_RUNTIME_LIBRARIES "")
|
||||
|
||||
set(GNURADIO_PMT_INCLUDE_DIRS "")
|
||||
set(GNURADIO_PMT_LIBRARY_DIRS "")
|
||||
set(GNURADIO_PMT_LIBRARIES "")
|
||||
|
||||
set(GNURADIO_BLOCKS_INCLUDE_DIRS "")
|
||||
set(GNURADIO_BLOCKS_LIBRARY_DIRS "")
|
||||
set(GNURADIO_BLOCKS_LIBRARIES "")
|
||||
|
||||
LIST(APPEND GR_OSMOSDR_PC_CFLAGS "-I\${includedir}/osmosdr/runtime")
|
||||
|
||||
# disable python bindings as long as we don't have any swig files for the runtime
|
||||
set(PYTHON_RUNTIME_CHECK FALSE)
|
||||
endif(NOT GNURADIO_RUNTIME_FOUND)
|
||||
|
||||
if(GNURADIO_RUNTIME_FOUND)
|
||||
LIST(APPEND GR_OSMOSDR_PC_REQUIRES "gnuradio-runtime")
|
||||
endif(GNURADIO_RUNTIME_FOUND)
|
||||
if(GNURADIO_PMT_FOUND)
|
||||
LIST(APPEND GR_OSMOSDR_PC_REQUIRES "gnuradio-pmt")
|
||||
endif(GNURADIO_PMT_FOUND)
|
||||
if(GNURADIO_BLOCKS_FOUND)
|
||||
LIST(APPEND GR_OSMOSDR_PC_REQUIRES "gnuradio-blocks")
|
||||
endif(GNURADIO_BLOCKS_FOUND)
|
||||
|
||||
########################################################################
|
||||
# Setup the include and linker paths
|
||||
|
@ -211,10 +264,11 @@ if(SWIG_FOUND)
|
|||
endif(SWIG_FOUND)
|
||||
|
||||
include(GrComponent)
|
||||
GR_REGISTER_COMPONENT("Python support" ENABLE_PYTHON
|
||||
GR_REGISTER_COMPONENT("Python bindings" ENABLE_PYTHON
|
||||
PYTHONLIBS_FOUND
|
||||
SWIG_FOUND
|
||||
SWIG_VERSION_CHECK
|
||||
PYTHON_RUNTIME_CHECK
|
||||
)
|
||||
|
||||
########################################################################
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_CONFIG_H_ // [
|
||||
#define _MSC_CONFIG_H_
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// enable inline functions for C code
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifndef __cplusplus
|
||||
# define inline __inline
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// signed size_t
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include <stddef.h>
|
||||
typedef ptrdiff_t ssize_t;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// rint functions
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include <math.h>
|
||||
static inline long lrint(double x){return (long)(x > 0.0 ? x + 0.5 : x - 0.5);}
|
||||
static inline long lrintf(float x){return (long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
|
||||
static inline long long llrint(double x){return (long long)(x > 0.0 ? x + 0.5 : x - 0.5);}
|
||||
static inline long long llrintf(float x){return (long long)(x > 0.0f ? x + 0.5f : x - 0.5f);}
|
||||
static inline double rint(double x){return (x > 0.0)? floor(x + 0.5) : ceil(x - 0.5);}
|
||||
static inline float rintf(float x){return (x > 0.0f)? floorf(x + 0.5f) : ceilf(x - 0.5f);}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// math constants
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#define INFINITY HUGE_VAL
|
||||
|
||||
# define M_E 2.7182818284590452354 /* e */
|
||||
# define M_LOG2E 1.4426950408889634074 /* log_2 e */
|
||||
# define M_LOG10E 0.43429448190325182765 /* log_10 e */
|
||||
# define M_LN2 0.69314718055994530942 /* log_e 2 */
|
||||
# define M_LN10 2.30258509299404568402 /* log_e 10 */
|
||||
# define M_PI 3.14159265358979323846 /* pi */
|
||||
# define M_PI_2 1.57079632679489661923 /* pi/2 */
|
||||
# define M_PI_4 0.78539816339744830962 /* pi/4 */
|
||||
# define M_1_PI 0.31830988618379067154 /* 1/pi */
|
||||
# define M_2_PI 0.63661977236758134308 /* 2/pi */
|
||||
# define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
|
||||
# define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
|
||||
# define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// random and srandom
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include <stdlib.h>
|
||||
static inline long int random (void) { return rand(); }
|
||||
static inline void srandom (unsigned int seed) { srand(seed); }
|
||||
|
||||
#endif // _MSC_CONFIG_H_ ]
|
|
@ -0,0 +1,301 @@
|
|||
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006 Alexander Chemeris
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The name of the author may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_INTTYPES_H_ // [
|
||||
#define _MSC_INTTYPES_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// 7.8 Format conversion of integer types
|
||||
|
||||
typedef struct {
|
||||
intmax_t quot;
|
||||
intmax_t rem;
|
||||
} imaxdiv_t;
|
||||
|
||||
// 7.8.1 Macros for format specifiers
|
||||
|
||||
// The fprintf macros for signed integers are:
|
||||
#define PRId8 "d"
|
||||
#define PRIi8 "i"
|
||||
#define PRIdLEAST8 "d"
|
||||
#define PRIiLEAST8 "i"
|
||||
#define PRIdFAST8 "d"
|
||||
#define PRIiFAST8 "i"
|
||||
|
||||
#define PRId16 "hd"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIdLEAST16 "hd"
|
||||
#define PRIiLEAST16 "hi"
|
||||
#define PRIdFAST16 "hd"
|
||||
#define PRIiFAST16 "hi"
|
||||
|
||||
#define PRId32 "I32d"
|
||||
#define PRIi32 "I32i"
|
||||
#define PRIdLEAST32 "I32d"
|
||||
#define PRIiLEAST32 "I32i"
|
||||
#define PRIdFAST32 "I32d"
|
||||
#define PRIiFAST32 "I32i"
|
||||
|
||||
#define PRId64 "I64d"
|
||||
#define PRIi64 "I64i"
|
||||
#define PRIdLEAST64 "I64d"
|
||||
#define PRIiLEAST64 "I64i"
|
||||
#define PRIdFAST64 "I64d"
|
||||
#define PRIiFAST64 "I64i"
|
||||
|
||||
#define PRIdMAX "I64d"
|
||||
#define PRIiMAX "I64i"
|
||||
|
||||
#define PRIdPTR "Id"
|
||||
#define PRIiPTR "Ii"
|
||||
|
||||
// The fprintf macros for unsigned integers are:
|
||||
#define PRIo8 "o"
|
||||
#define PRIu8 "u"
|
||||
#define PRIx8 "x"
|
||||
#define PRIX8 "X"
|
||||
#define PRIoLEAST8 "o"
|
||||
#define PRIuLEAST8 "u"
|
||||
#define PRIxLEAST8 "x"
|
||||
#define PRIXLEAST8 "X"
|
||||
#define PRIoFAST8 "o"
|
||||
#define PRIuFAST8 "u"
|
||||
#define PRIxFAST8 "x"
|
||||
#define PRIXFAST8 "X"
|
||||
|
||||
#define PRIo16 "ho"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIX16 "hX"
|
||||
#define PRIoLEAST16 "ho"
|
||||
#define PRIuLEAST16 "hu"
|
||||
#define PRIxLEAST16 "hx"
|
||||
#define PRIXLEAST16 "hX"
|
||||
#define PRIoFAST16 "ho"
|
||||
#define PRIuFAST16 "hu"
|
||||
#define PRIxFAST16 "hx"
|
||||
#define PRIXFAST16 "hX"
|
||||
|
||||
#define PRIo32 "I32o"
|
||||
#define PRIu32 "I32u"
|
||||
#define PRIx32 "I32x"
|
||||
#define PRIX32 "I32X"
|
||||
#define PRIoLEAST32 "I32o"
|
||||
#define PRIuLEAST32 "I32u"
|
||||
#define PRIxLEAST32 "I32x"
|
||||
#define PRIXLEAST32 "I32X"
|
||||
#define PRIoFAST32 "I32o"
|
||||
#define PRIuFAST32 "I32u"
|
||||
#define PRIxFAST32 "I32x"
|
||||
#define PRIXFAST32 "I32X"
|
||||
|
||||
#define PRIo64 "I64o"
|
||||
#define PRIu64 "I64u"
|
||||
#define PRIx64 "I64x"
|
||||
#define PRIX64 "I64X"
|
||||
#define PRIoLEAST64 "I64o"
|
||||
#define PRIuLEAST64 "I64u"
|
||||
#define PRIxLEAST64 "I64x"
|
||||
#define PRIXLEAST64 "I64X"
|
||||
#define PRIoFAST64 "I64o"
|
||||
#define PRIuFAST64 "I64u"
|
||||
#define PRIxFAST64 "I64x"
|
||||
#define PRIXFAST64 "I64X"
|
||||
|
||||
#define PRIoMAX "I64o"
|
||||
#define PRIuMAX "I64u"
|
||||
#define PRIxMAX "I64x"
|
||||
#define PRIXMAX "I64X"
|
||||
|
||||
#define PRIoPTR "Io"
|
||||
#define PRIuPTR "Iu"
|
||||
#define PRIxPTR "Ix"
|
||||
#define PRIXPTR "IX"
|
||||
|
||||
// The fscanf macros for signed integers are:
|
||||
#define SCNd8 "d"
|
||||
#define SCNi8 "i"
|
||||
#define SCNdLEAST8 "d"
|
||||
#define SCNiLEAST8 "i"
|
||||
#define SCNdFAST8 "d"
|
||||
#define SCNiFAST8 "i"
|
||||
|
||||
#define SCNd16 "hd"
|
||||
#define SCNi16 "hi"
|
||||
#define SCNdLEAST16 "hd"
|
||||
#define SCNiLEAST16 "hi"
|
||||
#define SCNdFAST16 "hd"
|
||||
#define SCNiFAST16 "hi"
|
||||
|
||||
#define SCNd32 "ld"
|
||||
#define SCNi32 "li"
|
||||
#define SCNdLEAST32 "ld"
|
||||
#define SCNiLEAST32 "li"
|
||||
#define SCNdFAST32 "ld"
|
||||
#define SCNiFAST32 "li"
|
||||
|
||||
#define SCNd64 "I64d"
|
||||
#define SCNi64 "I64i"
|
||||
#define SCNdLEAST64 "I64d"
|
||||
#define SCNiLEAST64 "I64i"
|
||||
#define SCNdFAST64 "I64d"
|
||||
#define SCNiFAST64 "I64i"
|
||||
|
||||
#define SCNdMAX "I64d"
|
||||
#define SCNiMAX "I64i"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNdPTR "I64d"
|
||||
# define SCNiPTR "I64i"
|
||||
#else // _WIN64 ][
|
||||
# define SCNdPTR "ld"
|
||||
# define SCNiPTR "li"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// The fscanf macros for unsigned integers are:
|
||||
#define SCNo8 "o"
|
||||
#define SCNu8 "u"
|
||||
#define SCNx8 "x"
|
||||
#define SCNX8 "X"
|
||||
#define SCNoLEAST8 "o"
|
||||
#define SCNuLEAST8 "u"
|
||||
#define SCNxLEAST8 "x"
|
||||
#define SCNXLEAST8 "X"
|
||||
#define SCNoFAST8 "o"
|
||||
#define SCNuFAST8 "u"
|
||||
#define SCNxFAST8 "x"
|
||||
#define SCNXFAST8 "X"
|
||||
|
||||
#define SCNo16 "ho"
|
||||
#define SCNu16 "hu"
|
||||
#define SCNx16 "hx"
|
||||
#define SCNX16 "hX"
|
||||
#define SCNoLEAST16 "ho"
|
||||
#define SCNuLEAST16 "hu"
|
||||
#define SCNxLEAST16 "hx"
|
||||
#define SCNXLEAST16 "hX"
|
||||
#define SCNoFAST16 "ho"
|
||||
#define SCNuFAST16 "hu"
|
||||
#define SCNxFAST16 "hx"
|
||||
#define SCNXFAST16 "hX"
|
||||
|
||||
#define SCNo32 "lo"
|
||||
#define SCNu32 "lu"
|
||||
#define SCNx32 "lx"
|
||||
#define SCNX32 "lX"
|
||||
#define SCNoLEAST32 "lo"
|
||||
#define SCNuLEAST32 "lu"
|
||||
#define SCNxLEAST32 "lx"
|
||||
#define SCNXLEAST32 "lX"
|
||||
#define SCNoFAST32 "lo"
|
||||
#define SCNuFAST32 "lu"
|
||||
#define SCNxFAST32 "lx"
|
||||
#define SCNXFAST32 "lX"
|
||||
|
||||
#define SCNo64 "I64o"
|
||||
#define SCNu64 "I64u"
|
||||
#define SCNx64 "I64x"
|
||||
#define SCNX64 "I64X"
|
||||
#define SCNoLEAST64 "I64o"
|
||||
#define SCNuLEAST64 "I64u"
|
||||
#define SCNxLEAST64 "I64x"
|
||||
#define SCNXLEAST64 "I64X"
|
||||
#define SCNoFAST64 "I64o"
|
||||
#define SCNuFAST64 "I64u"
|
||||
#define SCNxFAST64 "I64x"
|
||||
#define SCNXFAST64 "I64X"
|
||||
|
||||
#define SCNoMAX "I64o"
|
||||
#define SCNuMAX "I64u"
|
||||
#define SCNxMAX "I64x"
|
||||
#define SCNXMAX "I64X"
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define SCNoPTR "I64o"
|
||||
# define SCNuPTR "I64u"
|
||||
# define SCNxPTR "I64x"
|
||||
# define SCNXPTR "I64X"
|
||||
#else // _WIN64 ][
|
||||
# define SCNoPTR "lo"
|
||||
# define SCNuPTR "lu"
|
||||
# define SCNxPTR "lx"
|
||||
# define SCNXPTR "lX"
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.8.2 Functions for greatest-width integer types
|
||||
|
||||
// 7.8.2.1 The imaxabs function
|
||||
#define imaxabs _abs64
|
||||
|
||||
// 7.8.2.2 The imaxdiv function
|
||||
|
||||
// This is modified version of div() function from Microsoft's div.c found
|
||||
// in %MSVC.NET%\crt\src\div.c
|
||||
#ifdef STATIC_IMAXDIV // [
|
||||
static
|
||||
#else // STATIC_IMAXDIV ][
|
||||
_inline
|
||||
#endif // STATIC_IMAXDIV ]
|
||||
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
|
||||
{
|
||||
imaxdiv_t result;
|
||||
|
||||
result.quot = numer / denom;
|
||||
result.rem = numer % denom;
|
||||
|
||||
if (numer < 0 && result.rem > 0) {
|
||||
// did division wrong; must fix up
|
||||
++result.quot;
|
||||
result.rem -= denom;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 7.8.2.3 The strtoimax and strtoumax functions
|
||||
#define strtoimax _strtoi64
|
||||
#define strtoumax _strtoui64
|
||||
|
||||
// 7.8.2.4 The wcstoimax and wcstoumax functions
|
||||
#define wcstoimax _wcstoi64
|
||||
#define wcstoumax _wcstoui64
|
||||
|
||||
|
||||
#endif // _MSC_INTTYPES_H_ ]
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2005, 2006 Apple Computer, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public License
|
||||
* along with this library; see the file COPYING.LIB. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STDBOOL_WIN32_H
|
||||
#define STDBOOL_WIN32_H
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
typedef unsigned char bool;
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#ifndef CASSERT
|
||||
#define CASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
|
||||
#endif
|
||||
|
||||
CASSERT(sizeof(bool) == 1, bool_is_one_byte)
|
||||
CASSERT(true, true_is_true)
|
||||
CASSERT(!false, false_is_false)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,251 @@
|
|||
// ISO C9x compliant stdint.h for Microsoft Visual Studio
|
||||
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
|
||||
//
|
||||
// Copyright (c) 2006-2008 Alexander Chemeris
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. The name of the author may be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_STDINT_H_ // [
|
||||
#define _MSC_STDINT_H_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
|
||||
// or compiler give many errors like this:
|
||||
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
# include <wchar.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Define _W64 macros to mark types changing their size, like intptr_t.
|
||||
#ifndef _W64
|
||||
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
|
||||
# define _W64 __w64
|
||||
# else
|
||||
# define _W64
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
// 7.18.1 Integer types
|
||||
|
||||
// 7.18.1.1 Exact-width integer types
|
||||
|
||||
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
|
||||
// realize that, e.g. char has the same size as __int8
|
||||
// so we give up on __intX for them.
|
||||
#if (_MSC_VER < 1300)
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef signed __int8 int8_t;
|
||||
typedef signed __int16 int16_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
#endif
|
||||
typedef signed __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
|
||||
// 7.18.1.2 Minimum-width integer types
|
||||
typedef int8_t int_least8_t;
|
||||
typedef int16_t int_least16_t;
|
||||
typedef int32_t int_least32_t;
|
||||
typedef int64_t int_least64_t;
|
||||
typedef uint8_t uint_least8_t;
|
||||
typedef uint16_t uint_least16_t;
|
||||
typedef uint32_t uint_least32_t;
|
||||
typedef uint64_t uint_least64_t;
|
||||
|
||||
// 7.18.1.3 Fastest minimum-width integer types
|
||||
typedef int8_t int_fast8_t;
|
||||
typedef int16_t int_fast16_t;
|
||||
typedef int32_t int_fast32_t;
|
||||
typedef int64_t int_fast64_t;
|
||||
typedef uint8_t uint_fast8_t;
|
||||
typedef uint16_t uint_fast16_t;
|
||||
typedef uint32_t uint_fast32_t;
|
||||
typedef uint64_t uint_fast64_t;
|
||||
|
||||
// 7.18.1.4 Integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
typedef signed __int64 intptr_t;
|
||||
typedef unsigned __int64 uintptr_t;
|
||||
#else // _WIN64 ][
|
||||
typedef _W64 signed int intptr_t;
|
||||
typedef _W64 unsigned int uintptr_t;
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.1.5 Greatest-width integer types
|
||||
typedef int64_t intmax_t;
|
||||
typedef uint64_t uintmax_t;
|
||||
|
||||
|
||||
// 7.18.2 Limits of specified-width integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
|
||||
|
||||
// 7.18.2.1 Limits of exact-width integer types
|
||||
#define INT8_MIN ((int8_t)_I8_MIN)
|
||||
#define INT8_MAX _I8_MAX
|
||||
#define INT16_MIN ((int16_t)_I16_MIN)
|
||||
#define INT16_MAX _I16_MAX
|
||||
#define INT32_MIN ((int32_t)_I32_MIN)
|
||||
#define INT32_MAX _I32_MAX
|
||||
#define INT64_MIN ((int64_t)_I64_MIN)
|
||||
#define INT64_MAX _I64_MAX
|
||||
#define UINT8_MAX _UI8_MAX
|
||||
#define UINT16_MAX _UI16_MAX
|
||||
#define UINT32_MAX _UI32_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
||||
// 7.18.2.2 Limits of minimum-width integer types
|
||||
#define INT_LEAST8_MIN INT8_MIN
|
||||
#define INT_LEAST8_MAX INT8_MAX
|
||||
#define INT_LEAST16_MIN INT16_MIN
|
||||
#define INT_LEAST16_MAX INT16_MAX
|
||||
#define INT_LEAST32_MIN INT32_MIN
|
||||
#define INT_LEAST32_MAX INT32_MAX
|
||||
#define INT_LEAST64_MIN INT64_MIN
|
||||
#define INT_LEAST64_MAX INT64_MAX
|
||||
#define UINT_LEAST8_MAX UINT8_MAX
|
||||
#define UINT_LEAST16_MAX UINT16_MAX
|
||||
#define UINT_LEAST32_MAX UINT32_MAX
|
||||
#define UINT_LEAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.3 Limits of fastest minimum-width integer types
|
||||
#define INT_FAST8_MIN INT8_MIN
|
||||
#define INT_FAST8_MAX INT8_MAX
|
||||
#define INT_FAST16_MIN INT16_MIN
|
||||
#define INT_FAST16_MAX INT16_MAX
|
||||
#define INT_FAST32_MIN INT32_MIN
|
||||
#define INT_FAST32_MAX INT32_MAX
|
||||
#define INT_FAST64_MIN INT64_MIN
|
||||
#define INT_FAST64_MAX INT64_MAX
|
||||
#define UINT_FAST8_MAX UINT8_MAX
|
||||
#define UINT_FAST16_MAX UINT16_MAX
|
||||
#define UINT_FAST32_MAX UINT32_MAX
|
||||
#define UINT_FAST64_MAX UINT64_MAX
|
||||
|
||||
// 7.18.2.4 Limits of integer types capable of holding object pointers
|
||||
#ifdef _WIN64 // [
|
||||
# define INTPTR_MIN INT64_MIN
|
||||
# define INTPTR_MAX INT64_MAX
|
||||
# define UINTPTR_MAX UINT64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define INTPTR_MIN INT32_MIN
|
||||
# define INTPTR_MAX INT32_MAX
|
||||
# define UINTPTR_MAX UINT32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
// 7.18.2.5 Limits of greatest-width integer types
|
||||
#define INTMAX_MIN INT64_MIN
|
||||
#define INTMAX_MAX INT64_MAX
|
||||
#define UINTMAX_MAX UINT64_MAX
|
||||
|
||||
// 7.18.3 Limits of other integer types
|
||||
|
||||
#ifdef _WIN64 // [
|
||||
# define PTRDIFF_MIN _I64_MIN
|
||||
# define PTRDIFF_MAX _I64_MAX
|
||||
#else // _WIN64 ][
|
||||
# define PTRDIFF_MIN _I32_MIN
|
||||
# define PTRDIFF_MAX _I32_MAX
|
||||
#endif // _WIN64 ]
|
||||
|
||||
#define SIG_ATOMIC_MIN INT_MIN
|
||||
#define SIG_ATOMIC_MAX INT_MAX
|
||||
|
||||
#ifndef SIZE_MAX // [
|
||||
# ifdef _WIN64 // [
|
||||
# define SIZE_MAX _UI64_MAX
|
||||
# else // _WIN64 ][
|
||||
# define SIZE_MAX _UI32_MAX
|
||||
# endif // _WIN64 ]
|
||||
#endif // SIZE_MAX ]
|
||||
|
||||
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
|
||||
#ifndef WCHAR_MIN // [
|
||||
# define WCHAR_MIN 0
|
||||
#endif // WCHAR_MIN ]
|
||||
#ifndef WCHAR_MAX // [
|
||||
# define WCHAR_MAX _UI16_MAX
|
||||
#endif // WCHAR_MAX ]
|
||||
|
||||
#define WINT_MIN 0
|
||||
#define WINT_MAX _UI16_MAX
|
||||
|
||||
#endif // __STDC_LIMIT_MACROS ]
|
||||
|
||||
|
||||
// 7.18.4 Limits of other integer types
|
||||
|
||||
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
|
||||
|
||||
// 7.18.4.1 Macros for minimum-width integer constants
|
||||
|
||||
#define INT8_C(val) val##i8
|
||||
#define INT16_C(val) val##i16
|
||||
#define INT32_C(val) val##i32
|
||||
#define INT64_C(val) val##i64
|
||||
|
||||
#define UINT8_C(val) val##ui8
|
||||
#define UINT16_C(val) val##ui16
|
||||
#define UINT32_C(val) val##ui32
|
||||
#define UINT64_C(val) val##ui64
|
||||
|
||||
// 7.18.4.2 Macros for greatest-width integer constants
|
||||
#ifndef INTMAX_C
|
||||
#define INTMAX_C INT64_C
|
||||
#endif
|
||||
#ifndef UINTMAX_C
|
||||
#define UINTMAX_C UINT64_C
|
||||
#endif
|
||||
|
||||
#endif // __STDC_CONSTANT_MACROS ]
|
||||
|
||||
|
||||
#endif // _MSC_STDINT_H_ ]
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_SYS_TIME_H_
|
||||
#define _MSC_SYS_TIME_H_
|
||||
|
||||
//http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/430449b3-f6dd-4e18-84de-eebd26a8d668
|
||||
#include < time.h >
|
||||
#include <windows.h> //I've ommited this line.
|
||||
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
|
||||
#else
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
#endif
|
||||
|
||||
struct timespec {
|
||||
|
||||
time_t tv_sec; /* Seconds since 00:00:00 GMT, */
|
||||
|
||||
/* 1 January 1970 */
|
||||
|
||||
long tv_nsec; /* Additional nanoseconds since */
|
||||
|
||||
/* tv_sec */
|
||||
|
||||
};
|
||||
|
||||
struct timezone
|
||||
{
|
||||
int tz_minuteswest; /* minutes W of Greenwich */
|
||||
int tz_dsttime; /* type of dst correction */
|
||||
};
|
||||
|
||||
static inline int gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
FILETIME ft;
|
||||
unsigned __int64 tmpres = 0;
|
||||
static int tzflag;
|
||||
|
||||
if (NULL != tv)
|
||||
{
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
|
||||
tmpres |= ft.dwHighDateTime;
|
||||
tmpres <<= 32;
|
||||
tmpres |= ft.dwLowDateTime;
|
||||
|
||||
/*converting file time to unix epoch*/
|
||||
tmpres -= DELTA_EPOCH_IN_MICROSECS;
|
||||
tv->tv_sec = (long)(tmpres / 1000000UL);
|
||||
tv->tv_usec = (long)(tmpres % 1000000UL);
|
||||
}
|
||||
|
||||
if (NULL != tz)
|
||||
{
|
||||
if (!tzflag)
|
||||
{
|
||||
_tzset();
|
||||
tzflag++;
|
||||
}
|
||||
tz->tz_minuteswest = _timezone / 60;
|
||||
tz->tz_dsttime = _daylight;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif //_MSC_SYS_TIME_H_
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef _MSC_VER // [
|
||||
#error "Use this header only with Microsoft Visual C++ compilers!"
|
||||
#endif // _MSC_VER ]
|
||||
|
||||
#ifndef _MSC_UNISTD_H_ // [
|
||||
#define _MSC_UNISTD_H_
|
||||
|
||||
#include <process.h>
|
||||
|
||||
#endif // _MSC_UNISTD_H_ ]
|
|
@ -1,14 +1,14 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/@GR_LIBRARY_DIR@
|
||||
includedir=${prefix}/@GR_INCLUDE_DIR@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: @CPACK_PACKAGE_NAME@
|
||||
Description: @CPACK_PACKAGE_DESCRIPTION_SUMMARY@
|
||||
URL: http://sdr.osmocom.org/trac/wiki/GrOsmoSDR
|
||||
Version: @CPACK_PACKAGE_VERSION@
|
||||
Requires: gnuradio-runtime gnuradio-blocks
|
||||
Requires.private: @GR_OSMOSDR_PC_REQUIRES@
|
||||
Requires: @GR_OSMOSDR_PC_REQUIRES@
|
||||
Requires.private:
|
||||
Conflicts:
|
||||
Cflags: -I${includedir} @GR_OSMOSDR_PC_CFLAGS@
|
||||
Libs: -L${libdir} -lgnuradio-osmosdr
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# Copyright 2011 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU Radio
|
||||
#
|
||||
# GNU Radio is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU Radio is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU Radio; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
########################################################################
|
||||
# Install public header files
|
||||
########################################################################
|
||||
install(FILES
|
||||
gnuradio/blocks/api.h
|
||||
gnuradio/blocks/null_sink.h
|
||||
gnuradio/blocks/null_source.h
|
||||
gnuradio/blocks/throttle.h
|
||||
DESTINATION include/osmosdr/runtime/gnuradio/blocks
|
||||
)
|
||||
|
||||
install(FILES
|
||||
gnuradio/thread/thread.h
|
||||
gnuradio/thread/thread_body_wrapper.h
|
||||
gnuradio/thread/thread_group.h
|
||||
|
||||
DESTINATION include/osmosdr/runtime/gnuradio/thread
|
||||
)
|
||||
|
||||
install(FILES
|
||||
gnuradio/api.h
|
||||
gnuradio/attributes.h
|
||||
gnuradio/basic_block.h
|
||||
gnuradio/block.h
|
||||
gnuradio/block_detail.h
|
||||
gnuradio/block_gateway.h
|
||||
gnuradio/block_registry.h
|
||||
gnuradio/buffer.h
|
||||
gnuradio/constants.h
|
||||
gnuradio/endianness.h
|
||||
gnuradio/expj.h
|
||||
gnuradio/feval.h
|
||||
gnuradio/flowgraph.h
|
||||
gnuradio/fxpt.h
|
||||
gnuradio/fxpt_nco.h
|
||||
gnuradio/fxpt_vco.h
|
||||
gnuradio/gr_complex.h
|
||||
gnuradio/hier_block2.h
|
||||
gnuradio/high_res_timer.h
|
||||
gnuradio/io_signature.h
|
||||
gnuradio/logger.h
|
||||
gnuradio/math.h
|
||||
gnuradio/misc.h
|
||||
gnuradio/prefs.h
|
||||
gnuradio/random.h
|
||||
gnuradio/realtime.h
|
||||
gnuradio/realtime_impl.h
|
||||
gnuradio/runtime_types.h
|
||||
gnuradio/sincos.h
|
||||
gnuradio/sptr_magic.h
|
||||
gnuradio/sync_block.h
|
||||
gnuradio/sync_decimator.h
|
||||
gnuradio/sync_interpolator.h
|
||||
gnuradio/sys_paths.h
|
||||
gnuradio/top_block.h
|
||||
gnuradio/tpb_detail.h
|
||||
gnuradio/types.h
|
||||
DESTINATION include/osmosdr/runtime/gnuradio
|
||||
)
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_RUNTIME_RUNTIME_API_H
|
||||
#define INCLUDED_GR_RUNTIME_RUNTIME_API_H
|
||||
|
||||
#include <gnuradio/attributes.h>
|
||||
|
||||
#ifdef gnuradio_runtime_EXPORTS
|
||||
# define GR_RUNTIME_API __GR_ATTR_EXPORT
|
||||
#else
|
||||
# define GR_RUNTIME_API __GR_ATTR_IMPORT
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_RUNTIME_API_H */
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GNURADIO_ATTRIBUTES_H
|
||||
#define INCLUDED_GNURADIO_ATTRIBUTES_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Cross-platform attribute macros
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#if defined __GNUC__
|
||||
# define __GR_ATTR_ALIGNED(x) __attribute__((aligned(x)))
|
||||
# define __GR_ATTR_UNUSED __attribute__((unused))
|
||||
# define __GR_ATTR_INLINE __attribute__((always_inline))
|
||||
# define __GR_ATTR_DEPRECATED __attribute__((deprecated))
|
||||
# if __GNUC__ >= 4
|
||||
# define __GR_ATTR_EXPORT __attribute__((visibility("default")))
|
||||
# define __GR_ATTR_IMPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
# define __GR_ATTR_EXPORT
|
||||
# define __GR_ATTR_IMPORT
|
||||
# endif
|
||||
#elif _MSC_VER
|
||||
# define __GR_ATTR_ALIGNED(x) __declspec(align(x))
|
||||
# define __GR_ATTR_UNUSED
|
||||
# define __GR_ATTR_INLINE __forceinline
|
||||
# define __GR_ATTR_DEPRECATED __declspec(deprecated)
|
||||
# define __GR_ATTR_EXPORT __declspec(dllexport)
|
||||
# define __GR_ATTR_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# define __GR_ATTR_ALIGNED(x)
|
||||
# define __GR_ATTR_UNUSED
|
||||
# define __GR_ATTR_INLINE
|
||||
# define __GR_ATTR_DEPRECATED
|
||||
# define __GR_ATTR_EXPORT
|
||||
# define __GR_ATTR_IMPORT
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// define inline when building C
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#if defined(_MSC_VER) && !defined(__cplusplus) && !defined(inline)
|
||||
# define inline __inline
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// suppress warnings
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
|
||||
# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ...
|
||||
# pragma warning(disable: 4244) // conversion from 'double' to 'float', possible loss of data
|
||||
# pragma warning(disable: 4305) // 'initializing' : truncation from 'double' to 'float'
|
||||
# pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDED_GNURADIO_ATTRIBUTES_H */
|
|
@ -0,0 +1,209 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2006,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 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_BASIC_BLOCK_H
|
||||
#define INCLUDED_GR_BASIC_BLOCK_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/sptr_magic.h>
|
||||
#include <gnuradio/runtime_types.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
|
||||
#ifdef GR_CTRLPORT
|
||||
#include <gnuradio/rpcregisterhelpers.h>
|
||||
#endif
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief The abstract base class for all signal processing blocks.
|
||||
* \ingroup internal
|
||||
*
|
||||
* Basic blocks are the bare abstraction of an entity that has a
|
||||
* name, a set of inputs and outputs, and a message queue. These
|
||||
* are never instantiated directly; rather, this is the abstract
|
||||
* parent class of both gr_hier_block, which is a recursive
|
||||
* container, and block, which implements actual signal
|
||||
* processing functions.
|
||||
*/
|
||||
class GR_RUNTIME_API basic_block : public boost::enable_shared_from_this<basic_block>
|
||||
{
|
||||
private:
|
||||
gr::thread::mutex mutex; //< protects all vars
|
||||
|
||||
protected:
|
||||
friend class flowgraph;
|
||||
friend class flat_flowgraph; // TODO: will be redundant
|
||||
friend class tpb_thread_body;
|
||||
|
||||
enum vcolor { WHITE, GREY, BLACK };
|
||||
|
||||
std::string d_name;
|
||||
gr::io_signature::sptr d_input_signature;
|
||||
gr::io_signature::sptr d_output_signature;
|
||||
long d_unique_id;
|
||||
long d_symbolic_id;
|
||||
std::string d_symbol_name;
|
||||
std::string d_symbol_alias;
|
||||
vcolor d_color;
|
||||
bool d_rpc_set;
|
||||
|
||||
std::vector<boost::any> d_rpc_vars; // container for all RPC variables
|
||||
|
||||
basic_block(void) {} // allows pure virtual interface sub-classes
|
||||
|
||||
//! Protected constructor prevents instantiation by non-derived classes
|
||||
basic_block(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
//! may only be called during constructor
|
||||
void set_input_signature(gr::io_signature::sptr iosig) {
|
||||
d_input_signature = iosig;
|
||||
}
|
||||
|
||||
//! may only be called during constructor
|
||||
void set_output_signature(gr::io_signature::sptr iosig) {
|
||||
d_output_signature = iosig;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Allow the flowgraph to set for sorting and partitioning
|
||||
*/
|
||||
void set_color(vcolor color) { d_color = color; }
|
||||
vcolor color() const { return d_color; }
|
||||
|
||||
public:
|
||||
virtual ~basic_block();
|
||||
long unique_id() const { return d_unique_id; }
|
||||
long symbolic_id() const { return d_symbolic_id; }
|
||||
std::string name() const { return d_name; }
|
||||
std::string symbol_name() const { return d_symbol_name; }
|
||||
gr::io_signature::sptr input_signature() const { return d_input_signature; }
|
||||
gr::io_signature::sptr output_signature() const { return d_output_signature; }
|
||||
basic_block_sptr to_basic_block(); // Needed for Python type coercion
|
||||
bool alias_set() { return !d_symbol_alias.empty(); }
|
||||
std::string alias(){ return alias_set()?d_symbol_alias:symbol_name(); }
|
||||
void set_block_alias(std::string name);
|
||||
|
||||
|
||||
|
||||
#ifdef GR_CTRLPORT
|
||||
/*!
|
||||
* \brief Add an RPC variable (get or set).
|
||||
*
|
||||
* Using controlport, we create new getters/setters and need to
|
||||
* store them. Each block has a vector to do this, and these never
|
||||
* need to be accessed again once they are registered with the RPC
|
||||
* backend. This function takes a
|
||||
* boost::shared_sptr<rpcbasic_base> so that when the block is
|
||||
* deleted, all RPC registered variables are cleaned up.
|
||||
*
|
||||
* \param s an rpcbasic_sptr of the new RPC variable register to store.
|
||||
*/
|
||||
void add_rpc_variable(rpcbasic_sptr s)
|
||||
{
|
||||
d_rpc_vars.push_back(s);
|
||||
}
|
||||
#endif /* GR_CTRLPORT */
|
||||
|
||||
/*!
|
||||
* \brief Set up the RPC registered variables.
|
||||
*
|
||||
* This must be overloaded by a block that wants to use
|
||||
* controlport. This is where rpcbasic_register_{get,set} pointers
|
||||
* are created, which then get wrapped as shared pointers
|
||||
* (rpcbasic_sptr(...)) and stored using add_rpc_variable.
|
||||
*/
|
||||
virtual void setup_rpc() {};
|
||||
|
||||
/*!
|
||||
* \brief Ask if this block has been registered to the RPC.
|
||||
*
|
||||
* We can only register a block once, so we use this to protect us
|
||||
* from calling it multiple times.
|
||||
*/
|
||||
bool is_rpc_set() { return d_rpc_set; }
|
||||
|
||||
/*!
|
||||
* \brief When the block is registered with the RPC, set this.
|
||||
*/
|
||||
void rpc_set() { d_rpc_set = true; }
|
||||
|
||||
/*!
|
||||
* \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.
|
||||
*/
|
||||
virtual bool check_topology(int ninputs, int noutputs) {
|
||||
(void)ninputs;
|
||||
(void)noutputs;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void set_processor_affinity(const std::vector<int> &mask)
|
||||
{ throw std::runtime_error("set_processor_affinity not overloaded in child class."); }
|
||||
|
||||
virtual void unset_processor_affinity()
|
||||
{ throw std::runtime_error("unset_processor_affinity not overloaded in child class."); }
|
||||
|
||||
virtual std::vector<int> processor_affinity()
|
||||
{ throw std::runtime_error("processor_affinity not overloaded in child class."); }
|
||||
};
|
||||
|
||||
inline bool operator<(basic_block_sptr lhs, basic_block_sptr rhs)
|
||||
{
|
||||
return lhs->unique_id() < rhs->unique_id();
|
||||
}
|
||||
|
||||
typedef std::vector<basic_block_sptr> basic_block_vector_t;
|
||||
typedef std::vector<basic_block_sptr>::iterator basic_block_viter_t;
|
||||
|
||||
GR_RUNTIME_API long basic_block_ncurrently_allocated();
|
||||
|
||||
inline std::ostream &operator << (std::ostream &os, basic_block_sptr basic_block)
|
||||
{
|
||||
os << basic_block->name() << "(" << basic_block->unique_id() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_BASIC_BLOCK_H */
|
|
@ -0,0 +1,573 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,2007,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_RUNTIME_BLOCK_H
|
||||
#define INCLUDED_GR_RUNTIME_BLOCK_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/basic_block.h>
|
||||
#include <gnuradio/logger.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief The abstract base class for all 'terminal' processing blocks.
|
||||
* \ingroup base_blk
|
||||
*
|
||||
* A signal processing flow is constructed by creating a tree of
|
||||
* hierarchical blocks, which at any level may also contain terminal
|
||||
* nodes that actually implement signal processing functions. This
|
||||
* is the base class for all such leaf nodes.
|
||||
*
|
||||
* Blocks have a set of input streams and output streams. The
|
||||
* input_signature and output_signature define the number of input
|
||||
* streams and output streams respectively, and the type of the data
|
||||
* items in each stream.
|
||||
*
|
||||
* Although blocks may consume data on each input stream at a
|
||||
* different rate, all outputs streams must produce data at the same
|
||||
* rate. That rate may be different from any of the input rates.
|
||||
*
|
||||
* User derived blocks override two methods, forecast and
|
||||
* general_work, to implement their signal processing
|
||||
* behavior. forecast is called by the system scheduler to determine
|
||||
* how many items are required on each input stream in order to
|
||||
* produce a given number of output items.
|
||||
*
|
||||
* general_work is called to perform the signal processing in the
|
||||
* block. It reads the input items and writes the output items.
|
||||
*/
|
||||
class GR_RUNTIME_API block : public basic_block
|
||||
{
|
||||
public:
|
||||
|
||||
//! Magic return values from general_work
|
||||
enum {
|
||||
WORK_CALLED_PRODUCE = -2,
|
||||
WORK_DONE = -1
|
||||
};
|
||||
|
||||
enum tag_propagation_policy_t {
|
||||
TPP_DONT = 0,
|
||||
TPP_ALL_TO_ALL = 1,
|
||||
TPP_ONE_TO_ONE = 2
|
||||
};
|
||||
|
||||
virtual ~block();
|
||||
|
||||
/*!
|
||||
* Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
|
||||
* History is the number of x_i's that are examined to produce one y_i.
|
||||
* This comes in handy for FIR filters, where we use history to
|
||||
* ensure that our input contains the appropriate "history" for the
|
||||
* filter. History should be equal to the number of filter taps.
|
||||
*/
|
||||
unsigned history() const { return d_history; }
|
||||
void set_history(unsigned history) { d_history = history; }
|
||||
|
||||
/*!
|
||||
* \brief Return true if this block has a fixed input to output rate.
|
||||
*
|
||||
* If true, then fixed_rate_in_to_out and fixed_rate_out_to_in may be called.
|
||||
*/
|
||||
bool fixed_rate() const { return d_fixed_rate; }
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// 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.
|
||||
*/
|
||||
virtual void forecast(int noutput_items,
|
||||
gr_vector_int &ninput_items_required);
|
||||
|
||||
/*!
|
||||
* \brief compute output items from input items
|
||||
*
|
||||
* \param noutput_items number of output items to write on each output stream
|
||||
* \param ninput_items number of input items available on each input stream
|
||||
* \param input_items vector of pointers to the input items, one entry per input stream
|
||||
* \param output_items vector of pointers to the output items, one entry per output stream
|
||||
*
|
||||
* \returns number of items actually written to each output stream, or -1 on EOF.
|
||||
* It is OK to return a value less than noutput_items. -1 <= return value <= noutput_items
|
||||
*
|
||||
* general_work must call consume or consume_each to indicate how
|
||||
* many items were consumed on each input stream.
|
||||
*/
|
||||
virtual int general_work(int noutput_items,
|
||||
gr_vector_int &ninput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
|
||||
/*!
|
||||
* \brief Called to enable drivers, etc for i/o devices.
|
||||
*
|
||||
* This allows a block to enable an associated driver to begin
|
||||
* transfering data just before we start to execute the scheduler.
|
||||
* The end result is that this reduces latency in the pipeline
|
||||
* when dealing with audio devices, usrps, etc.
|
||||
*/
|
||||
virtual bool start();
|
||||
|
||||
/*!
|
||||
* \brief Called to disable drivers, etc for i/o devices.
|
||||
*/
|
||||
virtual bool stop();
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
* \brief Constrain the noutput_items argument passed to forecast and general_work
|
||||
*
|
||||
* set_output_multiple causes the scheduler to ensure that the
|
||||
* noutput_items argument passed to forecast and general_work will
|
||||
* be an integer multiple of \param multiple The default value of
|
||||
* output multiple is 1.
|
||||
*/
|
||||
void set_output_multiple(int multiple);
|
||||
int output_multiple() const { return d_output_multiple; }
|
||||
bool output_multiple_set() const { return d_output_multiple_set; }
|
||||
|
||||
/*!
|
||||
* \brief Constrains buffers to work on a set item alignment (for SIMD)
|
||||
*
|
||||
* set_alignment_multiple causes the scheduler to ensure that the
|
||||
* noutput_items argument passed to forecast and general_work will
|
||||
* be an integer multiple of \param multiple The default value is
|
||||
* 1.
|
||||
*
|
||||
* This control is similar to the output_multiple setting, except
|
||||
* that if the number of items passed to the block is less than
|
||||
* the output_multiple, this value is ignored and the block can
|
||||
* produce like normal. The d_unaligned value is set to the number
|
||||
* of items the block is off by. In the next call to general_work,
|
||||
* the noutput_items is set to d_unaligned or less until
|
||||
* d_unaligned==0. The buffers are now aligned again and the
|
||||
* aligned calls can be performed again.
|
||||
*/
|
||||
void set_alignment(int multiple);
|
||||
int alignment() const { return d_output_multiple; }
|
||||
|
||||
void set_unaligned(int na);
|
||||
int unaligned() const { return d_unaligned; }
|
||||
void set_is_unaligned(bool u);
|
||||
bool is_unaligned() const { return d_is_unaligned; }
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items of input stream \p
|
||||
* which_input were consumed.
|
||||
*/
|
||||
void consume(int which_input, int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items were consumed on
|
||||
* each input stream.
|
||||
*/
|
||||
void consume_each(int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items were produced on
|
||||
* output stream \p which_output.
|
||||
*
|
||||
* If the block's general_work method calls produce, \p
|
||||
* general_work must return WORK_CALLED_PRODUCE.
|
||||
*/
|
||||
void produce(int which_output, int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Set the approximate output rate / input rate
|
||||
*
|
||||
* Provide a hint to the buffer allocator and scheduler.
|
||||
* The default relative_rate is 1.0
|
||||
*
|
||||
* decimators have relative_rates < 1.0
|
||||
* interpolators have relative_rates > 1.0
|
||||
*/
|
||||
void set_relative_rate(double relative_rate);
|
||||
|
||||
/*!
|
||||
* \brief return the approximate output rate / input rate
|
||||
*/
|
||||
double relative_rate() const { return d_relative_rate; }
|
||||
|
||||
/*
|
||||
* The following two methods provide special case info to the
|
||||
* scheduler in the event that a block has a fixed input to output
|
||||
* ratio. sync_block, sync_decimator and
|
||||
* 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.
|
||||
*/
|
||||
virtual int fixed_rate_ninput_to_noutput(int ninput);
|
||||
|
||||
/*!
|
||||
* \brief Given noutput samples, return number of input samples required to produce noutput.
|
||||
* N.B. this is only defined if fixed_rate returns true.
|
||||
* Generally speaking, you don't need to override this.
|
||||
*/
|
||||
virtual int fixed_rate_noutput_to_ninput(int noutput);
|
||||
|
||||
/*!
|
||||
* \brief Return the number of items read on input stream which_input
|
||||
*/
|
||||
uint64_t nitems_read(unsigned int which_input);
|
||||
|
||||
/*!
|
||||
* \brief Return the number of items written on output stream which_output
|
||||
*/
|
||||
uint64_t nitems_written(unsigned int which_output);
|
||||
|
||||
/*!
|
||||
* \brief Return the minimum number of output items this block can
|
||||
* produce during a call to work.
|
||||
*
|
||||
* Should be 0 for most blocks. Useful if we're dealing with
|
||||
* packets and the block produces one packet per call to work.
|
||||
*/
|
||||
int min_noutput_items() const { return d_min_noutput_items; }
|
||||
|
||||
/*!
|
||||
* \brief Set the minimum number of output items this block can
|
||||
* produce during a call to work.
|
||||
*
|
||||
* \param m the minimum noutput_items this block can produce.
|
||||
*/
|
||||
void set_min_noutput_items(int m) { d_min_noutput_items = m; }
|
||||
|
||||
/*!
|
||||
* \brief Return the maximum number of output items this block will
|
||||
* handle during a call to work.
|
||||
*/
|
||||
int max_noutput_items();
|
||||
|
||||
/*!
|
||||
* \brief Set the maximum number of output items this block will
|
||||
* handle during a call to work.
|
||||
*
|
||||
* \param m the maximum noutput_items this block will handle.
|
||||
*/
|
||||
void set_max_noutput_items(int m);
|
||||
|
||||
/*!
|
||||
* \brief Clear the switch for using the max_noutput_items value of this block.
|
||||
*
|
||||
* When is_set_max_noutput_items() returns 'true', the scheduler
|
||||
* will use the value returned by max_noutput_items() to limit the
|
||||
* size of the number of items possible for this block's work
|
||||
* function. If is_set_max_notput_items() returns 'false', then
|
||||
* the scheduler ignores the internal value and uses the value set
|
||||
* globally in the top_block.
|
||||
*
|
||||
* Use this value to clear the 'is_set' flag so the scheduler will
|
||||
* ignore this. Use the set_max_noutput_items(m) call to both set
|
||||
* a new value for max_noutput_items and to reenable its use in
|
||||
* the scheduler.
|
||||
*/
|
||||
void unset_max_noutput_items();
|
||||
|
||||
/*!
|
||||
* \brief Ask the block if the flag is or is not set to use the
|
||||
* internal value of max_noutput_items during a call to work.
|
||||
*/
|
||||
bool is_set_max_noutput_items();
|
||||
|
||||
/*
|
||||
* Used to expand the vectors that hold the min/max buffer sizes.
|
||||
*
|
||||
* Specifically, when -1 is used, the vectors are just initialized
|
||||
* with 1 value; this is used by the flat_flowgraph to expand when
|
||||
* required to add a new value for new ports on these blocks.
|
||||
*/
|
||||
void expand_minmax_buffer(int port);
|
||||
|
||||
/*!
|
||||
* \brief Returns max buffer size on output port \p i.
|
||||
*/
|
||||
long max_output_buffer(size_t i);
|
||||
|
||||
/*!
|
||||
* \brief Sets max buffer size on all output ports.
|
||||
*/
|
||||
void set_max_output_buffer(long max_output_buffer);
|
||||
|
||||
/*!
|
||||
* \brief Sets max buffer size on output port \p port.
|
||||
*/
|
||||
void set_max_output_buffer(int port, long max_output_buffer);
|
||||
|
||||
/*!
|
||||
* \brief Returns min buffer size on output port \p i.
|
||||
*/
|
||||
long min_output_buffer(size_t i);
|
||||
|
||||
/*!
|
||||
* \brief Sets min buffer size on all output ports.
|
||||
*/
|
||||
void set_min_output_buffer(long min_output_buffer);
|
||||
|
||||
/*!
|
||||
* \brief Sets min buffer size on output port \p port.
|
||||
*/
|
||||
void set_min_output_buffer(int port, long min_output_buffer);
|
||||
|
||||
// --------------- Performance counter functions -------------
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous noutput_items performance counter.
|
||||
*/
|
||||
float pc_noutput_items();
|
||||
|
||||
/*!
|
||||
* \brief Gets average noutput_items performance counter.
|
||||
*/
|
||||
float pc_noutput_items_avg();
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of noutput_items performance counter.
|
||||
*/
|
||||
float pc_noutput_items_var();
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous num items produced performance counter.
|
||||
*/
|
||||
float pc_nproduced();
|
||||
|
||||
/*!
|
||||
* \brief Gets average num items produced performance counter.
|
||||
*/
|
||||
float pc_nproduced_avg();
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of num items produced performance counter.
|
||||
*/
|
||||
float pc_nproduced_var();
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_input_buffers_full(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets average fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_input_buffers_full_avg(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_input_buffers_full_var(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous fullness of all input buffers.
|
||||
*/
|
||||
std::vector<float> pc_input_buffers_full();
|
||||
|
||||
/*!
|
||||
* \brief Gets average fullness of all input buffers.
|
||||
*/
|
||||
std::vector<float> pc_input_buffers_full_avg();
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of fullness of all input buffers.
|
||||
*/
|
||||
std::vector<float> pc_input_buffers_full_var();
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_output_buffers_full(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets average fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_output_buffers_full_avg(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of fullness of \p which input buffer.
|
||||
*/
|
||||
float pc_output_buffers_full_var(int which);
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous fullness of all output buffers.
|
||||
*/
|
||||
std::vector<float> pc_output_buffers_full();
|
||||
|
||||
/*!
|
||||
* \brief Gets average fullness of all output buffers.
|
||||
*/
|
||||
std::vector<float> pc_output_buffers_full_avg();
|
||||
|
||||
/*!
|
||||
* \brief Gets variance of fullness of all output buffers.
|
||||
*/
|
||||
std::vector<float> pc_output_buffers_full_var();
|
||||
|
||||
/*!
|
||||
* \brief Gets instantaneous clock cycles spent in work.
|
||||
*/
|
||||
float pc_work_time();
|
||||
|
||||
/*!
|
||||
* \brief Gets average clock cycles spent in work.
|
||||
*/
|
||||
float pc_work_time_avg();
|
||||
|
||||
/*!
|
||||
* \brief Gets average clock cycles spent in work.
|
||||
*/
|
||||
float pc_work_time_var();
|
||||
|
||||
/*!
|
||||
* \brief Resets the performance counters
|
||||
*/
|
||||
void reset_perf_counters();
|
||||
|
||||
/*!
|
||||
* \brief Sets up export of perf. counters to ControlPort. Only
|
||||
* called by the scheduler.
|
||||
*/
|
||||
void setup_pc_rpc();
|
||||
|
||||
/*!
|
||||
* \brief Checks if this block is already exporting perf. counters
|
||||
* to ControlPort.
|
||||
*/
|
||||
bool is_pc_rpc_set() { return d_pc_rpc_set; }
|
||||
|
||||
/*!
|
||||
* \brief If the block calls this in its constructor, it's
|
||||
* perf. counters will not be exported.
|
||||
*/
|
||||
void no_pc_rpc() { d_pc_rpc_set = true; }
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Functions to handle thread affinity
|
||||
|
||||
/*!
|
||||
* \brief Set the thread's affinity to processor core \p n.
|
||||
*
|
||||
* \param mask a vector of ints of the core numbers available to this block.
|
||||
*/
|
||||
void set_processor_affinity(const std::vector<int> &mask);
|
||||
|
||||
/*!
|
||||
* \brief Remove processor affinity to a specific core.
|
||||
*/
|
||||
void unset_processor_affinity();
|
||||
|
||||
/*!
|
||||
* \brief Get the current processor affinity.
|
||||
*/
|
||||
std::vector<int> processor_affinity() { return d_affinity; }
|
||||
|
||||
/*!
|
||||
* \brief Get the current thread priority in use
|
||||
*/
|
||||
int active_thread_priority();
|
||||
|
||||
/*!
|
||||
* \brief Get the current thread priority stored
|
||||
*/
|
||||
int thread_priority();
|
||||
|
||||
/*!
|
||||
* \brief Set the current thread priority
|
||||
*/
|
||||
int set_thread_priority(int priority);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
int d_output_multiple;
|
||||
bool d_output_multiple_set;
|
||||
int d_unaligned;
|
||||
bool d_is_unaligned;
|
||||
double d_relative_rate; // approx output_rate / input_rate
|
||||
block_detail_sptr d_detail; // implementation details
|
||||
unsigned d_history;
|
||||
bool d_fixed_rate;
|
||||
bool d_max_noutput_items_set; // if d_max_noutput_items is valid
|
||||
int d_max_noutput_items; // value of max_noutput_items for this block
|
||||
int d_min_noutput_items;
|
||||
std::vector<int> d_affinity; // thread affinity proc. mask
|
||||
int d_priority; // thread priority level
|
||||
bool d_pc_rpc_set;
|
||||
|
||||
protected:
|
||||
block(void) {} // allows pure virtual interface sub-classes
|
||||
block(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
void set_fixed_rate(bool fixed_rate) { d_fixed_rate = fixed_rate; }
|
||||
|
||||
std::vector<long> d_max_output_buffer;
|
||||
std::vector<long> d_min_output_buffer;
|
||||
|
||||
/*! Used by block's setters and work functions to make
|
||||
* setting/resetting of parameters thread-safe.
|
||||
*
|
||||
* Used by calling gr::thread::scoped_lock l(d_setlock);
|
||||
*/
|
||||
gr::thread::mutex d_setlock;
|
||||
|
||||
/*! Used by blocks to access the logger system.
|
||||
*/
|
||||
gr::logger_ptr d_logger;
|
||||
gr::logger_ptr d_debug_logger;
|
||||
|
||||
// These are really only for internal use, but leaving them public avoids
|
||||
// having to work up an ever-varying list of friend GR_RUNTIME_APIs
|
||||
|
||||
public:
|
||||
block_detail_sptr detail() const { return d_detail; }
|
||||
void set_detail(block_detail_sptr detail) { d_detail = detail; }
|
||||
};
|
||||
|
||||
typedef std::vector<block_sptr> block_vector_t;
|
||||
typedef std::vector<block_sptr>::iterator block_viter_t;
|
||||
|
||||
inline block_sptr cast_to_block_sptr(basic_block_sptr p)
|
||||
{
|
||||
return boost::dynamic_pointer_cast<block, basic_block>(p);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator << (std::ostream& os, const block *m);
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_BLOCK_H */
|
|
@ -0,0 +1,207 @@
|
|||
/* -*- 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 detail.
|
||||
*
|
||||
* 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_DETAIL_H
|
||||
#define INCLUDED_GR_RUNTIME_BLOCK_DETAIL_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/runtime_types.h>
|
||||
#include <gnuradio/tpb_detail.h>
|
||||
#include <gnuradio/high_res_timer.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Implementation details to support the signal processing abstraction
|
||||
* \ingroup internal
|
||||
*
|
||||
* This class contains implementation detail that should be "out of
|
||||
* sight" of almost all users of GNU Radio. This decoupling also
|
||||
* means that we can make changes to the guts without having to
|
||||
* recompile everything.
|
||||
*/
|
||||
class GR_RUNTIME_API block_detail
|
||||
{
|
||||
public:
|
||||
~block_detail();
|
||||
|
||||
int ninputs() const { return d_ninputs; }
|
||||
int noutputs() const { return d_noutputs; }
|
||||
bool sink_p() const { return d_noutputs == 0; }
|
||||
bool source_p() const { return d_ninputs == 0; }
|
||||
|
||||
void set_done(bool done);
|
||||
bool done() const { return d_done; }
|
||||
|
||||
void set_input(unsigned int which, buffer_reader_sptr reader);
|
||||
buffer_reader_sptr input(unsigned int which)
|
||||
{
|
||||
if(which >= d_ninputs)
|
||||
throw std::invalid_argument("block_detail::input");
|
||||
return d_input[which];
|
||||
}
|
||||
|
||||
void set_output(unsigned int which, buffer_sptr buffer);
|
||||
buffer_sptr output(unsigned int which)
|
||||
{
|
||||
if(which >= d_noutputs)
|
||||
throw std::invalid_argument("block_detail::output");
|
||||
return d_output[which];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items of input stream \p
|
||||
* which_input were consumed.
|
||||
*/
|
||||
void consume(int which_input, int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items were consumed on
|
||||
* each input stream.
|
||||
*/
|
||||
void consume_each(int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items were produced on
|
||||
* output stream \p which_output.
|
||||
*/
|
||||
void produce(int which_output, int how_many_items);
|
||||
|
||||
/*!
|
||||
* \brief Tell the scheduler \p how_many_items were produced on
|
||||
* each output stream.
|
||||
*/
|
||||
void produce_each(int how_many_items);
|
||||
|
||||
// Return the number of items read on input stream which_input
|
||||
uint64_t nitems_read(unsigned int which_input);
|
||||
|
||||
// Return the number of items written on output stream which_output
|
||||
uint64_t nitems_written(unsigned int which_output);
|
||||
|
||||
/*!
|
||||
* \brief Set core affinity of block to the cores in the vector
|
||||
* mask.
|
||||
*
|
||||
* \param mask a vector of ints of the core numbers available to
|
||||
* this block.
|
||||
*/
|
||||
void set_processor_affinity(const std::vector<int> &mask);
|
||||
|
||||
/*!
|
||||
* \brief Unset core affinity.
|
||||
*/
|
||||
void unset_processor_affinity();
|
||||
|
||||
/*!
|
||||
* \brief Get the current thread priority
|
||||
*/
|
||||
int thread_priority();
|
||||
|
||||
/*!
|
||||
* \brief Set the current thread priority
|
||||
*
|
||||
* \param priority the new thread priority to set
|
||||
*/
|
||||
int set_thread_priority(int priority);
|
||||
|
||||
bool threaded; // set if thread is currently running.
|
||||
gr::thread::gr_thread_t thread; // portable thread handle
|
||||
|
||||
void start_perf_counters();
|
||||
void stop_perf_counters(int noutput_items, int nproduced);
|
||||
void reset_perf_counters();
|
||||
|
||||
// Calls to get performance counter items
|
||||
float pc_noutput_items();
|
||||
float pc_nproduced();
|
||||
float pc_input_buffers_full(size_t which);
|
||||
std::vector<float> pc_input_buffers_full();
|
||||
float pc_output_buffers_full(size_t which);
|
||||
std::vector<float> pc_output_buffers_full();
|
||||
float pc_work_time();
|
||||
|
||||
float pc_noutput_items_avg();
|
||||
float pc_nproduced_avg();
|
||||
float pc_input_buffers_full_avg(size_t which);
|
||||
std::vector<float> pc_input_buffers_full_avg();
|
||||
float pc_output_buffers_full_avg(size_t which);
|
||||
std::vector<float> pc_output_buffers_full_avg();
|
||||
float pc_work_time_avg();
|
||||
|
||||
float pc_noutput_items_var();
|
||||
float pc_nproduced_var();
|
||||
float pc_input_buffers_full_var(size_t which);
|
||||
std::vector<float> pc_input_buffers_full_var();
|
||||
float pc_output_buffers_full_var(size_t which);
|
||||
std::vector<float> pc_output_buffers_full_var();
|
||||
float pc_work_time_var();
|
||||
|
||||
tpb_detail d_tpb; // used by thread-per-block scheduler
|
||||
int d_produce_or;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
unsigned int d_ninputs;
|
||||
unsigned int d_noutputs;
|
||||
std::vector<buffer_reader_sptr> d_input;
|
||||
std::vector<buffer_sptr> d_output;
|
||||
bool d_done;
|
||||
|
||||
// Performance counters
|
||||
float d_ins_noutput_items;
|
||||
float d_avg_noutput_items;
|
||||
float d_var_noutput_items;
|
||||
float d_ins_nproduced;
|
||||
float d_avg_nproduced;
|
||||
float d_var_nproduced;
|
||||
std::vector<float> d_ins_input_buffers_full;
|
||||
std::vector<float> d_avg_input_buffers_full;
|
||||
std::vector<float> d_var_input_buffers_full;
|
||||
std::vector<float> d_ins_output_buffers_full;
|
||||
std::vector<float> d_avg_output_buffers_full;
|
||||
std::vector<float> d_var_output_buffers_full;
|
||||
gr::high_res_timer_type d_start_of_work, d_end_of_work;
|
||||
float d_ins_work_time;
|
||||
float d_avg_work_time;
|
||||
float d_var_work_time;
|
||||
float d_pc_counter;
|
||||
|
||||
block_detail(unsigned int ninputs, unsigned int noutputs);
|
||||
|
||||
friend struct tpb_detail;
|
||||
|
||||
friend GR_RUNTIME_API block_detail_sptr
|
||||
make_block_detail(unsigned int ninputs, unsigned int noutputs);
|
||||
};
|
||||
|
||||
GR_RUNTIME_API block_detail_sptr
|
||||
make_block_detail(unsigned int ninputs, unsigned int noutputs);
|
||||
|
||||
GR_RUNTIME_API long
|
||||
block_detail_ncurrently_allocated();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_BLOCK_DETAIL_H */
|
|
@ -0,0 +1,178 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_RUNTIME_BLOCK_GATEWAY_H
|
||||
#define INCLUDED_RUNTIME_BLOCK_GATEWAY_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
#include <gnuradio/feval.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* The work type enum tells the gateway what kind of block to
|
||||
* implement. The choices are familiar gnuradio block overloads
|
||||
* (sync, decim, interp).
|
||||
*/
|
||||
enum block_gw_work_type {
|
||||
GR_BLOCK_GW_WORK_GENERAL,
|
||||
GR_BLOCK_GW_WORK_SYNC,
|
||||
GR_BLOCK_GW_WORK_DECIM,
|
||||
GR_BLOCK_GW_WORK_INTERP,
|
||||
};
|
||||
|
||||
/*!
|
||||
* Shared message structure between python and gateway.
|
||||
* Each action type represents a scheduler-called function.
|
||||
*/
|
||||
struct block_gw_message_type {
|
||||
enum action_type {
|
||||
ACTION_GENERAL_WORK, //dispatch work
|
||||
ACTION_WORK, //dispatch work
|
||||
ACTION_FORECAST, //dispatch forecast
|
||||
ACTION_START, //dispatch start
|
||||
ACTION_STOP, //dispatch stop
|
||||
};
|
||||
|
||||
action_type action;
|
||||
|
||||
int general_work_args_noutput_items;
|
||||
std::vector<int> general_work_args_ninput_items;
|
||||
std::vector<void *> general_work_args_input_items; //TODO this should be const void*, but swig cant int cast it right
|
||||
std::vector<void *> general_work_args_output_items;
|
||||
int general_work_args_return_value;
|
||||
|
||||
int work_args_ninput_items;
|
||||
int work_args_noutput_items;
|
||||
std::vector<void *> work_args_input_items; //TODO this should be const void*, but swig cant int cast it right
|
||||
std::vector<void *> work_args_output_items;
|
||||
int work_args_return_value;
|
||||
|
||||
int forecast_args_noutput_items;
|
||||
std::vector<int> forecast_args_ninput_items_required;
|
||||
|
||||
bool start_args_return_value;
|
||||
|
||||
bool stop_args_return_value;
|
||||
};
|
||||
|
||||
/*!
|
||||
* The gateway block which performs all the magic.
|
||||
*
|
||||
* The gateway provides access to all the gr::block routines.
|
||||
* The methods prefixed with gr::block__ are renamed
|
||||
* to class methods without the prefix in python.
|
||||
*/
|
||||
class GR_RUNTIME_API block_gateway : virtual public gr::block
|
||||
{
|
||||
public:
|
||||
// gr::block_gateway::sptr
|
||||
typedef boost::shared_ptr<block_gateway> sptr;
|
||||
|
||||
/*!
|
||||
* Make a new gateway block.
|
||||
* \param handler the swig director object with callback
|
||||
* \param name the name of the block (Ex: "Shirley")
|
||||
* \param in_sig the input signature for this block
|
||||
* \param out_sig the output signature for this block
|
||||
* \param work_type the type of block overload to implement
|
||||
* \param factor the decimation or interpolation factor
|
||||
* \return a new gateway block
|
||||
*/
|
||||
static sptr make(gr::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);
|
||||
|
||||
//! Provide access to the shared message object
|
||||
virtual block_gw_message_type &block_message(void) = 0;
|
||||
|
||||
long block__unique_id(void) const {
|
||||
return gr::block::unique_id();
|
||||
}
|
||||
|
||||
std::string block__name(void) const {
|
||||
return gr::block::name();
|
||||
}
|
||||
|
||||
unsigned block__history(void) const {
|
||||
return gr::block::history();
|
||||
}
|
||||
|
||||
void block__set_history(unsigned history) {
|
||||
return gr::block::set_history(history);
|
||||
}
|
||||
|
||||
void block__set_fixed_rate(bool fixed_rate) {
|
||||
return gr::block::set_fixed_rate(fixed_rate);
|
||||
}
|
||||
|
||||
bool block__fixed_rate(void) const {
|
||||
return gr::block::fixed_rate();
|
||||
}
|
||||
|
||||
void block__set_output_multiple(int multiple) {
|
||||
return gr::block::set_output_multiple(multiple);
|
||||
}
|
||||
|
||||
int block__output_multiple(void) const {
|
||||
return gr::block::output_multiple();
|
||||
}
|
||||
|
||||
void block__consume(int which_input, int how_many_items) {
|
||||
return gr::block::consume(which_input, how_many_items);
|
||||
}
|
||||
|
||||
void block__consume_each(int how_many_items) {
|
||||
return gr::block::consume_each(how_many_items);
|
||||
}
|
||||
|
||||
void block__produce(int which_output, int how_many_items) {
|
||||
return gr::block::produce(which_output, how_many_items);
|
||||
}
|
||||
|
||||
void block__set_relative_rate(double relative_rate) {
|
||||
return gr::block::set_relative_rate(relative_rate);
|
||||
}
|
||||
|
||||
double block__relative_rate(void) const {
|
||||
return gr::block::relative_rate();
|
||||
}
|
||||
|
||||
uint64_t block__nitems_read(unsigned int which_input) {
|
||||
return gr::block::nitems_read(which_input);
|
||||
}
|
||||
|
||||
uint64_t block__nitems_written(unsigned int which_output) {
|
||||
return gr::block::nitems_written(which_output);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_RUNTIME_BLOCK_GATEWAY_H */
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef GR_RUNTIME_BLOCK_REGISTRY_H
|
||||
#define GR_RUNTIME_BLOCK_REGISTRY_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/basic_block.h>
|
||||
#include <map>
|
||||
|
||||
namespace gr {
|
||||
|
||||
#ifndef GR_BASIC_BLOCK_H
|
||||
class basic_block;
|
||||
class block;
|
||||
#endif
|
||||
|
||||
class GR_RUNTIME_API block_registry
|
||||
{
|
||||
public:
|
||||
block_registry();
|
||||
|
||||
long block_register(basic_block* block);
|
||||
void block_unregister(basic_block* block);
|
||||
|
||||
std::string register_symbolic_name(basic_block* block);
|
||||
void register_symbolic_name(basic_block* block, std::string name);
|
||||
|
||||
void register_primitive(std::string blk, gr::block* ref);
|
||||
void unregister_primitive(std::string blk);
|
||||
void notify_blk(std::string blk);
|
||||
|
||||
private:
|
||||
//typedef std::map< long, basic_block_sptr > blocksubmap_t;
|
||||
typedef std::map< long, basic_block* > blocksubmap_t;
|
||||
typedef std::map< std::string, blocksubmap_t > blockmap_t;
|
||||
|
||||
blockmap_t d_map;
|
||||
std::map< std::string, block*> primitive_map;
|
||||
gr::thread::mutex d_mutex;
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
GR_RUNTIME_API extern gr::block_registry global_block_registry;
|
||||
|
||||
#endif /* GR_RUNTIME_BLOCK_REGISTRY_H */
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_BLOCKS_API_H
|
||||
#define INCLUDED_BLOCKS_API_H
|
||||
|
||||
#include <gnuradio/attributes.h>
|
||||
|
||||
#ifdef gnuradio_blocks_EXPORTS
|
||||
# define BLOCKS_API __GR_ATTR_EXPORT
|
||||
#else
|
||||
# define BLOCKS_API __GR_ATTR_IMPORT
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDED_BLOCKS_API_H */
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_NULL_SINK_H
|
||||
#define INCLUDED_GR_NULL_SINK_H
|
||||
|
||||
#include <gnuradio/blocks/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
/*!
|
||||
* \brief Bit bucket. Use as a termination point when a sink is
|
||||
* required and we don't want to do anything real.
|
||||
* \ingroup misc_blk
|
||||
*/
|
||||
class BLOCKS_API null_sink : virtual public sync_block
|
||||
{
|
||||
public:
|
||||
// gr::blocks::null_sink::sptr
|
||||
typedef boost::shared_ptr<null_sink> sptr;
|
||||
|
||||
/*!
|
||||
* Build a null sink block.
|
||||
*
|
||||
* \param sizeof_stream_item size of the stream items in bytes.
|
||||
*/
|
||||
static sptr make(size_t sizeof_stream_item);
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_NULL_SINK_H */
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_NULL_SOURCE_H
|
||||
#define INCLUDED_GR_NULL_SOURCE_H
|
||||
|
||||
#include <gnuradio/blocks/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
/*!
|
||||
* \brief A source of zeros used mainly for testing.
|
||||
* \ingroup misc_blk
|
||||
*/
|
||||
class BLOCKS_API null_source : virtual public sync_block
|
||||
{
|
||||
public:
|
||||
// gr::blocks::null_source::sptr
|
||||
typedef boost::shared_ptr<null_source> sptr;
|
||||
|
||||
/*!
|
||||
* Build a null source block.
|
||||
*
|
||||
* \param sizeof_stream_item size of the stream items in bytes.
|
||||
*/
|
||||
static sptr make(size_t sizeof_stream_item);
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_NULL_SOURCE_H */
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_THROTTLE_H
|
||||
#define INCLUDED_GR_THROTTLE_H
|
||||
|
||||
#include <gnuradio/blocks/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
/*!
|
||||
* \brief throttle flow of samples such that the average rate does
|
||||
* not exceed samples_per_sec.
|
||||
* \ingroup misc_blk
|
||||
*
|
||||
* \details
|
||||
* input: one stream of itemsize; output: one stream of itemsize
|
||||
*
|
||||
* N.B. this should only be used in GUI apps where there is no
|
||||
* other rate limiting block. It is not intended nor effective at
|
||||
* precisely controlling the rate of samples. That should be
|
||||
* controlled by a source or sink tied to sample clock. E.g., a
|
||||
* USRP or audio card.
|
||||
*/
|
||||
class BLOCKS_API throttle : virtual public sync_block
|
||||
{
|
||||
public:
|
||||
typedef boost::shared_ptr<throttle> sptr;
|
||||
|
||||
static sptr make(size_t itemsize, double samples_per_sec);
|
||||
|
||||
//! Sets the sample rate in samples per second.
|
||||
virtual void set_sample_rate(double rate) = 0;
|
||||
|
||||
//! Get the sample rate in samples per second.
|
||||
virtual double sample_rate() const = 0;
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_THROTTLE_H */
|
|
@ -0,0 +1,258 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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 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_BUFFER_H
|
||||
#define INCLUDED_GR_RUNTIME_BUFFER_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/runtime_types.h>
|
||||
#include <boost/weak_ptr.hpp>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <deque>
|
||||
|
||||
namespace gr {
|
||||
|
||||
class vmcircbuf;
|
||||
|
||||
/*!
|
||||
* \brief Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
|
||||
*
|
||||
* The total size of the buffer will be rounded up to a system
|
||||
* dependent boundary. This is typically the system page size, but
|
||||
* under MS windows is 64KB.
|
||||
*
|
||||
* \param nitems is the minimum number of items the buffer will hold.
|
||||
* \param sizeof_item is the size of an item in bytes.
|
||||
* \param link is the block that writes to this buffer.
|
||||
*/
|
||||
GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item,
|
||||
block_sptr link=block_sptr());
|
||||
|
||||
/*!
|
||||
* \brief Single writer, multiple reader fifo.
|
||||
* \ingroup internal
|
||||
*/
|
||||
class GR_RUNTIME_API buffer
|
||||
{
|
||||
public:
|
||||
virtual ~buffer();
|
||||
|
||||
/*!
|
||||
* \brief return number of items worth of space available for writing
|
||||
*/
|
||||
int space_available();
|
||||
|
||||
/*!
|
||||
* \brief return size of this buffer in items
|
||||
*/
|
||||
int bufsize() const { return d_bufsize; }
|
||||
|
||||
/*!
|
||||
* \brief return pointer to write buffer.
|
||||
*
|
||||
* The return value points at space that can hold at least
|
||||
* space_available() items.
|
||||
*/
|
||||
void *write_pointer();
|
||||
|
||||
/*!
|
||||
* \brief tell buffer that we wrote \p nitems into it
|
||||
*/
|
||||
void update_write_pointer(int nitems);
|
||||
|
||||
void set_done(bool done);
|
||||
bool done() const { return d_done; }
|
||||
|
||||
/*!
|
||||
* \brief Return the block that writes to this buffer.
|
||||
*/
|
||||
block_sptr link() { return block_sptr(d_link); }
|
||||
|
||||
size_t nreaders() const { return d_readers.size(); }
|
||||
buffer_reader* reader(size_t index) { return d_readers[index]; }
|
||||
|
||||
gr::thread::mutex *mutex() { return &d_mutex; }
|
||||
|
||||
uint64_t nitems_written() { return d_abs_write_offset; }
|
||||
|
||||
size_t get_sizeof_item() { return d_sizeof_item; }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
friend class buffer_reader;
|
||||
friend GR_RUNTIME_API buffer_sptr make_buffer(int nitems, size_t sizeof_item, block_sptr link);
|
||||
friend GR_RUNTIME_API buffer_reader_sptr buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link);
|
||||
|
||||
protected:
|
||||
char *d_base; // base address of buffer
|
||||
unsigned int d_bufsize; // in items
|
||||
private:
|
||||
gr::vmcircbuf *d_vmcircbuf;
|
||||
size_t d_sizeof_item; // in bytes
|
||||
std::vector<buffer_reader *> d_readers;
|
||||
boost::weak_ptr<block> d_link; // block that writes to this buffer
|
||||
|
||||
//
|
||||
// The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags
|
||||
// and the d_read_index's and d_abs_read_offset's in the buffer readers.
|
||||
//
|
||||
gr::thread::mutex d_mutex;
|
||||
unsigned int d_write_index; // in items [0,d_bufsize)
|
||||
uint64_t d_abs_write_offset; // num items written since the start
|
||||
bool d_done;
|
||||
uint64_t d_last_min_items_read;
|
||||
|
||||
unsigned index_add(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned s = a + b;
|
||||
|
||||
if(s >= d_bufsize)
|
||||
s -= d_bufsize;
|
||||
|
||||
assert(s < d_bufsize);
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned index_sub(unsigned a, unsigned b)
|
||||
{
|
||||
int s = a - b;
|
||||
|
||||
if(s < 0)
|
||||
s += d_bufsize;
|
||||
|
||||
assert((unsigned) s < d_bufsize);
|
||||
return s;
|
||||
}
|
||||
|
||||
virtual bool allocate_buffer(int nitems, size_t sizeof_item);
|
||||
|
||||
/*!
|
||||
* \brief constructor is private. Use gr_make_buffer to create instances.
|
||||
*
|
||||
* Allocate a buffer that holds at least \p nitems of size \p sizeof_item.
|
||||
*
|
||||
* \param nitems is the minimum number of items the buffer will hold.
|
||||
* \param sizeof_item is the size of an item in bytes.
|
||||
* \param link is the block that writes to this buffer.
|
||||
*
|
||||
* The total size of the buffer will be rounded up to a system
|
||||
* dependent boundary. This is typically the system page size, but
|
||||
* under MS windows is 64KB.
|
||||
*/
|
||||
buffer(int nitems, size_t sizeof_item, block_sptr link);
|
||||
|
||||
/*!
|
||||
* \brief disassociate \p reader from this buffer
|
||||
*/
|
||||
void drop_reader(buffer_reader *reader);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Create a new gr::buffer_reader and attach it to buffer \p buf
|
||||
* \param buf is the buffer the \p gr::buffer_reader reads from.
|
||||
* \param nzero_preload -- number of zero items to "preload" into buffer.
|
||||
* \param link is the block that reads from the buffer using this gr::buffer_reader.
|
||||
*/
|
||||
GR_RUNTIME_API buffer_reader_sptr
|
||||
buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link=block_sptr());
|
||||
|
||||
//! returns # of buffers currently allocated
|
||||
GR_RUNTIME_API long buffer_ncurrently_allocated();
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/*!
|
||||
* \brief How we keep track of the readers of a gr::buffer.
|
||||
* \ingroup internal
|
||||
*/
|
||||
class GR_RUNTIME_API buffer_reader
|
||||
{
|
||||
public:
|
||||
~buffer_reader();
|
||||
|
||||
/*!
|
||||
* \brief Return number of items available for reading.
|
||||
*/
|
||||
int items_available() const;
|
||||
|
||||
/*!
|
||||
* \brief Return buffer this reader reads from.
|
||||
*/
|
||||
buffer_sptr buffer() const { return d_buffer; }
|
||||
|
||||
/*!
|
||||
* \brief Return maximum number of items that could ever be available for reading.
|
||||
* This is used as a sanity check in the scheduler to avoid looping forever.
|
||||
*/
|
||||
int max_possible_items_available() const { return d_buffer->d_bufsize - 1; }
|
||||
|
||||
/*!
|
||||
* \brief return pointer to read buffer.
|
||||
*
|
||||
* The return value points to items_available() number of items
|
||||
*/
|
||||
const void *read_pointer();
|
||||
|
||||
/*
|
||||
* \brief tell buffer we read \p items from it
|
||||
*/
|
||||
void update_read_pointer(int nitems);
|
||||
|
||||
void set_done(bool done) { d_buffer->set_done(done); }
|
||||
bool done() const { return d_buffer->done(); }
|
||||
|
||||
gr::thread::mutex *mutex() { return d_buffer->mutex(); }
|
||||
|
||||
uint64_t nitems_read() { return d_abs_read_offset; }
|
||||
|
||||
size_t get_sizeof_item() { return d_buffer->get_sizeof_item(); }
|
||||
|
||||
/*!
|
||||
* \brief Return the block that reads via this reader.
|
||||
*
|
||||
*/
|
||||
block_sptr link() { return block_sptr(d_link); }
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
friend class buffer;
|
||||
friend GR_RUNTIME_API buffer_reader_sptr
|
||||
buffer_add_reader(buffer_sptr buf, int nzero_preload, block_sptr link);
|
||||
|
||||
buffer_sptr d_buffer;
|
||||
unsigned int d_read_index; // in items [0,d->buffer.d_bufsize)
|
||||
uint64_t d_abs_read_offset; // num items seen since the start
|
||||
boost::weak_ptr<block> d_link; // block that reads via this buffer reader
|
||||
|
||||
//! constructor is private. Use gr::buffer::add_reader to create instances
|
||||
buffer_reader(buffer_sptr buffer, unsigned int read_index, block_sptr link);
|
||||
};
|
||||
|
||||
//! returns # of buffer_readers currently allocated
|
||||
GR_RUNTIME_API long buffer_reader_ncurrently_allocated ();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_BUFFER_H */
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2006,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_CONSTANTS_H
|
||||
#define INCLUDED_GR_CONSTANTS_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <string>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief return SYSCONFDIR. Typically ${CMAKE_INSTALL_PREFIX}/etc or /etc
|
||||
*/
|
||||
GR_RUNTIME_API const std::string prefix();
|
||||
|
||||
/*!
|
||||
* \brief return SYSCONFDIR. Typically ${CMAKE_INSTALL_PREFIX}/etc or /etc
|
||||
*/
|
||||
GR_RUNTIME_API const std::string sysconfdir();
|
||||
|
||||
/*!
|
||||
* \brief return preferences file directory. Typically ${SYSCONFDIR}/etc/conf.d
|
||||
*/
|
||||
GR_RUNTIME_API const std::string prefsdir();
|
||||
|
||||
/*!
|
||||
* \brief return date/time of build, as set when 'cmake' is run
|
||||
*/
|
||||
GR_RUNTIME_API const std::string build_date();
|
||||
|
||||
/*!
|
||||
* \brief return version string defined by cmake (GrVersion.cmake)
|
||||
*/
|
||||
GR_RUNTIME_API const std::string version();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_CONSTANTS_H */
|
|
@ -0,0 +1,32 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_ENDIANNESS_H
|
||||
#define INCLUDED_GR_ENDIANNESS_H
|
||||
|
||||
namespace gr {
|
||||
|
||||
typedef enum {GR_MSB_FIRST, GR_LSB_FIRST} endianness_t;
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_ENDIANNESS_H */
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- 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_EXPJ_H
|
||||
#define INCLUDED_GR_EXPJ_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/sincos.h>
|
||||
#include <gnuradio/types.h>
|
||||
|
||||
static inline gr_complex
|
||||
gr_expj(float phase)
|
||||
{
|
||||
float t_imag, t_real;
|
||||
gr::sincosf(phase, &t_imag, &t_real);
|
||||
return gr_complex(t_real, t_imag);
|
||||
}
|
||||
|
||||
|
||||
#endif /* INCLUDED_GR_EXPJ_H */
|
|
@ -0,0 +1,186 @@
|
|||
/* -*- 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_FEVAL_H
|
||||
#define INCLUDED_GR_FEVAL_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief base class for evaluating a function: double -> double
|
||||
* \ingroup misc
|
||||
*
|
||||
* This class is designed to be subclassed in Python or C++ and is
|
||||
* callable from both places. It uses SWIG's "director" feature to
|
||||
* implement the magic.
|
||||
*
|
||||
* It's slow. Don't use it in a performance critical path.
|
||||
*
|
||||
* Override eval to define the behavior.
|
||||
* Use calleval to invoke eval (this kludge is required to allow a
|
||||
* python specific "shim" to be inserted.
|
||||
*/
|
||||
class GR_RUNTIME_API feval_dd
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief override this to define the function
|
||||
*/
|
||||
virtual double eval(double x);
|
||||
|
||||
public:
|
||||
feval_dd() {}
|
||||
virtual ~feval_dd();
|
||||
|
||||
virtual double calleval(double x); // invoke "eval"
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief base class for evaluating a function: complex -> complex
|
||||
* \ingroup misc
|
||||
*
|
||||
* This class is designed to be subclassed in Python or C++ and is
|
||||
* callable from both places. It uses SWIG's "director" feature to
|
||||
* implement the magic.
|
||||
*
|
||||
* It's slow. Don't use it in a performance critical path.
|
||||
*
|
||||
* Override eval to define the behavior.
|
||||
* Use calleval to invoke eval (this kludge is required to allow a
|
||||
* python specific "shim" to be inserted.
|
||||
*/
|
||||
class GR_RUNTIME_API feval_cc
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief override this to define the function
|
||||
*/
|
||||
virtual gr_complex eval(gr_complex x);
|
||||
|
||||
public:
|
||||
feval_cc() {}
|
||||
virtual ~feval_cc();
|
||||
|
||||
virtual gr_complex calleval(gr_complex x); // invoke "eval"
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief base class for evaluating a function: long -> long
|
||||
* \ingroup misc
|
||||
*
|
||||
* This class is designed to be subclassed in Python or C++ and is
|
||||
* callable from both places. It uses SWIG's "director" feature to
|
||||
* implement the magic.
|
||||
*
|
||||
* It's slow. Don't use it in a performance critical path.
|
||||
*
|
||||
* Override eval to define the behavior.
|
||||
* Use calleval to invoke eval (this kludge is required to allow a
|
||||
* python specific "shim" to be inserted.
|
||||
*/
|
||||
class GR_RUNTIME_API feval_ll
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief override this to define the function
|
||||
*/
|
||||
virtual long eval(long x);
|
||||
|
||||
public:
|
||||
feval_ll() {}
|
||||
virtual ~feval_ll();
|
||||
|
||||
virtual long calleval(long x); // invoke "eval"
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief base class for evaluating a function: void -> void
|
||||
* \ingroup misc
|
||||
*
|
||||
* This class is designed to be subclassed in Python or C++ and is
|
||||
* callable from both places. It uses SWIG's "director" feature to
|
||||
* implement the magic.
|
||||
*
|
||||
* It's slow. Don't use it in a performance critical path.
|
||||
*
|
||||
* Override eval to define the behavior.
|
||||
* Use calleval to invoke eval (this kludge is required to allow a
|
||||
* python specific "shim" to be inserted.
|
||||
*/
|
||||
class GR_RUNTIME_API feval
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief override this to define the function
|
||||
*/
|
||||
virtual void eval();
|
||||
|
||||
public:
|
||||
feval() {}
|
||||
virtual ~feval();
|
||||
|
||||
virtual void calleval(); // invoke "eval"
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief base class for evaluating a function: pmt -> void
|
||||
* \ingroup misc
|
||||
*
|
||||
* This class is designed to be subclassed in Python or C++ and is
|
||||
* callable from both places. It uses SWIG's "director" feature to
|
||||
* implement the magic.
|
||||
*
|
||||
* It's slow. Don't use it in a performance critical path.
|
||||
*
|
||||
* Override eval to define the behavior.
|
||||
* Use calleval to invoke eval (this kludge is required to allow a
|
||||
* python specific "shim" to be inserted.
|
||||
*/
|
||||
class GR_RUNTIME_API feval_p
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* \brief override this to define the function
|
||||
*/
|
||||
virtual void eval(double);
|
||||
|
||||
public:
|
||||
feval_p() {}
|
||||
virtual ~feval_p();
|
||||
|
||||
virtual void calleval(double); // invoke "eval"
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief trivial examples / test cases showing C++ calling Python code
|
||||
*/
|
||||
GR_RUNTIME_API double feval_dd_example(feval_dd *f, double x);
|
||||
GR_RUNTIME_API gr_complex feval_cc_example(feval_cc *f, gr_complex x);
|
||||
GR_RUNTIME_API long feval_ll_example(feval_ll *f, long x);
|
||||
GR_RUNTIME_API void feval_example(feval *f);
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_FEVAL_H */
|
|
@ -0,0 +1,194 @@
|
|||
/* -*- 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_FLOWGRAPH_H
|
||||
#define INCLUDED_GR_RUNTIME_FLOWGRAPH_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/basic_block.h>
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <iostream>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Class representing a specific input or output graph endpoint
|
||||
* \ingroup internal
|
||||
*/
|
||||
class GR_RUNTIME_API endpoint
|
||||
{
|
||||
private:
|
||||
basic_block_sptr d_basic_block;
|
||||
int d_port;
|
||||
|
||||
public:
|
||||
endpoint() : d_basic_block(), d_port(0) { }
|
||||
endpoint(basic_block_sptr block, int port) { d_basic_block = block; d_port = port; }
|
||||
basic_block_sptr block() const { return d_basic_block; }
|
||||
int port() const { return d_port; }
|
||||
|
||||
bool operator==(const endpoint &other) const;
|
||||
};
|
||||
|
||||
inline bool endpoint::operator==(const endpoint &other) const
|
||||
{
|
||||
return (d_basic_block == other.d_basic_block &&
|
||||
d_port == other.d_port);
|
||||
}
|
||||
|
||||
// Hold vectors of gr::endpoint objects
|
||||
typedef std::vector<endpoint> endpoint_vector_t;
|
||||
typedef std::vector<endpoint>::iterator endpoint_viter_t;
|
||||
|
||||
/*!
|
||||
*\brief Class representing a connection between to graph endpoints
|
||||
*/
|
||||
class GR_RUNTIME_API edge
|
||||
{
|
||||
public:
|
||||
edge() : d_src(), d_dst() { };
|
||||
edge(const endpoint &src, const endpoint &dst)
|
||||
: d_src(src), d_dst(dst) { }
|
||||
~edge();
|
||||
|
||||
const endpoint &src() const { return d_src; }
|
||||
const endpoint &dst() const { return d_dst; }
|
||||
|
||||
private:
|
||||
endpoint d_src;
|
||||
endpoint d_dst;
|
||||
};
|
||||
|
||||
// Hold vectors of gr::edge objects
|
||||
typedef std::vector<edge> edge_vector_t;
|
||||
typedef std::vector<edge>::iterator edge_viter_t;
|
||||
|
||||
// Create a shared pointer to a heap allocated flowgraph
|
||||
// (types defined in runtime_types.h)
|
||||
GR_RUNTIME_API flowgraph_sptr make_flowgraph();
|
||||
|
||||
/*!
|
||||
* \brief Class representing a directed, acyclic graph of basic blocks
|
||||
* \ingroup internal
|
||||
*/
|
||||
class GR_RUNTIME_API flowgraph
|
||||
{
|
||||
public:
|
||||
friend GR_RUNTIME_API flowgraph_sptr make_flowgraph();
|
||||
|
||||
// Destruct an arbitrary flowgraph
|
||||
~flowgraph();
|
||||
|
||||
// Connect two endpoints
|
||||
void connect(const endpoint &src, const endpoint &dst);
|
||||
|
||||
// Disconnect two endpoints
|
||||
void disconnect(const endpoint &src, const endpoint &dst);
|
||||
|
||||
// Connect an output port to an input port (convenience)
|
||||
void connect(basic_block_sptr src_block, int src_port,
|
||||
basic_block_sptr dst_block, int dst_port);
|
||||
|
||||
// Disconnect an input port from an output port (convenience)
|
||||
void disconnect(basic_block_sptr src_block, int src_port,
|
||||
basic_block_sptr dst_block, int dst_port);
|
||||
|
||||
// Validate connectivity, raise exception if invalid
|
||||
void validate();
|
||||
|
||||
// Clear existing flowgraph
|
||||
void clear();
|
||||
|
||||
// Return vector of edges
|
||||
const edge_vector_t &edges() const { return d_edges; }
|
||||
|
||||
// Return vector of connected blocks
|
||||
basic_block_vector_t calc_used_blocks();
|
||||
|
||||
// Return toplogically sorted vector of blocks. All the sources come first.
|
||||
basic_block_vector_t topological_sort(basic_block_vector_t &blocks);
|
||||
|
||||
// Return vector of vectors of disjointly connected blocks,
|
||||
// topologically sorted.
|
||||
std::vector<basic_block_vector_t> partition();
|
||||
|
||||
protected:
|
||||
basic_block_vector_t d_blocks;
|
||||
edge_vector_t d_edges;
|
||||
|
||||
flowgraph();
|
||||
std::vector<int> calc_used_ports(basic_block_sptr block, bool check_inputs);
|
||||
basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port);
|
||||
edge_vector_t calc_upstream_edges(basic_block_sptr block);
|
||||
bool has_block_p(basic_block_sptr block);
|
||||
edge calc_upstream_edge(basic_block_sptr block, int port);
|
||||
|
||||
private:
|
||||
void check_valid_port(gr::io_signature::sptr sig, int port);
|
||||
void check_dst_not_used(const endpoint &dst);
|
||||
void check_type_match(const endpoint &src, const endpoint &dst);
|
||||
edge_vector_t calc_connections(basic_block_sptr block, bool check_inputs); // false=use outputs
|
||||
void check_contiguity(basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs);
|
||||
|
||||
basic_block_vector_t calc_downstream_blocks(basic_block_sptr block);
|
||||
basic_block_vector_t calc_reachable_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
|
||||
void reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t &blocks);
|
||||
basic_block_vector_t calc_adjacent_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
|
||||
basic_block_vector_t sort_sources_first(basic_block_vector_t &blocks);
|
||||
bool source_p(basic_block_sptr block);
|
||||
void topological_dfs_visit(basic_block_sptr block, basic_block_vector_t &output);
|
||||
};
|
||||
|
||||
// Convenience functions
|
||||
inline
|
||||
void flowgraph::connect(basic_block_sptr src_block, int src_port,
|
||||
basic_block_sptr dst_block, int dst_port)
|
||||
{
|
||||
connect(endpoint(src_block, src_port),
|
||||
endpoint(dst_block, dst_port));
|
||||
}
|
||||
|
||||
inline
|
||||
void flowgraph::disconnect(basic_block_sptr src_block, int src_port,
|
||||
basic_block_sptr dst_block, int dst_port)
|
||||
{
|
||||
disconnect(endpoint(src_block, src_port),
|
||||
endpoint(dst_block, dst_port));
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator <<(std::ostream &os, const endpoint endp)
|
||||
{
|
||||
os << endp.block()->alias() << ":" << endp.port();
|
||||
return os;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator <<(std::ostream &os, const edge edge)
|
||||
{
|
||||
os << edge.src() << "->" << edge.dst();
|
||||
return os;
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_FLOWGRAPH_H */
|
|
@ -0,0 +1,108 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_FXPT_H
|
||||
#define INCLUDED_GR_FXPT_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/types.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief fixed point sine and cosine and friends.
|
||||
* \ingroup misc
|
||||
*
|
||||
* fixed pt radians
|
||||
* --------- --------
|
||||
* -2**31 -pi
|
||||
* 0 0
|
||||
* 2**31-1 pi - epsilon
|
||||
*/
|
||||
class GR_RUNTIME_API fxpt
|
||||
{
|
||||
static const int WORDBITS = 32;
|
||||
static const int NBITS = 10;
|
||||
static const float s_sine_table[1 << NBITS][2];
|
||||
static const float PI;
|
||||
static const float TWO_TO_THE_31;
|
||||
|
||||
public:
|
||||
static gr_int32
|
||||
float_to_fixed(float x)
|
||||
{
|
||||
// Fold x into -PI to PI.
|
||||
int d = (int)floor(x/2/PI+0.5);
|
||||
x -= d*2*PI;
|
||||
// And convert to an integer.
|
||||
return (gr_int32) ((float) x * TWO_TO_THE_31 / PI);
|
||||
}
|
||||
|
||||
static float
|
||||
fixed_to_float (gr_int32 x)
|
||||
{
|
||||
return x * (PI / TWO_TO_THE_31);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Given a fixed point angle x, return float sine (x)
|
||||
*/
|
||||
static float
|
||||
sin(gr_int32 x)
|
||||
{
|
||||
gr_uint32 ux = x;
|
||||
int index = ux >> (WORDBITS - NBITS);
|
||||
return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Given a fixed point angle x, return float cosine (x)
|
||||
*/
|
||||
static float
|
||||
cos (gr_int32 x)
|
||||
{
|
||||
gr_uint32 ux = x + 0x40000000;
|
||||
int index = ux >> (WORDBITS - NBITS);
|
||||
return s_sine_table[index][0] * (ux >> 1) + s_sine_table[index][1];
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Given a fixedpoint angle x, return float cos(x) and sin (x)
|
||||
*/
|
||||
static void sincos(gr_int32 x, float *s, float *c)
|
||||
{
|
||||
gr_uint32 ux = x;
|
||||
int sin_index = ux >> (WORDBITS - NBITS);
|
||||
*s = s_sine_table[sin_index][0] * (ux >> 1) + s_sine_table[sin_index][1];
|
||||
|
||||
ux = x + 0x40000000;
|
||||
int cos_index = ux >> (WORDBITS - NBITS);
|
||||
*c = s_sine_table[cos_index][0] * (ux >> 1) + s_sine_table[cos_index][1];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_FXPT_H */
|
|
@ -0,0 +1,160 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2002,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_FXPT_NCO_H
|
||||
#define INCLUDED_GR_FXPT_NCO_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/fxpt.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Numerically Controlled Oscillator (NCO)
|
||||
* \ingroup misc
|
||||
*/
|
||||
class /*GR_RUNTIME_API*/ fxpt_nco
|
||||
{
|
||||
uint32_t d_phase;
|
||||
int32_t d_phase_inc;
|
||||
|
||||
public:
|
||||
fxpt_nco() : d_phase(0), d_phase_inc(0) {}
|
||||
|
||||
~fxpt_nco() {}
|
||||
|
||||
// radians
|
||||
void set_phase(float angle) {
|
||||
d_phase = gr::fxpt::float_to_fixed(angle);
|
||||
}
|
||||
|
||||
void adjust_phase(float delta_phase) {
|
||||
d_phase += gr::fxpt::float_to_fixed(delta_phase);
|
||||
}
|
||||
|
||||
// angle_rate is in radians / step
|
||||
void set_freq(float angle_rate){
|
||||
d_phase_inc = gr::fxpt::float_to_fixed(angle_rate);
|
||||
}
|
||||
|
||||
// angle_rate is a delta in radians / step
|
||||
void adjust_freq(float delta_angle_rate)
|
||||
{
|
||||
d_phase_inc += gr::fxpt::float_to_fixed(delta_angle_rate);
|
||||
}
|
||||
|
||||
// increment current phase angle
|
||||
|
||||
void step()
|
||||
{
|
||||
d_phase += d_phase_inc;
|
||||
}
|
||||
|
||||
void step(int n)
|
||||
{
|
||||
d_phase += d_phase_inc * n;
|
||||
}
|
||||
|
||||
// units are radians / step
|
||||
float get_phase() const { return gr::fxpt::fixed_to_float(d_phase); }
|
||||
float get_freq() const { return gr::fxpt::fixed_to_float(d_phase_inc); }
|
||||
|
||||
// compute sin and cos for current phase angle
|
||||
void sincos(float *sinx, float *cosx) const
|
||||
{
|
||||
*sinx = gr::fxpt::sin(d_phase);
|
||||
*cosx = gr::fxpt::cos(d_phase);
|
||||
}
|
||||
|
||||
// compute cos and sin for a block of phase angles
|
||||
void sincos(gr_complex *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = gr_complex(gr::fxpt::cos(d_phase) * ampl, gr::fxpt::sin(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute sin for a block of phase angles
|
||||
void sin(float *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (float)(gr::fxpt::sin(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute cos for a block of phase angles
|
||||
void cos(float *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (float)(gr::fxpt::cos(d_phase) * ampl);
|
||||
step ();
|
||||
}
|
||||
}
|
||||
|
||||
// compute sin for a block of phase angles
|
||||
void sin(short *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (short)(gr::fxpt::sin(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute cos for a block of phase angles
|
||||
void cos(short *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (short)(gr::fxpt::cos(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute sin for a block of phase angles
|
||||
void sin(int *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (int)(gr::fxpt::sin(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute cos for a block of phase angles
|
||||
void cos(int *output, int noutput_items, double ampl=1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (int)(gr::fxpt::cos(d_phase) * ampl);
|
||||
step();
|
||||
}
|
||||
}
|
||||
|
||||
// compute cos or sin for current phase angle
|
||||
float cos() const { return gr::fxpt::cos(d_phase); }
|
||||
float sin() const { return gr::fxpt::sin(d_phase); }
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_FXPT_NCO_H */
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2002,2004,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 INCLUDED_GR_FXPT_VCO_H
|
||||
#define INCLUDED_GR_FXPT_VCO_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/fxpt.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Voltage Controlled Oscillator (VCO)
|
||||
* \ingroup misc
|
||||
*/
|
||||
class /*GR_RUNTIME_API*/ fxpt_vco {
|
||||
gr_int32 d_phase;
|
||||
|
||||
public:
|
||||
fxpt_vco () : d_phase(0) {}
|
||||
|
||||
~fxpt_vco() {}
|
||||
|
||||
// radians
|
||||
void set_phase(float angle) {
|
||||
d_phase = fxpt::float_to_fixed(angle);
|
||||
}
|
||||
|
||||
void adjust_phase(float delta_phase) {
|
||||
d_phase += fxpt::float_to_fixed(delta_phase);
|
||||
}
|
||||
|
||||
float get_phase() const {
|
||||
return fxpt::fixed_to_float(d_phase);
|
||||
}
|
||||
|
||||
// compute sin and cos for current phase angle
|
||||
void sincos(float *sinx, float *cosx) const
|
||||
{
|
||||
*sinx = fxpt::sin(d_phase);
|
||||
*cosx = fxpt::cos(d_phase);
|
||||
}
|
||||
|
||||
// compute a block at a time
|
||||
void cos(float *output, const float *input, int noutput_items, float k, float ampl = 1.0)
|
||||
{
|
||||
for(int i = 0; i < noutput_items; i++) {
|
||||
output[i] = (float)(fxpt::cos(d_phase) * ampl);
|
||||
adjust_phase(input[i] * k);
|
||||
}
|
||||
}
|
||||
|
||||
// compute cos or sin for current phase angle
|
||||
float cos() const { return fxpt::cos(d_phase); }
|
||||
float sin() const { return fxpt::sin(d_phase); }
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_FXPT_VCO_H */
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_COMPLEX_H
|
||||
#define INCLUDED_GR_COMPLEX_H
|
||||
|
||||
#include <complex>
|
||||
typedef std::complex<float> gr_complex;
|
||||
typedef std::complex<double> gr_complexd;
|
||||
|
||||
inline bool is_complex (gr_complex x) { (void) x; return true;}
|
||||
inline bool is_complex (gr_complexd x) { (void) x; return true;}
|
||||
inline bool is_complex (float x) { (void) x; return false;}
|
||||
inline bool is_complex (double x) { (void) x; return false;}
|
||||
inline bool is_complex (int x) { (void) x; return false;}
|
||||
inline bool is_complex (char x) { (void) x; return false;}
|
||||
inline bool is_complex (short x) { (void) x; return false;}
|
||||
|
||||
// this doesn't really belong here, but there are worse places for it...
|
||||
|
||||
#define CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected,actual,delta) \
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.real(), actual.real(), delta); \
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL (expected.imag(), actual.imag(), delta);
|
||||
|
||||
#endif /* INCLUDED_GR_COMPLEX_H */
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2006-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_H
|
||||
#define INCLUDED_GR_RUNTIME_HIER_BLOCK2_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/basic_block.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief public constructor for hier_block2
|
||||
*/
|
||||
GR_RUNTIME_API hier_block2_sptr
|
||||
make_hier_block2(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
class hier_block2_detail;
|
||||
|
||||
/*!
|
||||
* \brief Hierarchical container class for gr::block's and gr::hier_block2's
|
||||
* \ingroup container_blk
|
||||
* \ingroup base_blk
|
||||
*/
|
||||
class GR_RUNTIME_API hier_block2 : public basic_block
|
||||
{
|
||||
private:
|
||||
friend class hier_block2_detail;
|
||||
friend GR_RUNTIME_API hier_block2_sptr
|
||||
make_hier_block2(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
/*!
|
||||
* \brief Private implementation details of gr::hier_block2
|
||||
*/
|
||||
hier_block2_detail *d_detail;
|
||||
|
||||
protected:
|
||||
hier_block2(void) {} // allows pure virtual interface sub-classes
|
||||
hier_block2(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
public:
|
||||
virtual ~hier_block2();
|
||||
|
||||
/*!
|
||||
* \brief typedef for object returned from self().
|
||||
*
|
||||
* This type is only guaranteed to be passable to connect and
|
||||
* disconnect. No other assumptions should be made about it.
|
||||
*/
|
||||
typedef basic_block_sptr opaque_self;
|
||||
|
||||
/*!
|
||||
* \brief Return an object, representing the current block, which
|
||||
* can be passed to connect.
|
||||
*
|
||||
* The returned object may only be used as an argument to connect
|
||||
* or disconnect. Any other use of self() results in unspecified
|
||||
* (erroneous) behavior.
|
||||
*/
|
||||
opaque_self self();
|
||||
|
||||
/*!
|
||||
* \brief Add a stand-alone (possibly hierarchical) block to
|
||||
* internal graph
|
||||
*
|
||||
* This adds a gr-block or hierarchical block to the internal
|
||||
* graph without wiring it to anything else.
|
||||
*/
|
||||
void connect(basic_block_sptr block);
|
||||
|
||||
/*!
|
||||
* \brief Add gr-blocks or hierarchical blocks to internal graph
|
||||
* and wire together
|
||||
*
|
||||
* This adds (if not done earlier by another connect) a pair of
|
||||
* gr-blocks or hierarchical blocks to the internal flowgraph, and
|
||||
* wires the specified output port to the specified input port.
|
||||
*/
|
||||
void connect(basic_block_sptr src, int src_port,
|
||||
basic_block_sptr dst, int dst_port);
|
||||
|
||||
/*!
|
||||
* \brief Remove a gr-block or hierarchical block from the
|
||||
* internal flowgraph.
|
||||
*
|
||||
* This removes a gr-block or hierarchical block from the internal
|
||||
* flowgraph, disconnecting it from other blocks as needed.
|
||||
*/
|
||||
void disconnect(basic_block_sptr block);
|
||||
|
||||
/*!
|
||||
* \brief Disconnect a pair of gr-blocks or hierarchical blocks in
|
||||
* internal flowgraph.
|
||||
*
|
||||
* This disconnects the specified input port from the specified
|
||||
* output port of a pair of gr-blocks or hierarchical blocks.
|
||||
*/
|
||||
void disconnect(basic_block_sptr src, int src_port,
|
||||
basic_block_sptr dst, int dst_port);
|
||||
|
||||
/*!
|
||||
* \brief Disconnect all connections in the internal flowgraph.
|
||||
*
|
||||
* This call removes all output port to input port connections in
|
||||
* the internal flowgraph.
|
||||
*/
|
||||
void disconnect_all();
|
||||
|
||||
/*!
|
||||
* Lock a flowgraph in preparation for reconfiguration. When an
|
||||
* equal number of calls to lock() and unlock() have occurred, the
|
||||
* flowgraph will be reconfigured.
|
||||
*
|
||||
* N.B. lock() and unlock() may not be called from a flowgraph
|
||||
* thread (E.g., gr::block::work method) or deadlock will occur
|
||||
* when reconfiguration happens.
|
||||
*/
|
||||
virtual void lock();
|
||||
|
||||
/*!
|
||||
* Unlock a flowgraph in preparation for reconfiguration. When an
|
||||
* equal number of calls to lock() and unlock() have occurred, the
|
||||
* flowgraph will be reconfigured.
|
||||
*
|
||||
* N.B. lock() and unlock() may not be called from a flowgraph
|
||||
* thread (E.g., gr::block::work method) or deadlock will occur
|
||||
* when reconfiguration happens.
|
||||
*/
|
||||
virtual void unlock();
|
||||
|
||||
// This is a public method for ease of code organization, but should be
|
||||
// ignored by the user.
|
||||
flat_flowgraph_sptr flatten() const;
|
||||
|
||||
hier_block2_sptr to_hier_block2(); // Needed for Python type coercion
|
||||
|
||||
/*!
|
||||
* \brief Set the affinity of all blocks in hier_block2 to processor core \p n.
|
||||
*
|
||||
* \param mask a vector of ints of the core numbers available to this block.
|
||||
*/
|
||||
void set_processor_affinity(const std::vector<int> &mask);
|
||||
|
||||
/*!
|
||||
* \brief Remove processor affinity for all blocks in hier_block2.
|
||||
*/
|
||||
void unset_processor_affinity();
|
||||
|
||||
/*!
|
||||
* \brief Get the current processor affinity.
|
||||
*
|
||||
* \details This returns the processor affinity value for the first
|
||||
* block in the hier_block2's list of blocks with the assumption
|
||||
* that they have always only been set through the hier_block2's
|
||||
* interface. If any block has been individually set, then this
|
||||
* call could be misleading.
|
||||
*/
|
||||
std::vector<int> processor_affinity();
|
||||
};
|
||||
|
||||
inline hier_block2_sptr cast_to_hier_block2_sptr(basic_block_sptr block) {
|
||||
return boost::dynamic_pointer_cast<hier_block2, basic_block>(block);
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_HIER_BLOCK2_H */
|
|
@ -0,0 +1,156 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GNURADIO_HIGH_RES_TIMER_H
|
||||
#define INCLUDED_GNURADIO_HIGH_RES_TIMER_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Use architecture defines to determine the implementation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__)
|
||||
#define GNURADIO_HRT_USE_CLOCK_GETTIME
|
||||
#include <ctime>
|
||||
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
#define GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||
#define GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define GNURADIO_HRT_USE_CLOCK_GETTIME
|
||||
#include <ctime>
|
||||
#else
|
||||
#define GNURADIO_HRT_USE_MICROSEC_CLOCK
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
namespace gr {
|
||||
|
||||
//! Typedef for the timer tick count
|
||||
typedef signed long long high_res_timer_type;
|
||||
|
||||
//! Get the current time in ticks
|
||||
high_res_timer_type high_res_timer_now(void);
|
||||
|
||||
//! Get the current time in ticks - for performance monitoring
|
||||
high_res_timer_type high_res_timer_now_perfmon(void);
|
||||
|
||||
//! Get the number of ticks per second
|
||||
high_res_timer_type high_res_timer_tps(void);
|
||||
|
||||
//! Get the tick count at the epoch
|
||||
high_res_timer_type high_res_timer_epoch(void);
|
||||
|
||||
#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME
|
||||
//! storage for high res timer type
|
||||
GR_RUNTIME_API extern clockid_t high_res_timer_source;
|
||||
#endif
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now(void){
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return ts.tv_sec*high_res_timer_tps() + ts.tv_nsec;
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now_perfmon(void){
|
||||
timespec ts;
|
||||
clock_gettime(high_res_timer_source, &ts);
|
||||
return ts.tv_sec*high_res_timer_tps() + ts.tv_nsec;
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_tps(void){
|
||||
return 1000000000UL;
|
||||
}
|
||||
#endif /* GNURADIO_HRT_USE_CLOCK_GETTIME */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef GNURADIO_HRT_USE_MACH_ABSOLUTE_TIME
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now(void){
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now_perfmon(void){
|
||||
return gr::high_res_timer_now();
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_tps(void){
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
return gr::high_res_timer_type(info.numer*1000000000UL)/info.denom;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef GNURADIO_HRT_USE_QUERY_PERFORMANCE_COUNTER
|
||||
#include <Windows.h>
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now(void){
|
||||
LARGE_INTEGER counts;
|
||||
QueryPerformanceCounter(&counts);
|
||||
return counts.QuadPart;
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now_perfmon(void){
|
||||
return gr::high_res_timer_now();
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_tps(void){
|
||||
LARGE_INTEGER freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
return freq.QuadPart;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#ifdef GNURADIO_HRT_USE_MICROSEC_CLOCK
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now(void){
|
||||
static const boost::posix_time::ptime epoch(boost::posix_time::from_time_t(0));
|
||||
return (boost::posix_time::microsec_clock::universal_time() - epoch).ticks();
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_now_perfmon(void){
|
||||
return gr::high_res_timer_now();
|
||||
}
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_tps(void){
|
||||
return boost::posix_time::time_duration::ticks_per_second();
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
inline gr::high_res_timer_type gr::high_res_timer_epoch(void){
|
||||
static const double hrt_ticks_per_utc_ticks = gr::high_res_timer_tps()/double(boost::posix_time::time_duration::ticks_per_second());
|
||||
boost::posix_time::time_duration utc = boost::posix_time::microsec_clock::universal_time() - boost::posix_time::from_time_t(0);
|
||||
return gr::high_res_timer_now() - utc.ticks()*hrt_ticks_per_utc_ticks;
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_GNURADIO_HIGH_RES_TIMER_H */
|
|
@ -0,0 +1,111 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_IO_SIGNATURE_H
|
||||
#define INCLUDED_IO_SIGNATURE_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/runtime_types.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief i/o signature for input and output ports.
|
||||
* \brief misc
|
||||
*/
|
||||
class GR_RUNTIME_API io_signature
|
||||
{
|
||||
int d_min_streams;
|
||||
int d_max_streams;
|
||||
std::vector<int> d_sizeof_stream_item;
|
||||
|
||||
io_signature(int min_streams, int max_streams,
|
||||
const std::vector<int> &sizeof_stream_items);
|
||||
|
||||
public:
|
||||
typedef boost::shared_ptr<io_signature> sptr;
|
||||
|
||||
static const int IO_INFINITE = -1;
|
||||
|
||||
~io_signature();
|
||||
|
||||
/*!
|
||||
* \brief Create an i/o signature
|
||||
*
|
||||
* \ingroup internal
|
||||
* \param min_streams specify minimum number of streams (>= 0)
|
||||
* \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
|
||||
* \param sizeof_stream_item specify the size of the items in each stream
|
||||
*/
|
||||
static sptr make(int min_streams, int max_streams,
|
||||
int sizeof_stream_item);
|
||||
|
||||
/*!
|
||||
* \brief Create an i/o signature
|
||||
*
|
||||
* \param min_streams specify minimum number of streams (>= 0)
|
||||
* \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
|
||||
* \param sizeof_stream_item1 specify the size of the items in the first stream
|
||||
* \param sizeof_stream_item2 specify the size of the items in the second and subsequent streams
|
||||
*/
|
||||
static sptr make2(int min_streams, int max_streams,
|
||||
int sizeof_stream_item1,
|
||||
int sizeof_stream_item2);
|
||||
|
||||
/*!
|
||||
* \brief Create an i/o signature
|
||||
*
|
||||
* \param min_streams specify minimum number of streams (>= 0)
|
||||
* \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
|
||||
* \param sizeof_stream_item1 specify the size of the items in the first stream
|
||||
* \param sizeof_stream_item2 specify the size of the items in the second stream
|
||||
* \param sizeof_stream_item3 specify the size of the items in the third and subsequent streams
|
||||
*/
|
||||
static sptr make3(int min_streams, int max_streams,
|
||||
int sizeof_stream_item1,
|
||||
int sizeof_stream_item2,
|
||||
int sizeof_stream_item3);
|
||||
|
||||
/*!
|
||||
* \brief Create an i/o signature
|
||||
*
|
||||
* \param min_streams specify minimum number of streams (>= 0)
|
||||
* \param max_streams specify maximum number of streams (>= min_streams or -1 -> infinite)
|
||||
* \param sizeof_stream_items specify the size of the items in the streams
|
||||
*
|
||||
* If there are more streams than there are entries in
|
||||
* sizeof_stream_items, the value of the last entry in
|
||||
* sizeof_stream_items is used for the missing values.
|
||||
* sizeof_stream_items must contain at least 1 entry.
|
||||
*/
|
||||
static sptr makev(int min_streams, int max_streams,
|
||||
const std::vector<int> &sizeof_stream_items);
|
||||
|
||||
int min_streams() const { return d_min_streams; }
|
||||
int max_streams() const { return d_max_streams; }
|
||||
int sizeof_stream_item(int index) const;
|
||||
std::vector<int> sizeof_stream_items() const;
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_IO_SIGNATURE_H */
|
|
@ -0,0 +1,733 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Author: Mark Plett
|
||||
* Description:
|
||||
* The gr::logger module wraps the log4cpp library for logging in gnuradio
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef INCLUDED_GR_LOGGER_H
|
||||
#define INCLUDED_GR_LOGGER_H
|
||||
|
||||
/*!
|
||||
* \ingroup logging
|
||||
* \brief GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ENABLE_GR_LOG
|
||||
//#cmakedefine ENABLE_GR_LOG
|
||||
#endif
|
||||
#ifndef HAVE_LOG4CPP
|
||||
//#cmakedefine HAVE_LOG4CPP
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#ifdef ENABLE_GR_LOG
|
||||
|
||||
// We have three configurations... first logging to stdout/stderr
|
||||
#ifndef HAVE_LOG4CPP
|
||||
|
||||
namespace gr {
|
||||
//#warning GR logging Enabled and using std::cout
|
||||
typedef std::string logger_ptr;
|
||||
} /* namespace gr */
|
||||
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger)
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name)
|
||||
#define GR_CONFIG_LOGGER(config)
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period)
|
||||
#define GR_LOG_GETLOGGER(logger, name)
|
||||
#define GR_SET_LEVEL(name, level)
|
||||
#define GR_LOG_SET_LEVEL(logger, level)
|
||||
#define GR_GET_LEVEL(name, level)
|
||||
#define GR_LOG_GET_LEVEL(logger, level)
|
||||
#define GR_ADD_APPENDER(name,appender)
|
||||
#define GR_LOG_ADD_APPENDER(logger,appender)
|
||||
#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_ADD_FILE_APPENDER(name,filename,append,pattern)
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern)
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_GET_LOGGER_NAMES(names)
|
||||
#define GR_RESET_CONFIGURATION()
|
||||
#define GR_DEBUG(name, msg) std::cout<<"DEBUG: "<<msg<<std::endl
|
||||
#define GR_INFO(name, msg) std::cout<<"INFO: "<<msg<<std::endl
|
||||
#define GR_NOTICE(name, msg) std::cout<<"NOTICE: "<<msg<<std::endl
|
||||
#define GR_WARN(name, msg) std::cerr<<"WARN: "<<msg<<std::endl
|
||||
#define GR_ERROR(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_ALERT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_CRIT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_FATAL(name, msg) std::cerr<<"FATAL: "<<msg<<std::endl
|
||||
#define GR_EMERG(name, msg) std::cerr<<"EMERG: "<<msg<<std::endl
|
||||
#define GR_ERRORIF(name, cond, msg) {if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;}
|
||||
#define GR_ASSERT(name, cond, msg) {if(!(cond)) std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);}
|
||||
#define GR_LOG_DEBUG(logger, msg) std::cout<<"DEBUG: "<<msg<<std::endl
|
||||
#define GR_LOG_INFO(logger, msg) std::cout<<"INFO: "<<msg<<std::endl
|
||||
#define GR_LOG_NOTICE(logger, msg) std::cout<<"NOTICE: "<<msg<<std::endl
|
||||
#define GR_LOG_WARN(logger, msg) std::cerr<<"WARN: "<<msg<<std::endl
|
||||
#define GR_LOG_ERROR(logger, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_LOG_ALERT(logger, msg) std::cerr<<"ALERT: "<<msg<<std::endl
|
||||
#define GR_LOG_CRIT(logger, msg) std::cerr<<"CRIT: "<<msg<<std::endl
|
||||
#define GR_LOG_FATAL(logger, msg) std::cerr<<"FATAL: "<<msg<<std::endl
|
||||
#define GR_LOG_EMERG(logger, msg) std::cerr<<"EMERG: "<<msg<<std::endl
|
||||
#define GR_LOG_ERRORIF(logger, cond, msg) { \
|
||||
if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;}
|
||||
#define GR_LOG_ASSERT(logger, cond, msg) { \
|
||||
if(!(cond)) {std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);};}
|
||||
|
||||
|
||||
#else /* HAVE_LOG4CPP */
|
||||
|
||||
// Second configuration...logging to log4cpp
|
||||
#include <log4cpp/Category.hh>
|
||||
#include <log4cpp/PropertyConfigurator.hh>
|
||||
#include <log4cpp/FileAppender.hh>
|
||||
#include <log4cpp/RollingFileAppender.hh>
|
||||
#include <log4cpp/OstreamAppender.hh>
|
||||
#include <log4cpp/PatternLayout.hh>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief GR_LOG macros
|
||||
* \ingroup logging
|
||||
*
|
||||
* These macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros
|
||||
* are:
|
||||
* LOG_DEBUG
|
||||
* LOG_INFO
|
||||
* LOG_WARN
|
||||
* LOG_TRACE
|
||||
* LOG_ERROR
|
||||
* LOG_ALERT
|
||||
* LOG_CRIT
|
||||
* LOG_FATAL
|
||||
* LOG_EMERG
|
||||
*/
|
||||
typedef log4cpp::Category* logger_ptr;
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
|
||||
/* Macros for Programmatic Configuration */
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger) \
|
||||
gr::logger_ptr logger;
|
||||
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name) \
|
||||
logger = gr::logger_get_logger(name);
|
||||
|
||||
#define GR_CONFIG_LOGGER(config) \
|
||||
gr::logger_config::load_config(config)
|
||||
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period) \
|
||||
gr::logger_config::load_config(config,period)
|
||||
|
||||
#define GR_LOG_GETLOGGER(logger, name) \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name);
|
||||
|
||||
#define GR_SET_LEVEL(name, level) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_set_level(logger,level);}
|
||||
|
||||
#define GR_LOG_SET_LEVEL(logger, level) \
|
||||
gr::logger_set_level(logger, level);
|
||||
|
||||
#define GR_GET_LEVEL(name, level) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_get_level(logger,level);}
|
||||
|
||||
#define GR_LOG_GET_LEVEL(logger, level) \
|
||||
gr::logger_get_level(logger,level);
|
||||
|
||||
#define GR_ADD_APPENDER(name, appender) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_appender(logger,appender);}
|
||||
|
||||
#define GR_LOG_ADD_APPENDER(logger, appender) { \
|
||||
gr::logger_add_appender(logger, appender);}
|
||||
|
||||
#define GR_ADD_CONSOLE_APPENDER(name, target, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_console_appender(logger,target,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger, target, pattern) { \
|
||||
gr::logger_add_console_appender(logger,target,pattern);}
|
||||
|
||||
#define GR_ADD_FILE_APPENDER(name, filename, append, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_file_appender(logger,filename,append,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger, filename, append, pattern) { \
|
||||
gr::logger_add_file_appender(logger,filename,append,pattern);}
|
||||
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name, filename, filesize, bkup_index, append, mode, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger, filename, filesize, bkup_index, append, mode, pattern) { \
|
||||
gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);}
|
||||
|
||||
#define GR_GET_LOGGER_NAMES(names) { \
|
||||
names = gr::logger_get_logger_names();}
|
||||
|
||||
#define GR_RESET_CONFIGURATION() \
|
||||
gr::logger_config::reset_config();
|
||||
|
||||
/* Logger name referenced macros */
|
||||
#define GR_DEBUG(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::DEBUG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_INFO(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::INFO << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_NOTICE(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger << log4cpp::Priority::NOTICE << msg;}
|
||||
|
||||
#define GR_WARN(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::WARN << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ERROR(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_CRIT(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::CRIT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ALERT(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ALERT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_FATAL(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::FATAL << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_EMERG(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ERRORIF(name, cond, msg) { \
|
||||
if((cond)) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \
|
||||
}
|
||||
|
||||
#define GR_ASSERT(name, cond, msg) { \
|
||||
if(!(cond)) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} \
|
||||
assert(0); \
|
||||
}
|
||||
|
||||
/* LoggerPtr Referenced Macros */
|
||||
#define GR_LOG_DEBUG(logger, msg) { \
|
||||
*logger << log4cpp::Priority::DEBUG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_INFO(logger, msg) { \
|
||||
*logger << log4cpp::Priority::INFO << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_NOTICE(logger, msg) { \
|
||||
*logger << log4cpp::Priority::NOTICE << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_WARN(logger, msg) { \
|
||||
*logger << log4cpp::Priority::WARN << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ERROR(logger, msg) { \
|
||||
*logger << log4cpp::Priority::ERROR << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_CRIT(logger, msg) { \
|
||||
*logger << log4cpp::Priority::CRIT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ALERT(logger, msg) { \
|
||||
*logger << log4cpp::Priority::ALERT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_FATAL(logger, msg) { \
|
||||
*logger << log4cpp::Priority::FATAL << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_EMERG(logger, msg) { \
|
||||
*logger << log4cpp::Priority::EMERG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ERRORIF(logger,cond, msg) { \
|
||||
if((cond)) { \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \
|
||||
}
|
||||
|
||||
#define GR_LOG_ASSERT(logger, cond, msg) { \
|
||||
if(!(cond)) { \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol; \
|
||||
assert(0);} \
|
||||
}
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Class to control configuration of logger.
|
||||
* This is a singleton that cna launch a thread to wathc a config file for changes
|
||||
* \ingroup logging
|
||||
*/
|
||||
class logger_config
|
||||
{
|
||||
private:
|
||||
/*! \brief filename of logger config file */
|
||||
std::string filename;
|
||||
/*! \brief Period (seconds) over which watcher thread checks config file for changes */
|
||||
unsigned int watch_period;
|
||||
/*! \brief Pointer to watch thread for config file changes */
|
||||
boost::thread *watch_thread;
|
||||
|
||||
/*! \brief Watcher thread method
|
||||
* /param filename Name of configuration file
|
||||
* /param watch_period Seconds between checks for changes in config file
|
||||
*/
|
||||
static void watch_file(std::string filename,unsigned int watch_period);
|
||||
|
||||
static bool logger_configured;
|
||||
|
||||
logger_config()
|
||||
{
|
||||
} //!< Constructor
|
||||
|
||||
/*
|
||||
rpcbasic_register_get<logger_config,std::string> rpc_get_filename;
|
||||
rpcbasic_register_get<logger_config,int> rpc_get_watchperiod;
|
||||
rpcbasic_register_get<logger_config,std::string> rpc_get_config;
|
||||
rpcbasic_register_set<logger_config,std::string> rpc_set_config;
|
||||
*/
|
||||
|
||||
logger_config(logger_config const&); //!<Copy constructor
|
||||
void operator=(logger_config const&); //!<Assignment Operator
|
||||
|
||||
std::string get_filename4rpc() {
|
||||
return filename;
|
||||
}
|
||||
int get_watchperiod4rpc(){return watch_period;};
|
||||
|
||||
std::string get_config4rpc() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
void set_config4rpc(std::string set) {
|
||||
printf("Set string was:%s\n", set.c_str());
|
||||
}
|
||||
|
||||
/*! \brief destrcutor stops watch thread before exits */
|
||||
~logger_config() {
|
||||
stop_watch();
|
||||
}
|
||||
|
||||
/*! \brief Instance getter for singleton. Only used by class. */
|
||||
static logger_config& get_instance(void);
|
||||
|
||||
public:
|
||||
/*! \brief Getter for config filename */
|
||||
static std::string get_filename();
|
||||
/*! \brief Getter for watch period */
|
||||
static unsigned int get_watch_period();
|
||||
/*! \brief Method to load configuration
|
||||
* /param filename Name of configuration file
|
||||
* /param watch_period Seconds between checks for changes in config file
|
||||
*/
|
||||
static void load_config(std::string filename,unsigned int watch_period=0);
|
||||
/*! \brief Method to stop watcher thread */
|
||||
static void stop_watch();
|
||||
/*! \brief method to reset logger configuration */
|
||||
static void reset_config(void);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Retrieve a pointer to a logger by name
|
||||
*
|
||||
* Retrives a logger pointer
|
||||
* \p name.
|
||||
*
|
||||
* \param name Name of the logger for which a pointer is requested
|
||||
*/
|
||||
GR_RUNTIME_API logger_ptr logger_get_logger(std::string name);
|
||||
|
||||
/*!
|
||||
* \brief Load logger's configuration file.
|
||||
*
|
||||
* Initialize the GNU Radio logger by loading the configuration file
|
||||
* \p config_filename.
|
||||
*
|
||||
* \param config_filename The configuration file. Set to "" for the
|
||||
* basic logger that outputs to the console.
|
||||
*/
|
||||
GR_RUNTIME_API bool logger_load_config(const std::string &config_filename="");
|
||||
|
||||
/*!
|
||||
* \brief Reset logger's configuration file.
|
||||
*
|
||||
* Remove all appenders from loggers
|
||||
*/
|
||||
GR_RUNTIME_API void logger_reset_config(void);
|
||||
|
||||
/*!
|
||||
* \brief Set the logger's output level.
|
||||
*
|
||||
* Sets the level of the logger. This takes a string that is
|
||||
* translated to the standard levels and can be (case insensitive):
|
||||
*
|
||||
* \li off , notset
|
||||
* \li debug
|
||||
* \li info
|
||||
* \li notice
|
||||
* \li warn
|
||||
* \li error
|
||||
* \li crit
|
||||
* \li alert
|
||||
* \li fatal
|
||||
* \li emerg
|
||||
*
|
||||
* \param logger the logger to set the level of.
|
||||
* \param level string to set the level to.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_set_level(logger_ptr logger,
|
||||
const std::string &level);
|
||||
|
||||
/*!
|
||||
* \brief Set the logger's output level.
|
||||
*
|
||||
* Sets the level of the logger. This takes the actual Log4cpp::Priority
|
||||
* data type, which can be:
|
||||
*
|
||||
* \li log4cpp::Priority::NOTSET
|
||||
* \li log4cpp::Priority::DEBUG
|
||||
* \li log4cpp::Priority::INFO
|
||||
* \li log4cpp::Priority::NOTICE
|
||||
* \li log4cpp::Priority::WARN
|
||||
* \li log4cpp::Priority::ERROR
|
||||
* \li log4cpp::Priority::CRIT
|
||||
* \li log4cpp::Priority::ALERT
|
||||
* \li log4cpp::Priority::FATAL
|
||||
* \li log4cpp::Priority::EMERG
|
||||
*
|
||||
* \param logger the logger to set the level of.
|
||||
* \param level new logger level of type Log4cpp::Priority
|
||||
*/
|
||||
GR_RUNTIME_API void logger_set_level(logger_ptr logger,
|
||||
log4cpp::Priority::Value level);
|
||||
|
||||
/*!
|
||||
* \brief Get the logger's output level.
|
||||
*
|
||||
* Gets the level of the logger. This returns a string that
|
||||
* corresponds to the standard levels and can be (case insensitive):
|
||||
*
|
||||
* \li notset
|
||||
* \li debug
|
||||
* \li info
|
||||
* \li notice
|
||||
* \li warn
|
||||
* \li error
|
||||
* \li crit
|
||||
* \li alert
|
||||
* \li fatal
|
||||
* \li emerg
|
||||
*
|
||||
* \param logger the logger to get the level of.
|
||||
* \param level string to get the level into.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_get_level(logger_ptr logger, std::string &level);
|
||||
|
||||
/*!
|
||||
* \brief Get the logger's output level.
|
||||
*
|
||||
* Gets the level of the logger. This returns the actual Log4cpp::Level
|
||||
* data type, which can be:
|
||||
*
|
||||
* \li log4cpp::Priority::NOTSET
|
||||
* \li log4cpp::Priority::DEBUG
|
||||
* \li log4cpp::Priority::INFO
|
||||
* \li log4cpp::Priority::NOTICE
|
||||
* \li log4cpp::Priority::WARN
|
||||
* \li log4cpp::Priority::ERROR
|
||||
* \li log4cpp::Priority::CRIT
|
||||
* \li log4cpp::Priority::ALERT
|
||||
* \li log4cpp::Priority::FATAL
|
||||
* \li log4cpp::Priority::EMERG
|
||||
*
|
||||
* \param logger the logger to get the level of.
|
||||
* \param level of the logger.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_get_level(logger_ptr logger,
|
||||
log4cpp::Priority::Value &level);
|
||||
|
||||
/*!
|
||||
* \brief Add console appender to a given logger
|
||||
*
|
||||
* Add console appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param appender Name of appender to add to logger
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_appender(logger_ptr logger,
|
||||
std::string appender);
|
||||
|
||||
/*!
|
||||
* \brief Add console appender to a given logger
|
||||
*
|
||||
* Add console appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param target Std target to write 'cout' or 'cerr' (default is cout)
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_console_appender(logger_ptr logger,
|
||||
std::string target,
|
||||
std::string pattern);
|
||||
|
||||
/*!
|
||||
* \brief Add file appender to a given logger
|
||||
*
|
||||
* Add file appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param filename File to which log will be written
|
||||
* \param append Overwrite or append to log file
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_file_appender(logger_ptr logger,
|
||||
std::string filename,
|
||||
bool append, std::string pattern);
|
||||
|
||||
/*!
|
||||
* \brief Add rolling file appender to a given logger
|
||||
*
|
||||
* Add rolling file appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param filename File to which log will be written
|
||||
* \param filesize Sizez of files to write
|
||||
* \param bkup_index Number of files to write
|
||||
* \param append Overwrite or append to log file
|
||||
* \param mode Permissions to set on log file
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API 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);
|
||||
|
||||
/*!
|
||||
* \brief Add rolling file appender to a given logger
|
||||
*
|
||||
* Add rolling file appender to a given logger
|
||||
*
|
||||
* \return vector of string names of loggers
|
||||
*/
|
||||
GR_RUNTIME_API std::vector<std::string> logger_get_logger_names(void);
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* HAVE_LOG4CPP */
|
||||
|
||||
// If Logger disable do nothing
|
||||
#else /* ENABLE_GR_LOG */
|
||||
|
||||
namespace gr {
|
||||
typedef void* logger_ptr;
|
||||
} /* namespace gr */
|
||||
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger)
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name)
|
||||
#define GR_CONFIG_LOGGER(config)
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period)
|
||||
#define GR_LOG_GETLOGGER(logger, name)
|
||||
#define GR_SET_LEVEL(name, level)
|
||||
#define GR_LOG_SET_LEVEL(logger, level)
|
||||
#define GR_GET_LEVEL(name, level)
|
||||
#define GR_LOG_GET_LEVEL(logger, level)
|
||||
#define GR_ADD_APPENDER(name,appender)
|
||||
#define GR_LOG_ADD_APPENDER(logger,appender)
|
||||
#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_ADD_FILE_APPENDER(name,filename,append,pattern)
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern)
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_GET_LOGGER_NAMES(names)
|
||||
#define GR_RESET_CONFIGURATION()
|
||||
#define GR_DEBUG(name, msg)
|
||||
#define GR_INFO(name, msg)
|
||||
#define GR_NOTICE(name, msg)
|
||||
#define GR_WARN(name, msg)
|
||||
#define GR_ERROR(name, msg)
|
||||
#define GR_ALERT(name, msg)
|
||||
#define GR_CRIT(name, msg)
|
||||
#define GR_FATAL(name, msg)
|
||||
#define GR_EMERG(name, msg)
|
||||
#define GR_ERRORIF(name, cond, msg)
|
||||
#define GR_ASSERT(name, cond, msg)
|
||||
#define GR_LOG_DEBUG(logger, msg)
|
||||
#define GR_LOG_INFO(logger, msg)
|
||||
#define GR_LOG_NOTICE(logger, msg)
|
||||
#define GR_LOG_WARN(logger, msg)
|
||||
#define GR_LOG_ERROR(logger, msg)
|
||||
#define GR_LOG_ALERT(logger, msg)
|
||||
#define GR_LOG_CRIT(logger, msg)
|
||||
#define GR_LOG_FATAL(logger, msg)
|
||||
#define GR_LOG_EMERG(logger, msg)
|
||||
#define GR_LOG_ERRORIF(logger, cond, msg)
|
||||
#define GR_LOG_ASSERT(logger, cond, msg)
|
||||
|
||||
#endif /* ENABLE_GR_LOG */
|
||||
|
||||
namespace gr {
|
||||
|
||||
// Even if logger is disabled we'll need for methods below to exist in python.
|
||||
// The macros these call will be disabled if ENABLE_GR_LOG is undefined
|
||||
|
||||
/********************* Start Classes and Methods for Python ******************/
|
||||
/*!
|
||||
* \brief Logger class for referencing loggers in python. Not
|
||||
* needed in C++ (use macros) Wraps and manipulates loggers for
|
||||
* python as python has no macros
|
||||
* \ingroup logging
|
||||
*
|
||||
*/
|
||||
class logger
|
||||
{
|
||||
private:
|
||||
/*! \brief logger pointer to logger associated wiith this wrapper class */
|
||||
logger_ptr d_logger;
|
||||
public:
|
||||
/*!
|
||||
* \brief contructor Provide name of logger to associate with this class
|
||||
* \param logger_name Name of logger associated with class
|
||||
*/
|
||||
logger(std::string logger_name) {
|
||||
GR_LOG_ASSIGN_LOGPTR(d_logger,logger_name);
|
||||
};
|
||||
|
||||
/*! \brief Destructor */
|
||||
~logger(){;}
|
||||
|
||||
// Wrappers for logging macros
|
||||
/*! \brief inline function, wrapper to set the logger level */
|
||||
void set_level(std::string level){GR_LOG_SET_LEVEL(d_logger,level);}
|
||||
|
||||
/*! \brief inline function, wrapper to get the logger level */
|
||||
void get_level(std::string &level){GR_LOG_GET_LEVEL(d_logger,level);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_DEBUG for DEBUG message */
|
||||
void debug(std::string msg){GR_LOG_DEBUG(d_logger,msg);};
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_INFO for INFO message */
|
||||
void info(std::string msg){GR_LOG_INFO(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for NOTICE message */
|
||||
void notice(std::string msg){GR_LOG_NOTICE(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_WARN for WARN message */
|
||||
void warn(std::string msg){GR_LOG_WARN(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ERROR for ERROR message */
|
||||
void error(std::string msg){GR_LOG_ERROR(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for NOTICE message */
|
||||
void crit(std::string msg){GR_LOG_CRIT(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for ALERT message */
|
||||
void alert(std::string msg){GR_LOG_ALERT(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for FATAL message */
|
||||
void fatal(std::string msg){GR_LOG_FATAL(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for EMERG message */
|
||||
void emerg(std::string msg){GR_LOG_EMERG(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */
|
||||
void errorIF(bool cond,std::string msg){GR_LOG_ERRORIF(d_logger,cond,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */
|
||||
void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);}
|
||||
|
||||
/*! \brief inline function, Method to add appender to logger by
|
||||
name (define appender in conf file) */
|
||||
void add_appender(std::string appender) {
|
||||
GR_LOG_ADD_APPENDER(d_logger, appender);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add console appender to logger */
|
||||
void add_console_appender(std::string target,std::string pattern) {
|
||||
GR_LOG_ADD_CONSOLE_APPENDER(d_logger, target, pattern);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add file appender to logger */
|
||||
void add_file_appender(std::string filename, bool append, std::string pattern) {
|
||||
GR_LOG_ADD_FILE_APPENDER(d_logger, filename, append, pattern);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add rolling file appender to logger */
|
||||
void add_rollingfile_appender(std::string filename, size_t filesize,
|
||||
int bkup_index, bool append, mode_t mode,
|
||||
std::string pattern) {
|
||||
GR_LOG_ADD_ROLLINGFILE_APPENDER(d_logger,filename,filesize,
|
||||
bkup_index,append,mode,pattern);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
/**************** Start Configuration Class and Methods for Python ************/
|
||||
/*!
|
||||
* \brief Function to call configuration macro from python.
|
||||
* Note: Configuration is only updated if filename or watch_period has changed.
|
||||
* \param config_filename Name of configuration file
|
||||
* \param watch_period Seconds to wait between checking for changes in conf file.
|
||||
* Watch_period defaults to 0 in which case the file is not watched for changes
|
||||
*/
|
||||
GR_RUNTIME_API void gr_logger_config(const std::string config_filename,
|
||||
unsigned int watch_period = 0);
|
||||
|
||||
/*!
|
||||
* \brief Function to return logger names to python
|
||||
* \return Vector of name strings
|
||||
*
|
||||
*/
|
||||
GR_RUNTIME_API std::vector<std::string> gr_logger_get_logger_names(void);
|
||||
|
||||
/*!
|
||||
* \brief Function to reset logger configuration from python
|
||||
*
|
||||
*/
|
||||
GR_RUNTIME_API void gr_logger_reset_config(void);
|
||||
|
||||
#endif /* INCLUDED_GR_LOGGER_H */
|
|
@ -0,0 +1,733 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Author: Mark Plett
|
||||
* Description:
|
||||
* The gr::logger module wraps the log4cpp library for logging in gnuradio
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef INCLUDED_GR_LOGGER_H
|
||||
#define INCLUDED_GR_LOGGER_H
|
||||
|
||||
/*!
|
||||
* \ingroup logging
|
||||
* \brief GNU Radio logging wrapper for log4cpp library (C++ port of log4j)
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ENABLE_GR_LOG
|
||||
#cmakedefine ENABLE_GR_LOG
|
||||
#endif
|
||||
#ifndef HAVE_LOG4CPP
|
||||
#cmakedefine HAVE_LOG4CPP
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef unsigned short mode_t;
|
||||
#endif
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <time.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#ifdef ENABLE_GR_LOG
|
||||
|
||||
// We have three configurations... first logging to stdout/stderr
|
||||
#ifndef HAVE_LOG4CPP
|
||||
|
||||
namespace gr {
|
||||
//#warning GR logging Enabled and using std::cout
|
||||
typedef std::string logger_ptr;
|
||||
} /* namespace gr */
|
||||
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger)
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name)
|
||||
#define GR_CONFIG_LOGGER(config)
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period)
|
||||
#define GR_LOG_GETLOGGER(logger, name)
|
||||
#define GR_SET_LEVEL(name, level)
|
||||
#define GR_LOG_SET_LEVEL(logger, level)
|
||||
#define GR_GET_LEVEL(name, level)
|
||||
#define GR_LOG_GET_LEVEL(logger, level)
|
||||
#define GR_ADD_APPENDER(name,appender)
|
||||
#define GR_LOG_ADD_APPENDER(logger,appender)
|
||||
#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_ADD_FILE_APPENDER(name,filename,append,pattern)
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern)
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_GET_LOGGER_NAMES(names)
|
||||
#define GR_RESET_CONFIGURATION()
|
||||
#define GR_DEBUG(name, msg) std::cout<<"DEBUG: "<<msg<<std::endl
|
||||
#define GR_INFO(name, msg) std::cout<<"INFO: "<<msg<<std::endl
|
||||
#define GR_NOTICE(name, msg) std::cout<<"NOTICE: "<<msg<<std::endl
|
||||
#define GR_WARN(name, msg) std::cerr<<"WARN: "<<msg<<std::endl
|
||||
#define GR_ERROR(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_ALERT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_CRIT(name, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_FATAL(name, msg) std::cerr<<"FATAL: "<<msg<<std::endl
|
||||
#define GR_EMERG(name, msg) std::cerr<<"EMERG: "<<msg<<std::endl
|
||||
#define GR_ERRORIF(name, cond, msg) {if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;}
|
||||
#define GR_ASSERT(name, cond, msg) {if(!(cond)) std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);}
|
||||
#define GR_LOG_DEBUG(logger, msg) std::cout<<"DEBUG: "<<msg<<std::endl
|
||||
#define GR_LOG_INFO(logger, msg) std::cout<<"INFO: "<<msg<<std::endl
|
||||
#define GR_LOG_NOTICE(logger, msg) std::cout<<"NOTICE: "<<msg<<std::endl
|
||||
#define GR_LOG_WARN(logger, msg) std::cerr<<"WARN: "<<msg<<std::endl
|
||||
#define GR_LOG_ERROR(logger, msg) std::cerr<<"ERROR: "<<msg<<std::endl
|
||||
#define GR_LOG_ALERT(logger, msg) std::cerr<<"ALERT: "<<msg<<std::endl
|
||||
#define GR_LOG_CRIT(logger, msg) std::cerr<<"CRIT: "<<msg<<std::endl
|
||||
#define GR_LOG_FATAL(logger, msg) std::cerr<<"FATAL: "<<msg<<std::endl
|
||||
#define GR_LOG_EMERG(logger, msg) std::cerr<<"EMERG: "<<msg<<std::endl
|
||||
#define GR_LOG_ERRORIF(logger, cond, msg) { \
|
||||
if((cond)) std::cerr<<"ERROR: "<<msg<<std::endl;}
|
||||
#define GR_LOG_ASSERT(logger, cond, msg) { \
|
||||
if(!(cond)) {std::cerr<<"FATAL: "<<msg<<std::endl; assert(cond);};}
|
||||
|
||||
|
||||
#else /* HAVE_LOG4CPP */
|
||||
|
||||
// Second configuration...logging to log4cpp
|
||||
#include <log4cpp/Category.hh>
|
||||
#include <log4cpp/PropertyConfigurator.hh>
|
||||
#include <log4cpp/FileAppender.hh>
|
||||
#include <log4cpp/RollingFileAppender.hh>
|
||||
#include <log4cpp/OstreamAppender.hh>
|
||||
#include <log4cpp/PatternLayout.hh>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief GR_LOG macros
|
||||
* \ingroup logging
|
||||
*
|
||||
* These macros wrap the standard LOG4CPP_LEVEL macros. The availablie macros
|
||||
* are:
|
||||
* LOG_DEBUG
|
||||
* LOG_INFO
|
||||
* LOG_WARN
|
||||
* LOG_TRACE
|
||||
* LOG_ERROR
|
||||
* LOG_ALERT
|
||||
* LOG_CRIT
|
||||
* LOG_FATAL
|
||||
* LOG_EMERG
|
||||
*/
|
||||
typedef log4cpp::Category* logger_ptr;
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
|
||||
/* Macros for Programmatic Configuration */
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger) \
|
||||
gr::logger_ptr logger;
|
||||
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name) \
|
||||
logger = gr::logger_get_logger(name);
|
||||
|
||||
#define GR_CONFIG_LOGGER(config) \
|
||||
gr::logger_config::load_config(config)
|
||||
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period) \
|
||||
gr::logger_config::load_config(config,period)
|
||||
|
||||
#define GR_LOG_GETLOGGER(logger, name) \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name);
|
||||
|
||||
#define GR_SET_LEVEL(name, level) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_set_level(logger,level);}
|
||||
|
||||
#define GR_LOG_SET_LEVEL(logger, level) \
|
||||
gr::logger_set_level(logger, level);
|
||||
|
||||
#define GR_GET_LEVEL(name, level) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_get_level(logger,level);}
|
||||
|
||||
#define GR_LOG_GET_LEVEL(logger, level) \
|
||||
gr::logger_get_level(logger,level);
|
||||
|
||||
#define GR_ADD_APPENDER(name, appender) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_appender(logger,appender);}
|
||||
|
||||
#define GR_LOG_ADD_APPENDER(logger, appender) { \
|
||||
gr::logger_add_appender(logger, appender);}
|
||||
|
||||
#define GR_ADD_CONSOLE_APPENDER(name, target, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_console_appender(logger,target,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger, target, pattern) { \
|
||||
gr::logger_add_console_appender(logger,target,pattern);}
|
||||
|
||||
#define GR_ADD_FILE_APPENDER(name, filename, append, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_file_appender(logger,filename,append,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger, filename, append, pattern) { \
|
||||
gr::logger_add_file_appender(logger,filename,append,pattern);}
|
||||
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name, filename, filesize, bkup_index, append, mode, pattern) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);}
|
||||
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger, filename, filesize, bkup_index, append, mode, pattern) { \
|
||||
gr::logger_add_rollingfile_appender(logger,filename,filesize,bkup_index,append,mode,pattern);}
|
||||
|
||||
#define GR_GET_LOGGER_NAMES(names) { \
|
||||
names = gr::logger_get_logger_names();}
|
||||
|
||||
#define GR_RESET_CONFIGURATION() \
|
||||
gr::logger_config::reset_config();
|
||||
|
||||
/* Logger name referenced macros */
|
||||
#define GR_DEBUG(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::DEBUG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_INFO(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::INFO << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_NOTICE(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger << log4cpp::Priority::NOTICE << msg;}
|
||||
|
||||
#define GR_WARN(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::WARN << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ERROR(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_CRIT(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::CRIT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ALERT(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ALERT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_FATAL(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::FATAL << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_EMERG(name, msg) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_ERRORIF(name, cond, msg) { \
|
||||
if((cond)) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \
|
||||
}
|
||||
|
||||
#define GR_ASSERT(name, cond, msg) { \
|
||||
if(!(cond)) { \
|
||||
gr::logger_ptr logger = gr::logger_get_logger(name); \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol;} \
|
||||
assert(0); \
|
||||
}
|
||||
|
||||
/* LoggerPtr Referenced Macros */
|
||||
#define GR_LOG_DEBUG(logger, msg) { \
|
||||
*logger << log4cpp::Priority::DEBUG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_INFO(logger, msg) { \
|
||||
*logger << log4cpp::Priority::INFO << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_NOTICE(logger, msg) { \
|
||||
*logger << log4cpp::Priority::NOTICE << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_WARN(logger, msg) { \
|
||||
*logger << log4cpp::Priority::WARN << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ERROR(logger, msg) { \
|
||||
*logger << log4cpp::Priority::ERROR << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_CRIT(logger, msg) { \
|
||||
*logger << log4cpp::Priority::CRIT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ALERT(logger, msg) { \
|
||||
*logger << log4cpp::Priority::ALERT << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_FATAL(logger, msg) { \
|
||||
*logger << log4cpp::Priority::FATAL << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_EMERG(logger, msg) { \
|
||||
*logger << log4cpp::Priority::EMERG << msg << log4cpp::eol;}
|
||||
|
||||
#define GR_LOG_ERRORIF(logger,cond, msg) { \
|
||||
if((cond)) { \
|
||||
*logger<< log4cpp::Priority::ERROR << msg << log4cpp::eol;} \
|
||||
}
|
||||
|
||||
#define GR_LOG_ASSERT(logger, cond, msg) { \
|
||||
if(!(cond)) { \
|
||||
*logger<< log4cpp::Priority::EMERG << msg << log4cpp::eol; \
|
||||
assert(0);} \
|
||||
}
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief Class to control configuration of logger.
|
||||
* This is a singleton that cna launch a thread to wathc a config file for changes
|
||||
* \ingroup logging
|
||||
*/
|
||||
class logger_config
|
||||
{
|
||||
private:
|
||||
/*! \brief filename of logger config file */
|
||||
std::string filename;
|
||||
/*! \brief Period (seconds) over which watcher thread checks config file for changes */
|
||||
unsigned int watch_period;
|
||||
/*! \brief Pointer to watch thread for config file changes */
|
||||
boost::thread *watch_thread;
|
||||
|
||||
/*! \brief Watcher thread method
|
||||
* /param filename Name of configuration file
|
||||
* /param watch_period Seconds between checks for changes in config file
|
||||
*/
|
||||
static void watch_file(std::string filename,unsigned int watch_period);
|
||||
|
||||
static bool logger_configured;
|
||||
|
||||
logger_config()
|
||||
{
|
||||
} //!< Constructor
|
||||
|
||||
/*
|
||||
rpcbasic_register_get<logger_config,std::string> rpc_get_filename;
|
||||
rpcbasic_register_get<logger_config,int> rpc_get_watchperiod;
|
||||
rpcbasic_register_get<logger_config,std::string> rpc_get_config;
|
||||
rpcbasic_register_set<logger_config,std::string> rpc_set_config;
|
||||
*/
|
||||
|
||||
logger_config(logger_config const&); //!<Copy constructor
|
||||
void operator=(logger_config const&); //!<Assignment Operator
|
||||
|
||||
std::string get_filename4rpc() {
|
||||
return filename;
|
||||
}
|
||||
int get_watchperiod4rpc(){return watch_period;};
|
||||
|
||||
std::string get_config4rpc() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
void set_config4rpc(std::string set) {
|
||||
printf("Set string was:%s\n", set.c_str());
|
||||
}
|
||||
|
||||
/*! \brief destrcutor stops watch thread before exits */
|
||||
~logger_config() {
|
||||
stop_watch();
|
||||
}
|
||||
|
||||
/*! \brief Instance getter for singleton. Only used by class. */
|
||||
static logger_config& get_instance(void);
|
||||
|
||||
public:
|
||||
/*! \brief Getter for config filename */
|
||||
static std::string get_filename();
|
||||
/*! \brief Getter for watch period */
|
||||
static unsigned int get_watch_period();
|
||||
/*! \brief Method to load configuration
|
||||
* /param filename Name of configuration file
|
||||
* /param watch_period Seconds between checks for changes in config file
|
||||
*/
|
||||
static void load_config(std::string filename,unsigned int watch_period=0);
|
||||
/*! \brief Method to stop watcher thread */
|
||||
static void stop_watch();
|
||||
/*! \brief method to reset logger configuration */
|
||||
static void reset_config(void);
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Retrieve a pointer to a logger by name
|
||||
*
|
||||
* Retrives a logger pointer
|
||||
* \p name.
|
||||
*
|
||||
* \param name Name of the logger for which a pointer is requested
|
||||
*/
|
||||
GR_RUNTIME_API logger_ptr logger_get_logger(std::string name);
|
||||
|
||||
/*!
|
||||
* \brief Load logger's configuration file.
|
||||
*
|
||||
* Initialize the GNU Radio logger by loading the configuration file
|
||||
* \p config_filename.
|
||||
*
|
||||
* \param config_filename The configuration file. Set to "" for the
|
||||
* basic logger that outputs to the console.
|
||||
*/
|
||||
GR_RUNTIME_API bool logger_load_config(const std::string &config_filename="");
|
||||
|
||||
/*!
|
||||
* \brief Reset logger's configuration file.
|
||||
*
|
||||
* Remove all appenders from loggers
|
||||
*/
|
||||
GR_RUNTIME_API void logger_reset_config(void);
|
||||
|
||||
/*!
|
||||
* \brief Set the logger's output level.
|
||||
*
|
||||
* Sets the level of the logger. This takes a string that is
|
||||
* translated to the standard levels and can be (case insensitive):
|
||||
*
|
||||
* \li off , notset
|
||||
* \li debug
|
||||
* \li info
|
||||
* \li notice
|
||||
* \li warn
|
||||
* \li error
|
||||
* \li crit
|
||||
* \li alert
|
||||
* \li fatal
|
||||
* \li emerg
|
||||
*
|
||||
* \param logger the logger to set the level of.
|
||||
* \param level string to set the level to.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_set_level(logger_ptr logger,
|
||||
const std::string &level);
|
||||
|
||||
/*!
|
||||
* \brief Set the logger's output level.
|
||||
*
|
||||
* Sets the level of the logger. This takes the actual Log4cpp::Priority
|
||||
* data type, which can be:
|
||||
*
|
||||
* \li log4cpp::Priority::NOTSET
|
||||
* \li log4cpp::Priority::DEBUG
|
||||
* \li log4cpp::Priority::INFO
|
||||
* \li log4cpp::Priority::NOTICE
|
||||
* \li log4cpp::Priority::WARN
|
||||
* \li log4cpp::Priority::ERROR
|
||||
* \li log4cpp::Priority::CRIT
|
||||
* \li log4cpp::Priority::ALERT
|
||||
* \li log4cpp::Priority::FATAL
|
||||
* \li log4cpp::Priority::EMERG
|
||||
*
|
||||
* \param logger the logger to set the level of.
|
||||
* \param level new logger level of type Log4cpp::Priority
|
||||
*/
|
||||
GR_RUNTIME_API void logger_set_level(logger_ptr logger,
|
||||
log4cpp::Priority::Value level);
|
||||
|
||||
/*!
|
||||
* \brief Get the logger's output level.
|
||||
*
|
||||
* Gets the level of the logger. This returns a string that
|
||||
* corresponds to the standard levels and can be (case insensitive):
|
||||
*
|
||||
* \li notset
|
||||
* \li debug
|
||||
* \li info
|
||||
* \li notice
|
||||
* \li warn
|
||||
* \li error
|
||||
* \li crit
|
||||
* \li alert
|
||||
* \li fatal
|
||||
* \li emerg
|
||||
*
|
||||
* \param logger the logger to get the level of.
|
||||
* \param level string to get the level into.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_get_level(logger_ptr logger, std::string &level);
|
||||
|
||||
/*!
|
||||
* \brief Get the logger's output level.
|
||||
*
|
||||
* Gets the level of the logger. This returns the actual Log4cpp::Level
|
||||
* data type, which can be:
|
||||
*
|
||||
* \li log4cpp::Priority::NOTSET
|
||||
* \li log4cpp::Priority::DEBUG
|
||||
* \li log4cpp::Priority::INFO
|
||||
* \li log4cpp::Priority::NOTICE
|
||||
* \li log4cpp::Priority::WARN
|
||||
* \li log4cpp::Priority::ERROR
|
||||
* \li log4cpp::Priority::CRIT
|
||||
* \li log4cpp::Priority::ALERT
|
||||
* \li log4cpp::Priority::FATAL
|
||||
* \li log4cpp::Priority::EMERG
|
||||
*
|
||||
* \param logger the logger to get the level of.
|
||||
* \param level of the logger.
|
||||
*/
|
||||
GR_RUNTIME_API void logger_get_level(logger_ptr logger,
|
||||
log4cpp::Priority::Value &level);
|
||||
|
||||
/*!
|
||||
* \brief Add console appender to a given logger
|
||||
*
|
||||
* Add console appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param appender Name of appender to add to logger
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_appender(logger_ptr logger,
|
||||
std::string appender);
|
||||
|
||||
/*!
|
||||
* \brief Add console appender to a given logger
|
||||
*
|
||||
* Add console appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param target Std target to write 'cout' or 'cerr' (default is cout)
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_console_appender(logger_ptr logger,
|
||||
std::string target,
|
||||
std::string pattern);
|
||||
|
||||
/*!
|
||||
* \brief Add file appender to a given logger
|
||||
*
|
||||
* Add file appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param filename File to which log will be written
|
||||
* \param append Overwrite or append to log file
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API void logger_add_file_appender(logger_ptr logger,
|
||||
std::string filename,
|
||||
bool append, std::string pattern);
|
||||
|
||||
/*!
|
||||
* \brief Add rolling file appender to a given logger
|
||||
*
|
||||
* Add rolling file appender to a given logger
|
||||
*
|
||||
* \param logger Logger to which appender will be added
|
||||
* \param filename File to which log will be written
|
||||
* \param filesize Sizez of files to write
|
||||
* \param bkup_index Number of files to write
|
||||
* \param append Overwrite or append to log file
|
||||
* \param mode Permissions to set on log file
|
||||
* \param pattern Formating pattern for log messages
|
||||
*/
|
||||
GR_RUNTIME_API 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);
|
||||
|
||||
/*!
|
||||
* \brief Add rolling file appender to a given logger
|
||||
*
|
||||
* Add rolling file appender to a given logger
|
||||
*
|
||||
* \return vector of string names of loggers
|
||||
*/
|
||||
GR_RUNTIME_API std::vector<std::string> logger_get_logger_names(void);
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* HAVE_LOG4CPP */
|
||||
|
||||
// If Logger disable do nothing
|
||||
#else /* ENABLE_GR_LOG */
|
||||
|
||||
namespace gr {
|
||||
typedef void* logger_ptr;
|
||||
} /* namespace gr */
|
||||
|
||||
#define GR_LOG_DECLARE_LOGPTR(logger)
|
||||
#define GR_LOG_ASSIGN_LOGPTR(logger,name)
|
||||
#define GR_CONFIG_LOGGER(config)
|
||||
#define GR_CONFIG_AND_WATCH_LOGGER(config,period)
|
||||
#define GR_LOG_GETLOGGER(logger, name)
|
||||
#define GR_SET_LEVEL(name, level)
|
||||
#define GR_LOG_SET_LEVEL(logger, level)
|
||||
#define GR_GET_LEVEL(name, level)
|
||||
#define GR_LOG_GET_LEVEL(logger, level)
|
||||
#define GR_ADD_APPENDER(name,appender)
|
||||
#define GR_LOG_ADD_APPENDER(logger,appender)
|
||||
#define GR_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_LOG_ADD_CONSOLE_APPENDER(logger,target,pattern)
|
||||
#define GR_ADD_FILE_APPENDER(name,filename,append,pattern)
|
||||
#define GR_LOG_ADD_FILE_APPENDER(logger,filename,append,pattern)
|
||||
#define GR_ADD_ROLLINGFILE_APPENDER(name,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_LOG_ADD_ROLLINGFILE_APPENDER(logger,filename,filesize,bkup_index,append,mode,pattern)
|
||||
#define GR_GET_LOGGER_NAMES(names)
|
||||
#define GR_RESET_CONFIGURATION()
|
||||
#define GR_DEBUG(name, msg)
|
||||
#define GR_INFO(name, msg)
|
||||
#define GR_NOTICE(name, msg)
|
||||
#define GR_WARN(name, msg)
|
||||
#define GR_ERROR(name, msg)
|
||||
#define GR_ALERT(name, msg)
|
||||
#define GR_CRIT(name, msg)
|
||||
#define GR_FATAL(name, msg)
|
||||
#define GR_EMERG(name, msg)
|
||||
#define GR_ERRORIF(name, cond, msg)
|
||||
#define GR_ASSERT(name, cond, msg)
|
||||
#define GR_LOG_DEBUG(logger, msg)
|
||||
#define GR_LOG_INFO(logger, msg)
|
||||
#define GR_LOG_NOTICE(logger, msg)
|
||||
#define GR_LOG_WARN(logger, msg)
|
||||
#define GR_LOG_ERROR(logger, msg)
|
||||
#define GR_LOG_ALERT(logger, msg)
|
||||
#define GR_LOG_CRIT(logger, msg)
|
||||
#define GR_LOG_FATAL(logger, msg)
|
||||
#define GR_LOG_EMERG(logger, msg)
|
||||
#define GR_LOG_ERRORIF(logger, cond, msg)
|
||||
#define GR_LOG_ASSERT(logger, cond, msg)
|
||||
|
||||
#endif /* ENABLE_GR_LOG */
|
||||
|
||||
namespace gr {
|
||||
|
||||
// Even if logger is disabled we'll need for methods below to exist in python.
|
||||
// The macros these call will be disabled if ENABLE_GR_LOG is undefined
|
||||
|
||||
/********************* Start Classes and Methods for Python ******************/
|
||||
/*!
|
||||
* \brief Logger class for referencing loggers in python. Not
|
||||
* needed in C++ (use macros) Wraps and manipulates loggers for
|
||||
* python as python has no macros
|
||||
* \ingroup logging
|
||||
*
|
||||
*/
|
||||
class logger
|
||||
{
|
||||
private:
|
||||
/*! \brief logger pointer to logger associated wiith this wrapper class */
|
||||
logger_ptr d_logger;
|
||||
public:
|
||||
/*!
|
||||
* \brief contructor Provide name of logger to associate with this class
|
||||
* \param logger_name Name of logger associated with class
|
||||
*/
|
||||
logger(std::string logger_name) {
|
||||
GR_LOG_ASSIGN_LOGPTR(d_logger,logger_name);
|
||||
};
|
||||
|
||||
/*! \brief Destructor */
|
||||
~logger(){;}
|
||||
|
||||
// Wrappers for logging macros
|
||||
/*! \brief inline function, wrapper to set the logger level */
|
||||
void set_level(std::string level){GR_LOG_SET_LEVEL(d_logger,level);}
|
||||
|
||||
/*! \brief inline function, wrapper to get the logger level */
|
||||
void get_level(std::string &level){GR_LOG_GET_LEVEL(d_logger,level);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_DEBUG for DEBUG message */
|
||||
void debug(std::string msg){GR_LOG_DEBUG(d_logger,msg);};
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_INFO for INFO message */
|
||||
void info(std::string msg){GR_LOG_INFO(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for NOTICE message */
|
||||
void notice(std::string msg){GR_LOG_NOTICE(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_WARN for WARN message */
|
||||
void warn(std::string msg){GR_LOG_WARN(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ERROR for ERROR message */
|
||||
void error(std::string msg){GR_LOG_ERROR(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for NOTICE message */
|
||||
void crit(std::string msg){GR_LOG_CRIT(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for ALERT message */
|
||||
void alert(std::string msg){GR_LOG_ALERT(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for FATAL message */
|
||||
void fatal(std::string msg){GR_LOG_FATAL(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for EMERG message */
|
||||
void emerg(std::string msg){GR_LOG_EMERG(d_logger,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */
|
||||
void errorIF(bool cond,std::string msg){GR_LOG_ERRORIF(d_logger,cond,msg);}
|
||||
|
||||
/*! \brief inline function, wrapper for LOG4CPP_ASSERT for conditional ERROR message */
|
||||
void log_assert(bool cond,std::string msg){GR_LOG_ASSERT(d_logger,cond,msg);}
|
||||
|
||||
/*! \brief inline function, Method to add appender to logger by
|
||||
name (define appender in conf file) */
|
||||
void add_appender(std::string appender) {
|
||||
GR_LOG_ADD_APPENDER(d_logger, appender);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add console appender to logger */
|
||||
void add_console_appender(std::string target,std::string pattern) {
|
||||
GR_LOG_ADD_CONSOLE_APPENDER(d_logger, target, pattern);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add file appender to logger */
|
||||
void add_file_appender(std::string filename, bool append, std::string pattern) {
|
||||
GR_LOG_ADD_FILE_APPENDER(d_logger, filename, append, pattern);
|
||||
}
|
||||
|
||||
/*! \brief inline function, Method to add rolling file appender to logger */
|
||||
void add_rollingfile_appender(std::string filename, size_t filesize,
|
||||
int bkup_index, bool append, mode_t mode,
|
||||
std::string pattern) {
|
||||
GR_LOG_ADD_ROLLINGFILE_APPENDER(d_logger,filename,filesize,
|
||||
bkup_index,append,mode,pattern);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
/**************** Start Configuration Class and Methods for Python ************/
|
||||
/*!
|
||||
* \brief Function to call configuration macro from python.
|
||||
* Note: Configuration is only updated if filename or watch_period has changed.
|
||||
* \param config_filename Name of configuration file
|
||||
* \param watch_period Seconds to wait between checking for changes in conf file.
|
||||
* Watch_period defaults to 0 in which case the file is not watched for changes
|
||||
*/
|
||||
GR_RUNTIME_API void gr_logger_config(const std::string config_filename,
|
||||
unsigned int watch_period = 0);
|
||||
|
||||
/*!
|
||||
* \brief Function to return logger names to python
|
||||
* \return Vector of name strings
|
||||
*
|
||||
*/
|
||||
GR_RUNTIME_API std::vector<std::string> gr_logger_get_logger_names(void);
|
||||
|
||||
/*!
|
||||
* \brief Function to reset logger configuration from python
|
||||
*
|
||||
*/
|
||||
GR_RUNTIME_API void gr_logger_reset_config(void);
|
||||
|
||||
#endif /* INCLUDED_GR_LOGGER_H */
|
|
@ -0,0 +1,227 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2003,2005,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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* mathematical odds and ends.
|
||||
*/
|
||||
|
||||
#ifndef _GR_MATH_H_
|
||||
#define _GR_MATH_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/gr_complex.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
static inline bool
|
||||
is_power_of_2(long x)
|
||||
{
|
||||
return x != 0 && (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Fast arc tangent using table lookup and linear interpolation
|
||||
* \ingroup misc
|
||||
*
|
||||
* \param y component of input vector
|
||||
* \param x component of input vector
|
||||
* \returns float angle angle of vector (x, y) in radians
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
GR_RUNTIME_API float fast_atan2f(float y, float x);
|
||||
|
||||
static inline float
|
||||
fast_atan2f(gr_complex z)
|
||||
{
|
||||
return fast_atan2f(z.imag(), z.real());
|
||||
}
|
||||
|
||||
/* This bounds x by +/- clip without a branch */
|
||||
static inline float
|
||||
branchless_clip(float x, float clip)
|
||||
{
|
||||
float x1 = fabsf(x+clip);
|
||||
float x2 = fabsf(x-clip);
|
||||
x1 -= x2;
|
||||
return 0.5*x1;
|
||||
}
|
||||
|
||||
static inline float
|
||||
clip(float x, float clip)
|
||||
{
|
||||
float y = x;
|
||||
if(x > clip)
|
||||
y = clip;
|
||||
else if(x < -clip)
|
||||
y = -clip;
|
||||
return y;
|
||||
}
|
||||
|
||||
// Slicer Functions
|
||||
static inline unsigned int
|
||||
binary_slicer(float x)
|
||||
{
|
||||
if(x >= 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
quad_45deg_slicer(float r, float i)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
if((r >= 0) && (i >= 0))
|
||||
ret = 0;
|
||||
else if((r < 0) && (i >= 0))
|
||||
ret = 1;
|
||||
else if((r < 0) && (i < 0))
|
||||
ret = 2;
|
||||
else
|
||||
ret = 3;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
quad_0deg_slicer(float r, float i)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
if(fabsf(r) > fabsf(i)) {
|
||||
if(r > 0)
|
||||
ret = 0;
|
||||
else
|
||||
ret = 2;
|
||||
}
|
||||
else {
|
||||
if(i > 0)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 3;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
quad_45deg_slicer(gr_complex x)
|
||||
{
|
||||
return quad_45deg_slicer(x.real(), x.imag());
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
quad_0deg_slicer(gr_complex x)
|
||||
{
|
||||
return quad_0deg_slicer(x.real(), x.imag());
|
||||
}
|
||||
|
||||
// Branchless Slicer Functions
|
||||
static inline unsigned int
|
||||
branchless_binary_slicer(float x)
|
||||
{
|
||||
return (x >= 0);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
branchless_quad_0deg_slicer(float r, float i)
|
||||
{
|
||||
unsigned int ret = 0;
|
||||
ret = (fabsf(r) > fabsf(i)) * (((r < 0) << 0x1)); // either 0 (00) or 2 (10)
|
||||
ret |= (fabsf(i) > fabsf(r)) * (((i < 0) << 0x1) | 0x1); // either 1 (01) or 3 (11)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
branchless_quad_0deg_slicer(gr_complex x)
|
||||
{
|
||||
return branchless_quad_0deg_slicer(x.real(), x.imag());
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
branchless_quad_45deg_slicer(float r, float i)
|
||||
{
|
||||
char ret = (r <= 0);
|
||||
ret |= ((i <= 0) << 1);
|
||||
return (ret ^ ((ret & 0x2) >> 0x1));
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
branchless_quad_45deg_slicer(gr_complex x)
|
||||
{
|
||||
return branchless_quad_45deg_slicer(x.real(), x.imag());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \param x any value
|
||||
* \param pow2 must be a power of 2
|
||||
* \returns \p x rounded down to a multiple of \p pow2.
|
||||
*/
|
||||
static inline size_t
|
||||
p2_round_down(size_t x, size_t pow2)
|
||||
{
|
||||
return x & -pow2;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \param x any value
|
||||
* \param pow2 must be a power of 2
|
||||
* \returns \p x rounded up to a multiple of \p pow2.
|
||||
*/
|
||||
static inline size_t
|
||||
p2_round_up(size_t x, size_t pow2)
|
||||
{
|
||||
return p2_round_down(x + pow2 - 1, pow2);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \param x any value
|
||||
* \param pow2 must be a power of 2
|
||||
* \returns \p x modulo \p pow2.
|
||||
*/
|
||||
static inline size_t
|
||||
p2_modulo(size_t x, size_t pow2)
|
||||
{
|
||||
return x & (pow2 - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \param x any value
|
||||
* \param pow2 must be a power of 2
|
||||
* \returns \p pow2 - (\p x modulo \p pow2).
|
||||
*/
|
||||
static inline size_t
|
||||
p2_modulo_neg(size_t x, size_t pow2)
|
||||
{
|
||||
return pow2 - p2_modulo(x, pow2);
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* _GR_MATH_H_ */
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- 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_MISC_H
|
||||
#define INCLUDED_GR_MISC_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/types.h>
|
||||
|
||||
GR_RUNTIME_API unsigned int
|
||||
gr_rounduppow2(unsigned int n);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
#endif /* INCLUDED_GR_MISC_H */
|
|
@ -0,0 +1,152 @@
|
|||
/* -*- 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_PREFS_H
|
||||
#define INCLUDED_GR_PREFS_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
typedef std::map< std::string, std::map<std::string, std::string> > config_map_t;
|
||||
typedef std::map< std::string, std::map<std::string, std::string> >::iterator config_map_itr;
|
||||
typedef std::map<std::string, std::string> config_map_elem_t;
|
||||
typedef std::map<std::string, std::string>::iterator config_map_elem_itr;
|
||||
|
||||
/*!
|
||||
* \brief Base class for representing user preferences a la windows INI files.
|
||||
* \ingroup misc
|
||||
*
|
||||
* The real implementation is in Python, and is accessable from C++
|
||||
* via the magic of SWIG directors.
|
||||
*/
|
||||
class GR_RUNTIME_API prefs
|
||||
{
|
||||
public:
|
||||
static prefs *singleton();
|
||||
static void set_singleton(prefs *p);
|
||||
|
||||
prefs();
|
||||
virtual ~prefs();
|
||||
|
||||
/*!
|
||||
* \brief Returns the configuration options as a string.
|
||||
*/
|
||||
std::string to_string();
|
||||
|
||||
/*!
|
||||
* \brief Saves the configuration settings to
|
||||
* ${HOME}/.gnuradio/config.conf.
|
||||
*
|
||||
* WARNING: this will overwrite your current config.conf file.
|
||||
*/
|
||||
void save();
|
||||
|
||||
/*!
|
||||
* \brief Does \p section exist?
|
||||
*/
|
||||
virtual bool has_section(const std::string §ion);
|
||||
|
||||
/*!
|
||||
* \brief Does \p option exist?
|
||||
*/
|
||||
virtual bool has_option(const std::string §ion,
|
||||
const std::string &option);
|
||||
|
||||
/*!
|
||||
* \brief If option exists return associated value; else
|
||||
* default_val.
|
||||
*/
|
||||
virtual const std::string get_string(const std::string §ion,
|
||||
const std::string &option,
|
||||
const std::string &default_val);
|
||||
|
||||
/*!
|
||||
* \brief Set or add a string \p option to \p section with value
|
||||
* \p val.
|
||||
*/
|
||||
virtual void set_string(const std::string §ion,
|
||||
const std::string &option,
|
||||
const std::string &val);
|
||||
|
||||
/*!
|
||||
* \brief If option exists and value can be converted to bool,
|
||||
* return it; else default_val.
|
||||
*/
|
||||
virtual bool get_bool(const std::string §ion,
|
||||
const std::string &option,
|
||||
bool default_val);
|
||||
|
||||
/*!
|
||||
* \brief Set or add a bool \p option to \p section with value \p val.
|
||||
*/
|
||||
virtual void set_bool(const std::string §ion,
|
||||
const std::string &option,
|
||||
bool val);
|
||||
|
||||
/*!
|
||||
* \brief If option exists and value can be converted to long,
|
||||
* return it; else default_val.
|
||||
*/
|
||||
virtual long get_long(const std::string §ion,
|
||||
const std::string &option,
|
||||
long default_val);
|
||||
|
||||
/*!
|
||||
* \brief Set or add a long \p option to \p section with value \p val.
|
||||
*/
|
||||
virtual void set_long(const std::string §ion,
|
||||
const std::string &option,
|
||||
long val);
|
||||
|
||||
/*!
|
||||
* \brief If option exists and value can be converted to double,
|
||||
* return it; else default_val.
|
||||
*/
|
||||
virtual double get_double(const std::string §ion,
|
||||
const std::string &option,
|
||||
double default_val);
|
||||
|
||||
/*!
|
||||
* \brief Set or add a double \p option to \p section with value \p val.
|
||||
*/
|
||||
virtual void set_double(const std::string §ion,
|
||||
const std::string &option,
|
||||
double val);
|
||||
|
||||
protected:
|
||||
virtual std::vector<std::string> _sys_prefs_filenames();
|
||||
virtual void _read_files();
|
||||
virtual void _convert_to_map(const std::string &conf);
|
||||
virtual char * option_to_env(std::string section, std::string option);
|
||||
|
||||
private:
|
||||
gr::thread::mutex d_mutex;
|
||||
config_map_t d_config_map;
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_PREFS_H */
|
|
@ -0,0 +1,81 @@
|
|||
/* -*- 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 <gnuradio/api.h>
|
||||
#include <gnuradio/gr_complex.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>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief pseudo random number generator
|
||||
* \ingroup math_blk
|
||||
*/
|
||||
class GR_RUNTIME_API random
|
||||
{
|
||||
protected:
|
||||
static const int NTAB = 32;
|
||||
long d_seed;
|
||||
long d_iy;
|
||||
long d_iv[NTAB];
|
||||
int d_iset;
|
||||
float d_gset;
|
||||
|
||||
public:
|
||||
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();
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RANDOM_H */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- 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_REALTIME_H
|
||||
#define INCLUDED_GR_REALTIME_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/realtime_impl.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief If possible, enable high-priority "real time" scheduling.
|
||||
* \ingroup misc
|
||||
*/
|
||||
GR_RUNTIME_API rt_status_t enable_realtime_scheduling();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_REALTIME_H */
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GNURADIO_REALTIME_H
|
||||
#define INCLUDED_GNURADIO_REALTIME_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <stdexcept>
|
||||
|
||||
/*!
|
||||
* \brief System independent way to ask for realtime scheduling
|
||||
*
|
||||
* \sa sys_pri.h
|
||||
*/
|
||||
namespace gr {
|
||||
|
||||
typedef enum {
|
||||
RT_OK = 0,
|
||||
RT_NOT_IMPLEMENTED,
|
||||
RT_NO_PRIVS,
|
||||
RT_OTHER_ERROR
|
||||
} rt_status_t;
|
||||
|
||||
enum rt_sched_policy {
|
||||
RT_SCHED_RR = 0, // round robin
|
||||
RT_SCHED_FIFO = 1, // first in first out
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
/*
|
||||
* Define the range for our virtual priorities (don't change
|
||||
* these)
|
||||
*
|
||||
* Processes (or threads) with numerically higher priority values
|
||||
* are scheduled before processes with numerically lower priority
|
||||
* values. Thus, the value returned by rt_priority_max() will be
|
||||
* greater than the value returned by rt_priority_min().
|
||||
*/
|
||||
static inline int rt_priority_min() { return 0; }
|
||||
static inline int rt_priority_max() { return 15; }
|
||||
static inline int rt_priority_default() { return 1; }
|
||||
|
||||
struct GR_RUNTIME_API rt_sched_param {
|
||||
int priority;
|
||||
rt_sched_policy policy;
|
||||
|
||||
rt_sched_param()
|
||||
: priority(rt_priority_default()), policy(RT_SCHED_RR){}
|
||||
|
||||
rt_sched_param(int priority_, rt_sched_policy policy_ = RT_SCHED_RR)
|
||||
{
|
||||
if(priority_ < rt_priority_min() || priority_ > rt_priority_max())
|
||||
throw std::invalid_argument("rt_sched_param: priority out of range");
|
||||
|
||||
priority = priority_;
|
||||
policy = policy_;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief If possible, enable "realtime" scheduling.
|
||||
* \ingroup misc
|
||||
*
|
||||
* In general, this means that the code will be scheduled before
|
||||
* any non-realtime (normal) processes. Note that if your code
|
||||
* contains an non-blocking infinite loop and you enable realtime
|
||||
* scheduling, it's possible to hang the system.
|
||||
*/
|
||||
|
||||
// NOTE: If you change this, you need to change the code in
|
||||
// gnuradio-runtime/swig/realtime.i, see note there.
|
||||
GR_RUNTIME_API rt_status_t enable_realtime_scheduling(rt_sched_param = rt_sched_param());
|
||||
|
||||
} /* namespace impl */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GNURADIO_REALTIME_H */
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_RUNTIME_TYPES_H
|
||||
#define INCLUDED_GR_RUNTIME_TYPES_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/types.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*
|
||||
* typedefs for smart pointers we use throughout the runtime system
|
||||
*/
|
||||
class basic_block;
|
||||
class block;
|
||||
class block_detail;
|
||||
class buffer;
|
||||
class buffer_reader;
|
||||
class hier_block2;
|
||||
class flat_flowgraph;
|
||||
class flowgraph;
|
||||
class top_block;
|
||||
|
||||
typedef boost::shared_ptr<basic_block> basic_block_sptr;
|
||||
typedef boost::shared_ptr<block> block_sptr;
|
||||
typedef boost::shared_ptr<block_detail> block_detail_sptr;
|
||||
typedef boost::shared_ptr<buffer> buffer_sptr;
|
||||
typedef boost::shared_ptr<buffer_reader> buffer_reader_sptr;
|
||||
typedef boost::shared_ptr<hier_block2> hier_block2_sptr;
|
||||
typedef boost::shared_ptr<flat_flowgraph> flat_flowgraph_sptr;
|
||||
typedef boost::shared_ptr<flowgraph> flowgraph_sptr;
|
||||
typedef boost::shared_ptr<top_block> top_block_sptr;
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_TYPES_H */
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2002,2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_SINCOS_H
|
||||
#define INCLUDED_GR_SINCOS_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
// compute sine and cosine at the same time
|
||||
GR_RUNTIME_API void sincos (double x, double *sin, double *cos);
|
||||
GR_RUNTIME_API void sincosf (float x, float *sin, float *cos);
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_GR_SINCOS_H */
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- 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_RUNTIME_SPTR_MAGIC_H
|
||||
#define INCLUDED_GR_RUNTIME_SPTR_MAGIC_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace gr {
|
||||
class basic_block;
|
||||
class hier_block2;
|
||||
}
|
||||
|
||||
namespace gnuradio {
|
||||
namespace detail {
|
||||
|
||||
class GR_RUNTIME_API sptr_magic
|
||||
{
|
||||
public:
|
||||
static boost::shared_ptr<gr::basic_block> fetch_initial_sptr(gr::basic_block *p);
|
||||
static void create_and_stash_initial_sptr(gr::hier_block2 *p);
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* \brief New! Improved! Standard method to get/create the
|
||||
* boost::shared_ptr for a block.
|
||||
*/
|
||||
template<class T>
|
||||
boost::shared_ptr<T>
|
||||
get_initial_sptr(T *p)
|
||||
{
|
||||
return boost::dynamic_pointer_cast<T, gr::basic_block>
|
||||
(detail::sptr_magic::fetch_initial_sptr(p));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_SPTR_MAGIC_H */
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_RUNTIME_SYNC_BLOCK_H
|
||||
#define INCLUDED_GR_RUNTIME_SYNC_BLOCK_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/block.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief synchronous 1:1 input to output with history
|
||||
* \ingroup base_blk
|
||||
*
|
||||
* Override work to provide the signal processing implementation.
|
||||
*/
|
||||
class GR_RUNTIME_API sync_block : public block
|
||||
{
|
||||
protected:
|
||||
sync_block(void) {} // allows pure virtual interface sub-classes
|
||||
sync_block(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature);
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief just like gr::block::general_work, only this arranges to
|
||||
* call consume_each for you
|
||||
*
|
||||
* The user must override work to define the signal processing code
|
||||
*/
|
||||
virtual int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items) = 0;
|
||||
|
||||
// gr::sync_block overrides these to assist work
|
||||
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 fixed_rate_ninput_to_noutput(int ninput);
|
||||
int fixed_rate_noutput_to_ninput(int noutput);
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_SYNC_BLOCK_H */
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H
|
||||
#define INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief synchronous N:1 input to output with history
|
||||
* \ingroup base_blk
|
||||
*
|
||||
* Override work to provide the signal processing implementation.
|
||||
*/
|
||||
class GR_RUNTIME_API sync_decimator : public sync_block
|
||||
{
|
||||
private:
|
||||
unsigned d_decimation;
|
||||
|
||||
protected:
|
||||
sync_decimator(void) {} // allows pure virtual interface sub-classes
|
||||
sync_decimator(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature,
|
||||
unsigned decimation);
|
||||
|
||||
public:
|
||||
unsigned decimation() const { return d_decimation; }
|
||||
void set_decimation(unsigned decimation)
|
||||
{
|
||||
d_decimation = decimation;
|
||||
set_relative_rate(1.0 / decimation);
|
||||
}
|
||||
|
||||
// gr::sync_decimator overrides these to assist work
|
||||
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);
|
||||
|
||||
// derived classes should override work
|
||||
|
||||
int fixed_rate_ninput_to_noutput(int ninput);
|
||||
int fixed_rate_noutput_to_ninput(int noutput);
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_SYNC_DECIMATOR_H */
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- 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_SYNC_INTERPOLATOR_H
|
||||
#define INCLUDED_GR_RUNTIME_SYNC_INTERPOLATOR_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/sync_block.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief synchronous 1:N input to output with history
|
||||
* \ingroup base_blk
|
||||
*
|
||||
* Override work to provide the signal processing implementation.
|
||||
*/
|
||||
class GR_RUNTIME_API sync_interpolator : public sync_block
|
||||
{
|
||||
private:
|
||||
unsigned d_interpolation;
|
||||
|
||||
protected:
|
||||
sync_interpolator(void) {} // allows pure virtual interface sub-classes
|
||||
sync_interpolator(const std::string &name,
|
||||
gr::io_signature::sptr input_signature,
|
||||
gr::io_signature::sptr output_signature,
|
||||
unsigned interpolation);
|
||||
|
||||
public:
|
||||
unsigned interpolation() const { return d_interpolation; }
|
||||
void set_interpolation(unsigned interpolation)
|
||||
{
|
||||
d_interpolation = interpolation;
|
||||
set_relative_rate(1.0 * interpolation);
|
||||
set_output_multiple(interpolation);
|
||||
}
|
||||
|
||||
// gr::sync_interpolator overrides these to assist work
|
||||
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);
|
||||
|
||||
// derived classes should override work
|
||||
|
||||
int fixed_rate_ninput_to_noutput(int ninput);
|
||||
int fixed_rate_noutput_to_ninput(int noutput);
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_RUNTIME_SYNC_INTERPOLATOR_H */
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef GR_SYS_PATHS_H
|
||||
#define GR_SYS_PATHS_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
//! directory to create temporary files
|
||||
GR_RUNTIME_API const char *tmp_path();
|
||||
|
||||
//! directory to store application data
|
||||
GR_RUNTIME_API const char *appdata_path();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* GR_SYS_PATHS_H */
|
|
@ -0,0 +1,156 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_THREAD_H
|
||||
#define INCLUDED_THREAD_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/thread/locks.hpp>
|
||||
#include <boost/thread/condition_variable.hpp>
|
||||
#include <vector>
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace gr {
|
||||
namespace thread {
|
||||
|
||||
typedef boost::thread thread;
|
||||
typedef boost::mutex mutex;
|
||||
typedef boost::unique_lock<boost::mutex> scoped_lock;
|
||||
typedef boost::condition_variable condition_variable;
|
||||
|
||||
/*! \brief a system-dependent typedef for the underlying thread type.
|
||||
*/
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
|
||||
typedef HANDLE gr_thread_t;
|
||||
#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
|
||||
typedef pthread_t gr_thread_t;
|
||||
#else
|
||||
typedef pthread_t gr_thread_t;
|
||||
#endif
|
||||
|
||||
/*! \brief Get the current thread's ID as a gr_thread_t
|
||||
*
|
||||
* We use this when setting the thread affinity or any other
|
||||
* low-level thread settings. Can be called withing a GNU Radio
|
||||
* block to get a reference to its current thread ID.
|
||||
*/
|
||||
GR_RUNTIME_API gr_thread_t get_current_thread_id();
|
||||
|
||||
/*! \brief Bind the current thread to a set of cores.
|
||||
*
|
||||
* Wrapper for system-dependent calls to set the affinity of the
|
||||
* current thread to the processor mask. The mask is simply a
|
||||
* 1-demensional vector containing the processor or core number
|
||||
* from 0 to N-1 for N cores.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_bind_to_processor(const std::vector<int> &mask);
|
||||
|
||||
/*! \brief Convineince function to bind the current thread to a single core.
|
||||
*
|
||||
* Wrapper for system-dependent calls to set the affinity of the
|
||||
* current thread to a given core from 0 to N-1 for N cores.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_bind_to_processor(int n);
|
||||
|
||||
/*! \brief Bind a thread to a set of cores.
|
||||
*
|
||||
* Wrapper for system-dependent calls to set the affinity of the
|
||||
* given thread ID to the processor mask. The mask is simply a
|
||||
* 1-demensional vector containing the processor or core number
|
||||
* from 0 to N-1 for N cores.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread,
|
||||
const std::vector<int> &mask);
|
||||
|
||||
|
||||
/*! \brief Convineince function to bind the a thread to a single core.
|
||||
*
|
||||
* Wrapper for system-dependent calls to set the affinity of the
|
||||
* given thread ID to a given core from 0 to N-1 for N cores.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_bind_to_processor(gr_thread_t thread,
|
||||
unsigned int n);
|
||||
|
||||
/*! \brief Remove any thread-processor affinity for the current thread.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_unbind();
|
||||
|
||||
/*! \brief Remove any thread-processor affinity for a given thread ID.
|
||||
*
|
||||
* Note: this does not work on OSX; it is a nop call since OSX
|
||||
* does not support the concept of thread affinity (and what they
|
||||
* do support in this way since 10.5 is not what we want or can
|
||||
* use in this fashion).
|
||||
*/
|
||||
GR_RUNTIME_API void thread_unbind(gr_thread_t thread);
|
||||
|
||||
/*! \brief get current thread priority for a given thread ID
|
||||
*
|
||||
* Note: this does not work on OSX
|
||||
*/
|
||||
GR_RUNTIME_API int thread_priority(gr_thread_t thread);
|
||||
|
||||
/*! \brief get current thread priority for a given thread ID
|
||||
*
|
||||
* Note: this does not work on OSX
|
||||
*/
|
||||
GR_RUNTIME_API int set_thread_priority(gr_thread_t thread, int priority);
|
||||
|
||||
} /* namespace thread */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_THREAD_H */
|
|
@ -0,0 +1,72 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_THREAD_BODY_WRAPPER_H
|
||||
#define INCLUDED_THREAD_BODY_WRAPPER_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace gr {
|
||||
namespace thread {
|
||||
|
||||
GR_RUNTIME_API void mask_signals();
|
||||
|
||||
template <class F>
|
||||
class thread_body_wrapper
|
||||
{
|
||||
private:
|
||||
F d_f;
|
||||
std::string d_name;
|
||||
|
||||
public:
|
||||
explicit thread_body_wrapper(F f, const std::string &name="")
|
||||
: d_f(f), d_name(name) {}
|
||||
|
||||
void operator()()
|
||||
{
|
||||
mask_signals();
|
||||
|
||||
try {
|
||||
d_f();
|
||||
}
|
||||
catch(boost::thread_interrupted const &)
|
||||
{
|
||||
}
|
||||
catch(std::exception const &e)
|
||||
{
|
||||
std::cerr << "thread[" << d_name << "]: "
|
||||
<< e.what() << std::endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "thread[" << d_name << "]: "
|
||||
<< "caught unrecognized exception\n";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace thread */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_THREAD_BODY_WRAPPER_H */
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright (C) 2001-2003 William E. Kempf
|
||||
* Copyright (C) 2007 Anthony Williams
|
||||
* Copyright 2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/*
|
||||
* This was extracted from Boost 1.35.0 and fixed.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_THREAD_GROUP_H
|
||||
#define INCLUDED_THREAD_GROUP_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/thread/shared_mutex.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
namespace gr {
|
||||
namespace thread {
|
||||
|
||||
class GR_RUNTIME_API thread_group : public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
thread_group();
|
||||
~thread_group();
|
||||
|
||||
boost::thread* create_thread(const boost::function0<void>& threadfunc);
|
||||
void add_thread(boost::thread* thrd);
|
||||
void remove_thread(boost::thread* thrd);
|
||||
void join_all();
|
||||
void interrupt_all();
|
||||
size_t size() const;
|
||||
|
||||
private:
|
||||
std::list<boost::thread*> m_threads;
|
||||
mutable boost::shared_mutex m_mutex;
|
||||
};
|
||||
|
||||
} /* namespace thread */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_THREAD_GROUP_H */
|
|
@ -0,0 +1,146 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 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_TOP_BLOCK_H
|
||||
#define INCLUDED_GR_TOP_BLOCK_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/hier_block2.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
class top_block_impl;
|
||||
|
||||
GR_RUNTIME_API top_block_sptr make_top_block(const std::string &name);
|
||||
|
||||
/*!
|
||||
*\brief Top-level hierarchical block representing a flowgraph
|
||||
* \ingroup container_blk
|
||||
*/
|
||||
class GR_RUNTIME_API top_block : public hier_block2
|
||||
{
|
||||
private:
|
||||
friend GR_RUNTIME_API top_block_sptr
|
||||
make_top_block(const std::string &name);
|
||||
|
||||
top_block_impl *d_impl;
|
||||
|
||||
protected:
|
||||
top_block(const std::string &name);
|
||||
|
||||
public:
|
||||
~top_block();
|
||||
|
||||
/*!
|
||||
* \brief The simple interface to running a flowgraph.
|
||||
*
|
||||
* Calls start() then wait(). Used to run a flowgraph that will
|
||||
* stop on its own, or when another thread will call stop().
|
||||
*
|
||||
* \param max_noutput_items the maximum number of output items
|
||||
* allowed for any block in the flowgraph. This passes through to
|
||||
* the start function; see that function for more details.
|
||||
*/
|
||||
void run(int max_noutput_items=100000000);
|
||||
|
||||
/*!
|
||||
* Start the contained flowgraph. Creates one or more threads to
|
||||
* execute the flow graph. Returns to the caller once the threads
|
||||
* are created. Calling start() on a top_block that is already
|
||||
* started IS an error.
|
||||
*
|
||||
* \param max_noutput_items the maximum number of output items
|
||||
* allowed for any block in the flowgraph; the noutput_items can
|
||||
* always be less than this, but this will cap it as a
|
||||
* maximum. Use this to adjust the maximum latency a flowgraph can
|
||||
* exhibit.
|
||||
*/
|
||||
void start(int max_noutput_items=100000000);
|
||||
|
||||
/*!
|
||||
* Stop the running flowgraph. Notifies each thread created by the
|
||||
* scheduler to shutdown, then returns to caller. Calling stop()
|
||||
* on a top_block that is already stopped IS NOT an error.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/*!
|
||||
* Wait for a flowgraph to complete. Flowgraphs complete when
|
||||
* either (1) all blocks indicate that they are done (typically
|
||||
* only when using blocks.file_source, or blocks.head, or (2)
|
||||
* after stop() has been called to request shutdown. Calling wait
|
||||
* on a top_block that is not running IS NOT an error (wait
|
||||
* returns w/o blocking).
|
||||
*/
|
||||
void wait();
|
||||
|
||||
/*!
|
||||
* Lock a flowgraph in preparation for reconfiguration. When an
|
||||
* equal number of calls to lock() and unlock() have occurred, the
|
||||
* flowgraph will be reconfigured.
|
||||
*
|
||||
* N.B. lock() and unlock() may not be called from a flowgraph
|
||||
* thread (E.g., block::work method) or deadlock will occur
|
||||
* when reconfiguration happens.
|
||||
*/
|
||||
virtual void lock();
|
||||
|
||||
/*!
|
||||
* Unlock a flowgraph in preparation for reconfiguration. When an
|
||||
* equal number of calls to lock() and unlock() have occurred, the
|
||||
* flowgraph will be reconfigured.
|
||||
*
|
||||
* N.B. lock() and unlock() may not be called from a flowgraph thread
|
||||
* (E.g., block::work method) or deadlock will occur when
|
||||
* reconfiguration happens.
|
||||
*/
|
||||
virtual void unlock();
|
||||
|
||||
/*!
|
||||
* Returns a string that lists the edge connections in the
|
||||
* flattened flowgraph.
|
||||
*/
|
||||
std::string edge_list();
|
||||
|
||||
/*!
|
||||
* Displays flattened flowgraph edges and block connectivity
|
||||
*/
|
||||
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);
|
||||
|
||||
top_block_sptr to_top_block(); // Needed for Python type coercion
|
||||
|
||||
void setup_rpc();
|
||||
};
|
||||
|
||||
inline top_block_sptr cast_to_top_block_sptr(basic_block_sptr block) {
|
||||
return boost::dynamic_pointer_cast<top_block, basic_block>(block);
|
||||
}
|
||||
|
||||
} /* namespce gr */
|
||||
|
||||
#endif /* INCLUDED_GR_TOP_BLOCK_H */
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_TPB_DETAIL_H
|
||||
#define INCLUDED_GR_TPB_DETAIL_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/thread/thread.h>
|
||||
#include <deque>
|
||||
|
||||
namespace gr {
|
||||
|
||||
class block_detail;
|
||||
|
||||
/*!
|
||||
* \brief used by thread-per-block scheduler
|
||||
*/
|
||||
struct GR_RUNTIME_API tpb_detail {
|
||||
gr::thread::mutex mutex; //< protects all vars
|
||||
bool input_changed;
|
||||
gr::thread::condition_variable input_cond;
|
||||
bool output_changed;
|
||||
gr::thread::condition_variable output_cond;
|
||||
|
||||
public:
|
||||
tpb_detail()
|
||||
: input_changed(false), output_changed(false) { }
|
||||
|
||||
//! Called by us to tell all our upstream blocks that their output
|
||||
//! may have changed.
|
||||
void notify_upstream(block_detail *d);
|
||||
|
||||
//! Called by us to tell all our downstream blocks that their
|
||||
//! input may have changed.
|
||||
void notify_downstream(block_detail *d);
|
||||
|
||||
//! Called by us to notify both upstream and downstream
|
||||
void notify_neighbors(block_detail *d);
|
||||
|
||||
//! Called by pmt msg posters
|
||||
void notify_msg() {
|
||||
input_cond.notify_one();
|
||||
output_cond.notify_one();
|
||||
}
|
||||
|
||||
//! Called by us
|
||||
void clear_changed()
|
||||
{
|
||||
gr::thread::scoped_lock guard(mutex);
|
||||
input_changed = false;
|
||||
output_changed = false;
|
||||
}
|
||||
|
||||
private:
|
||||
//! Used by notify_downstream
|
||||
void set_input_changed()
|
||||
{
|
||||
gr::thread::scoped_lock guard(mutex);
|
||||
input_changed = true;
|
||||
input_cond.notify_one();
|
||||
}
|
||||
|
||||
//! Used by notify_upstream
|
||||
void set_output_changed()
|
||||
{
|
||||
gr::thread::scoped_lock guard(mutex);
|
||||
output_changed = true;
|
||||
output_cond.notify_one();
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_TPB_DETAIL_H */
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_TYPES_H
|
||||
#define INCLUDED_GR_TYPES_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <vector>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#include <gnuradio/gr_complex.h>
|
||||
|
||||
typedef std::vector<int> gr_vector_int;
|
||||
typedef std::vector<unsigned int> gr_vector_uint;
|
||||
typedef std::vector<float> gr_vector_float;
|
||||
typedef std::vector<double> gr_vector_double;
|
||||
typedef std::vector<void *> gr_vector_void_star;
|
||||
typedef std::vector<const void *> gr_vector_const_void_star;
|
||||
|
||||
/*
|
||||
* #include <config.h> must be placed beforehand
|
||||
* in the source file including gnuradio/types.h for
|
||||
* the following to work correctly
|
||||
*/
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
typedef int16_t gr_int16;
|
||||
typedef int32_t gr_int32;
|
||||
typedef int64_t gr_int64;
|
||||
typedef uint16_t gr_uint16;
|
||||
typedef uint32_t gr_uint32;
|
||||
typedef uint64_t gr_uint64;
|
||||
#else
|
||||
/*
|
||||
* Note: these defaults may be wrong on 64-bit systems
|
||||
*/
|
||||
typedef short gr_int16;
|
||||
typedef int gr_int32;
|
||||
typedef long long gr_int64;
|
||||
typedef unsigned short gr_uint16;
|
||||
typedef unsigned int gr_uint32;
|
||||
typedef unsigned long long gr_uint64;
|
||||
#endif /* HAVE_STDINT_H */
|
||||
|
||||
#endif /* INCLUDED_GR_TYPES_H */
|
|
@ -49,6 +49,144 @@ GR_OSMOSDR_APPEND_LIBS(
|
|||
${GNURADIO_BLOCKS_LIBRARIES}
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Set up built-in GNU Radio runtime component
|
||||
########################################################################
|
||||
GR_REGISTER_COMPONENT("Built-in GNU Radio runtime" ENABLE_RUNTIME RUNTIME_MODE)
|
||||
if(ENABLE_RUNTIME)
|
||||
|
||||
message(STATUS "")
|
||||
INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/ConfigChecks.cmake)
|
||||
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/runtime)
|
||||
|
||||
GR_OSMOSDR_APPEND_SRCS(
|
||||
runtime/blocks/throttle_impl.cc
|
||||
runtime/blocks/null_sink_impl.cc
|
||||
runtime/blocks/null_source_impl.cc
|
||||
|
||||
runtime/math/fast_atan2f.cc
|
||||
runtime/math//fxpt.cc
|
||||
runtime/math/random.cc
|
||||
runtime/math/sincos.cc
|
||||
|
||||
runtime/thread/thread.cc
|
||||
runtime/thread/thread_body_wrapper.cc
|
||||
runtime/thread/thread_group.cc
|
||||
|
||||
runtime/basic_block.cc
|
||||
runtime/block.cc
|
||||
runtime/block_detail.cc
|
||||
runtime/block_executor.cc
|
||||
runtime/block_gateway_impl.cc
|
||||
runtime/block_registry.cc
|
||||
runtime/buffer.cc
|
||||
runtime/circular_file.cc
|
||||
runtime/feval.cc
|
||||
runtime/flat_flowgraph.cc
|
||||
runtime/flowgraph.cc
|
||||
runtime/hier_block2.cc
|
||||
runtime/hier_block2_detail.cc
|
||||
runtime/high_res_timer.cc
|
||||
runtime/io_signature.cc
|
||||
runtime/local_sighandler.cc
|
||||
runtime/logger.cc
|
||||
runtime/misc.cc
|
||||
runtime/pagesize.cc
|
||||
runtime/prefs.cc
|
||||
runtime/realtime.cc
|
||||
runtime/realtime_impl.cc
|
||||
runtime/scheduler.cc
|
||||
runtime/scheduler_sts.cc
|
||||
runtime/scheduler_tpb.cc
|
||||
runtime/single_threaded_scheduler.cc
|
||||
runtime/sptr_magic.cc
|
||||
runtime/sync_block.cc
|
||||
runtime/sys_paths.cc
|
||||
runtime/top_block.cc
|
||||
runtime/top_block_impl.cc
|
||||
runtime/tpb_detail.cc
|
||||
runtime/tpb_thread_body.cc
|
||||
runtime/vmcircbuf.cc
|
||||
runtime/vmcircbuf_createfilemapping.cc
|
||||
runtime/vmcircbuf_mmap_shm_open.cc
|
||||
runtime/vmcircbuf_mmap_tmpfile.cc
|
||||
runtime/vmcircbuf_prefs.cc
|
||||
runtime/vmcircbuf_sysv_shm.cc
|
||||
)
|
||||
|
||||
########################################################################
|
||||
# Handle the generated constants
|
||||
########################################################################
|
||||
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
|
||||
)
|
||||
|
||||
set(GR_VERSION "built-in")
|
||||
|
||||
message(STATUS "Loading prefix ${prefix} into constants...")
|
||||
message(STATUS "Loading SYSCONFDIR ${SYSCONFDIR} into constants...")
|
||||
message(STATUS "Loading GR_PREFSDIR ${GR_PREFSDIR} into constants...")
|
||||
message(STATUS "Loading build date ${BUILD_DATE} into constants...")
|
||||
message(STATUS "Loading version ${GR_VERSION} into constants...")
|
||||
|
||||
#double escape for windows backslash path separators
|
||||
string(REPLACE "\\" "\\\\" prefix ${prefix})
|
||||
string(REPLACE "\\" "\\\\" SYSCONFDIR ${SYSCONFDIR})
|
||||
string(REPLACE "\\" "\\\\" GR_PREFSDIR ${GR_PREFSDIR})
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/runtime/constants.cc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/constants.cc
|
||||
@ONLY)
|
||||
|
||||
GR_OSMOSDR_APPEND_SRCS(${CMAKE_CURRENT_BINARY_DIR}/constants.cc)
|
||||
|
||||
# PowerPC workaround for posix_memalign
|
||||
# Might not be needed, but we'll keep it for now.
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||
GR_OSMOSDR_APPEND_SRCS(runtime/posix_memalign.cc)
|
||||
endif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||
|
||||
########################################################################
|
||||
# Will set TRY_SHM_VMCIRCBUF to 1 by default except on Windows machines.
|
||||
# Can manually set with -DTRY_SHM_VMCIRCBUF=0|1
|
||||
########################################################################
|
||||
if(WIN32)
|
||||
OPTION(TRY_SHM_VMCIRCBUF "Try SHM VMCIRCBUF" OFF)
|
||||
else(WIN32)
|
||||
OPTION(TRY_SHM_VMCIRCBUF "Try SHM VMCIRCBUF" ON)
|
||||
endif(WIN32)
|
||||
|
||||
message(STATUS "TRY_SHM_VMCIRCBUF set to ${TRY_SHM_VMCIRCBUF}.")
|
||||
|
||||
if(TRY_SHM_VMCIRCBUF)
|
||||
ADD_DEFINITIONS( -DTRY_SHM_VMCIRCBUF )
|
||||
endif(TRY_SHM_VMCIRCBUF)
|
||||
|
||||
########################################################################
|
||||
# Add libraries for winsock2.h on Windows
|
||||
########################################################################
|
||||
CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H)
|
||||
if(HAVE_WINDOWS_H)
|
||||
include_directories(${CMAKE_SOURCE_DIR}/cmake/msvc)
|
||||
ADD_DEFINITIONS(-DHAVE_WINDOWS_H -DUSING_WINSOCK -DWIN32_LEAN_AND_MEAN)
|
||||
ADD_DEFINITIONS(-DNOMINMAX -D_USE_MATH_DEFINES)
|
||||
ADD_DEFINITIONS(/MP -D_CRT_SECURE_NO_WARNINGS -DD_CRT_SECURE_NO_DEPRECATE)
|
||||
MESSAGE(STATUS "Adding windows libs to gnuradio osmosdr lib...")
|
||||
GR_OSMOSDR_APPEND_LIBS(WS2_32.lib WSock32.lib)
|
||||
endif(HAVE_WINDOWS_H)
|
||||
|
||||
########################################################################
|
||||
# Need to link with librt for shm_*
|
||||
########################################################################
|
||||
if(LINUX)
|
||||
GR_OSMOSDR_APPEND_LIBS(rt)
|
||||
endif()
|
||||
|
||||
endif(ENABLE_RUNTIME)
|
||||
|
||||
########################################################################
|
||||
# Setup IQBalance component
|
||||
########################################################################
|
||||
|
@ -169,3 +307,8 @@ ADD_LIBRARY(gnuradio-osmosdr SHARED ${gr_osmosdr_srcs})
|
|||
TARGET_LINK_LIBRARIES(gnuradio-osmosdr ${gr_osmosdr_libs})
|
||||
SET_TARGET_PROPERTIES(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_osmosdr_EXPORTS")
|
||||
GR_LIBRARY_FOO(gnuradio-osmosdr)
|
||||
|
||||
if(ENABLE_RUNTIME)
|
||||
SET_TARGET_PROPERTIES(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_runtime_EXPORTS")
|
||||
SET_TARGET_PROPERTIES(gnuradio-osmosdr PROPERTIES DEFINE_SYMBOL "gnuradio_blocks_EXPORTS")
|
||||
endif(ENABLE_RUNTIME)
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
# 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.
|
||||
|
||||
########################################################################
|
||||
INCLUDE(GrMiscUtils)
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
IF(MSVC) #add this directory for our provided headers
|
||||
LIST(APPEND CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/msvc)
|
||||
ENDIF(MSVC)
|
||||
|
||||
#GR_CHECK_HDR_N_DEF(netdb.h HAVE_NETDB_H)
|
||||
#GR_CHECK_HDR_N_DEF(sys/time.h HAVE_SYS_TIME_H)
|
||||
GR_CHECK_HDR_N_DEF(sys/types.h HAVE_SYS_TYPES_H)
|
||||
#GR_CHECK_HDR_N_DEF(sys/select.h HAVE_SYS_SELECT_H)
|
||||
#GR_CHECK_HDR_N_DEF(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
#GR_CHECK_HDR_N_DEF(sys/resource.h HAVE_SYS_RESOURCE_H)
|
||||
GR_CHECK_HDR_N_DEF(io.h HAVE_IO_H)
|
||||
GR_CHECK_HDR_N_DEF(sys/mman.h HAVE_SYS_MMAN_H)
|
||||
GR_CHECK_HDR_N_DEF(sys/ipc.h HAVE_SYS_IPC_H)
|
||||
GR_CHECK_HDR_N_DEF(sys/shm.h HAVE_SYS_SHM_H)
|
||||
GR_CHECK_HDR_N_DEF(signal.h HAVE_SIGNAL_H)
|
||||
#GR_CHECK_HDR_N_DEF(netinet/in.h HAVE_NETINET_IN_H)
|
||||
#GR_CHECK_HDR_N_DEF(arpa/inet.h HAVE_ARPA_INET_H)
|
||||
#GR_CHECK_HDR_N_DEF(byteswap.h HAVE_BYTESWAP_H)
|
||||
#GR_CHECK_HDR_N_DEF(linux/ppdev.h HAVE_LINUX_PPDEV_H)
|
||||
#GR_CHECK_HDR_N_DEF(dev/ppbus/ppi.h HAVE_DEV_PPBUS_PPI_H)
|
||||
GR_CHECK_HDR_N_DEF(unistd.h HAVE_UNISTD_H)
|
||||
#GR_CHECK_HDR_N_DEF(malloc.h HAVE_MALLOC_H)
|
||||
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <stdio.h>
|
||||
int main(){snprintf(0, 0, 0); return 0;}
|
||||
" HAVE_SNPRINTF
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SNPRINTF)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <signal.h>
|
||||
int main(){sigaction(0, 0, 0); return 0;}
|
||||
" HAVE_SIGACTION
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SIGACTION)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sys/select.h>
|
||||
int main(){select(0, 0, 0, 0, 0); return 0;}
|
||||
" HAVE_SELECT
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SELECT)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <unistd.h>
|
||||
int main(){sysconf(0); return 0;}
|
||||
" HAVE_SYSCONF
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SYSCONF)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <unistd.h>
|
||||
int main(){getpagesize(); return 0;}
|
||||
" HAVE_GETPAGESIZE
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_GETPAGESIZE)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <Winbase.h>
|
||||
int main(){Sleep(0); return 0;}
|
||||
" HAVE_SSLEEP
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SSLEEP)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <time.h>
|
||||
int main(){nanosleep(0, 0); return 0;}
|
||||
" HAVE_NANOSLEEP
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_NANOSLEEP)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sys/time.h>
|
||||
int main(){gettimeofday(0, 0); return 0;}
|
||||
" HAVE_GETTIMEOFDAY
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_GETTIMEOFDAY)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <stdlib.h>
|
||||
int main(){posix_memalign(0, 0, 0); return 0;}
|
||||
" HAVE_POSIX_MEMALIGN
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_POSIX_MEMALIGN)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <malloc.h>
|
||||
int main(){valloc(0); return 0;}
|
||||
" HAVE_VALLOC
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_VALLOC)
|
||||
|
||||
ADD_DEFINITIONS(-DALIGNED_MALLOC=0)
|
||||
|
||||
########################################################################
|
||||
SET(CMAKE_REQUIRED_LIBRARIES -lpthread)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <signal.h>
|
||||
int main(){pthread_sigmask(0, 0, 0); return 0;}
|
||||
" HAVE_PTHREAD_SIGMASK
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_PTHREAD_SIGMASK)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <windows.h>
|
||||
int main(){
|
||||
HANDLE handle;
|
||||
int size;
|
||||
LPCTSTR lpName;
|
||||
handle = CreateFileMapping(
|
||||
INVALID_HANDLE_VALUE, // use paging file
|
||||
NULL, // default security
|
||||
PAGE_READWRITE, // read/write access
|
||||
0, // max. object size
|
||||
size, // buffer size
|
||||
lpName); // name of mapping object
|
||||
return 0;
|
||||
} " HAVE_CREATEFILEMAPPING
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_CREATEFILEMAPPING)
|
||||
|
||||
########################################################################
|
||||
SET(CMAKE_REQUIRED_LIBRARIES -lrt)
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
int main(){shm_open(0, 0, 0); return 0;}
|
||||
" HAVE_SHM_OPEN
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SHM_OPEN)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define _GNU_SOURCE
|
||||
#include <math.h>
|
||||
int main(){double x, sin, cos; sincos(x, &sin, &cos); return 0;}
|
||||
" HAVE_SINCOS
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SINCOS)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#define _GNU_SOURCE
|
||||
#include <math.h>
|
||||
int main(){float x, sin, cos; sincosf(x, &sin, &cos); return 0;}
|
||||
" HAVE_SINCOSF
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SINCOSF)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <math.h>
|
||||
int main(){sinf(0); return 0;}
|
||||
" HAVE_SINF
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_SINF)
|
||||
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <math.h>
|
||||
int main(){cosf(0); return 0;}
|
||||
" HAVE_COSF
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_COSF)
|
||||
|
||||
########################################################################
|
||||
CHECK_CXX_SOURCE_COMPILES("
|
||||
#include <sys/mman.h>
|
||||
int main(){mmap(0, 0, 0, 0, 0, 0); return 0;}
|
||||
" HAVE_MMAP
|
||||
)
|
||||
GR_ADD_COND_DEF(HAVE_MMAP)
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,626 @@
|
|||
/* -*- 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_priority(-1),
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
block::active_thread_priority()
|
||||
{
|
||||
if(d_detail) {
|
||||
return d_detail->thread_priority();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
block::thread_priority()
|
||||
{
|
||||
return d_priority;
|
||||
}
|
||||
|
||||
int
|
||||
block::set_thread_priority(int priority)
|
||||
{
|
||||
d_priority = priority;
|
||||
if(d_detail) {
|
||||
return d_detail->set_thread_priority(priority);
|
||||
}
|
||||
return d_priority;
|
||||
}
|
||||
|
||||
void
|
||||
block::expand_minmax_buffer(int port)
|
||||
{
|
||||
if((size_t)port >= d_max_output_buffer.size())
|
||||
set_max_output_buffer(port, -1);
|
||||
if((size_t)port >= d_min_output_buffer.size())
|
||||
set_min_output_buffer(port, -1);
|
||||
}
|
||||
|
||||
long
|
||||
block::max_output_buffer(size_t i)
|
||||
{
|
||||
if(i >= d_max_output_buffer.size())
|
||||
throw std::invalid_argument("basic_block::max_output_buffer: port out of range.");
|
||||
return d_max_output_buffer[i];
|
||||
}
|
||||
|
||||
void
|
||||
block::set_max_output_buffer(long max_output_buffer)
|
||||
{
|
||||
for(int i = 0; i < output_signature()->max_streams(); i++) {
|
||||
set_max_output_buffer(i, max_output_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
block::set_max_output_buffer(int port, long max_output_buffer)
|
||||
{
|
||||
if((size_t)port >= d_max_output_buffer.size())
|
||||
d_max_output_buffer.push_back(max_output_buffer);
|
||||
else
|
||||
d_max_output_buffer[port] = max_output_buffer;
|
||||
}
|
||||
|
||||
long
|
||||
block::min_output_buffer(size_t i)
|
||||
{
|
||||
if(i >= d_min_output_buffer.size())
|
||||
throw std::invalid_argument("basic_block::min_output_buffer: port out of range.");
|
||||
return d_min_output_buffer[i];
|
||||
}
|
||||
|
||||
void
|
||||
block::set_min_output_buffer(long min_output_buffer)
|
||||
{
|
||||
std::cout << "set_min_output_buffer on block " << unique_id() << " to " << min_output_buffer << std::endl;
|
||||
for(int i=0; i<output_signature()->max_streams(); i++) {
|
||||
set_min_output_buffer(i, min_output_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
block::set_min_output_buffer(int port, long min_output_buffer)
|
||||
{
|
||||
if((size_t)port >= d_min_output_buffer.size())
|
||||
d_min_output_buffer.push_back(min_output_buffer);
|
||||
else
|
||||
d_min_output_buffer[port] = min_output_buffer;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
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 */
|
|
@ -0,0 +1,435 @@
|
|||
/* -*- 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::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);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
block_detail::thread_priority(){
|
||||
if(threaded) {
|
||||
return gr::thread::thread_priority(thread);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
block_detail::set_thread_priority(int priority){
|
||||
if(threaded) {
|
||||
return gr::thread::set_thread_priority(thread,priority);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
block_detail::start_perf_counters()
|
||||
{
|
||||
d_start_of_work = gr::high_res_timer_now_perfmon();
|
||||
}
|
||||
|
||||
void
|
||||
block_detail::stop_perf_counters(int noutput_items, int nproduced)
|
||||
{
|
||||
d_end_of_work = gr::high_res_timer_now_perfmon();
|
||||
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++) {
|
||||
gr::thread::scoped_lock guard(*d_input[i]->mutex());
|
||||
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++) {
|
||||
gr::thread::scoped_lock guard(*d_output[i]->mutex());
|
||||
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++) {
|
||||
gr::thread::scoped_lock guard(*d_input[i]->mutex());
|
||||
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++) {
|
||||
gr::thread::scoped_lock guard(*d_output[i]->mutex());
|
||||
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 */
|
|
@ -0,0 +1,419 @@
|
|||
/* -*- 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;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
max_noutput_items = round_down(d_max_noutput_items, m->output_multiple());
|
||||
|
||||
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(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 */
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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 <fstream>
|
||||
#include <stdint.h>
|
||||
|
||||
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
|
||||
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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -0,0 +1,111 @@
|
|||
/* -*- 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()
|
||||
{
|
||||
}
|
||||
|
||||
long
|
||||
block_registry::block_register(basic_block* block)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
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)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
d_map[block->name()].erase( d_map[block->name()].find(block->symbolic_id()));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
block_registry::register_primitive(std::string blk, block* ref)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
primitive_map[blk] = ref;
|
||||
}
|
||||
|
||||
void
|
||||
block_registry::unregister_primitive(std::string blk)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
primitive_map.erase(primitive_map.find(blk));
|
||||
}
|
||||
|
||||
void
|
||||
block_registry::notify_blk(std::string blk)
|
||||
{
|
||||
gr::thread::scoped_lock guard(d_mutex);
|
||||
|
||||
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 */
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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 "null_sink_impl.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
null_sink::sptr
|
||||
null_sink::make(size_t sizeof_stream_item)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new null_sink_impl(sizeof_stream_item));
|
||||
}
|
||||
|
||||
null_sink_impl::null_sink_impl(size_t sizeof_stream_item)
|
||||
: sync_block("null_sink",
|
||||
io_signature::make(1, 1, sizeof_stream_item),
|
||||
io_signature::make(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
null_sink_impl::~null_sink_impl()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
null_sink_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_NULL_SINK_IMPL_H
|
||||
#define INCLUDED_GR_NULL_SINK_IMPL_H
|
||||
|
||||
#include <gnuradio/blocks/null_sink.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
class null_sink_impl : public null_sink
|
||||
{
|
||||
public:
|
||||
null_sink_impl(size_t sizeof_stream_item);
|
||||
~null_sink_impl();
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_NULL_SINK_IMPL_H */
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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 "null_source_impl.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
null_source::sptr
|
||||
null_source::make(size_t sizeof_stream_item)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new null_source_impl(sizeof_stream_item));
|
||||
}
|
||||
|
||||
null_source_impl::null_source_impl (size_t sizeof_stream_item)
|
||||
: sync_block("null_source",
|
||||
io_signature::make(0, 0, 0),
|
||||
io_signature::make(1, 1, sizeof_stream_item))
|
||||
{
|
||||
}
|
||||
|
||||
null_source_impl::~null_source_impl()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
null_source_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
void *optr = (void*)output_items[0];
|
||||
memset(optr, 0, noutput_items * output_signature()->sizeof_stream_item(0));
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,45 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_NULL_SOURCE_IMPL_H
|
||||
#define INCLUDED_GR_NULL_SOURCE_IMPL_H
|
||||
|
||||
#include <gnuradio/blocks/null_source.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
class null_source_impl : public null_source
|
||||
{
|
||||
public:
|
||||
null_source_impl(size_t sizeof_stream_item);
|
||||
~null_source_impl();
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_NULL_SOURCE_IMPL_H */
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 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 "throttle_impl.h"
|
||||
#include <gnuradio/io_signature.h>
|
||||
#include <cstring>
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
throttle::sptr
|
||||
throttle::make(size_t itemsize, double samples_per_sec)
|
||||
{
|
||||
return gnuradio::get_initial_sptr
|
||||
(new throttle_impl(itemsize, samples_per_sec));
|
||||
}
|
||||
|
||||
throttle_impl::throttle_impl(size_t itemsize,
|
||||
double samples_per_second)
|
||||
: sync_block("throttle",
|
||||
io_signature::make(1, 1, itemsize),
|
||||
io_signature::make(1, 1, itemsize)),
|
||||
d_itemsize(itemsize)
|
||||
{
|
||||
set_sample_rate(samples_per_second);
|
||||
}
|
||||
|
||||
throttle_impl::~throttle_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
throttle_impl::set_sample_rate(double rate)
|
||||
{
|
||||
//changing the sample rate performs a reset of state params
|
||||
d_start = boost::get_system_time();
|
||||
d_total_samples = 0;
|
||||
d_samps_per_tick = rate/boost::posix_time::time_duration::ticks_per_second();
|
||||
d_samps_per_us = rate/1e6;
|
||||
}
|
||||
|
||||
double
|
||||
throttle_impl::sample_rate() const
|
||||
{
|
||||
return d_samps_per_us * 1e6;
|
||||
}
|
||||
|
||||
int
|
||||
throttle_impl::work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items)
|
||||
{
|
||||
//calculate the expected number of samples to have passed through
|
||||
boost::system_time now = boost::get_system_time();
|
||||
boost::int64_t ticks = (now - d_start).ticks();
|
||||
uint64_t expected_samps = uint64_t(d_samps_per_tick*ticks);
|
||||
|
||||
//if the expected samples was less, we need to throttle back
|
||||
if(d_total_samples > expected_samps) {
|
||||
boost::this_thread::sleep(boost::posix_time::microseconds
|
||||
(long((d_total_samples - expected_samps)/d_samps_per_us)));
|
||||
}
|
||||
|
||||
//copy all samples output[i] <= input[i]
|
||||
const char *in = (const char *)input_items[0];
|
||||
char *out = (char *)output_items[0];
|
||||
std::memcpy(out, in, noutput_items * d_itemsize);
|
||||
d_total_samples += noutput_items;
|
||||
return noutput_items;
|
||||
}
|
||||
|
||||
void
|
||||
throttle_impl::setup_rpc()
|
||||
{
|
||||
}
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_THROTTLE_IMPL_H
|
||||
#define INCLUDED_GR_THROTTLE_IMPL_H
|
||||
|
||||
#include <gnuradio/blocks/throttle.h>
|
||||
|
||||
namespace gr {
|
||||
namespace blocks {
|
||||
|
||||
class throttle_impl : public throttle
|
||||
{
|
||||
private:
|
||||
boost::system_time d_start;
|
||||
size_t d_itemsize;
|
||||
uint64_t d_total_samples;
|
||||
double d_samps_per_tick, d_samps_per_us;
|
||||
|
||||
public:
|
||||
throttle_impl(size_t itemsize, double samples_per_sec);
|
||||
~throttle_impl();
|
||||
|
||||
void setup_rpc();
|
||||
|
||||
void set_sample_rate(double rate);
|
||||
double sample_rate() const;
|
||||
|
||||
int work(int noutput_items,
|
||||
gr_vector_const_void_star &input_items,
|
||||
gr_vector_void_star &output_items);
|
||||
};
|
||||
|
||||
} /* namespace blocks */
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* INCLUDED_GR_THROTTLE_IMPL_H */
|
|
@ -0,0 +1,269 @@
|
|||
/* -*- 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
long
|
||||
buffer_reader_ncurrently_allocated()
|
||||
{
|
||||
return s_buffer_reader_count;
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2006,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.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#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 "@GR_VERSION@";
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -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(double x)
|
||||
{
|
||||
// nop
|
||||
}
|
||||
|
||||
void
|
||||
feval_p::calleval(double 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 */
|
|
@ -0,0 +1,389 @@
|
|||
/* -*- 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> // FIXME:
|
||||
#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);
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
// We're going to let this fail once and retry. If that fails,
|
||||
// throw and exit.
|
||||
buffer_sptr b;
|
||||
try {
|
||||
b = make_buffer(nitems, item_size, grblock);
|
||||
}
|
||||
catch(std::bad_alloc&) {
|
||||
b = make_buffer(nitems, item_size, grblock);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
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 = 4; //volk_get_alignment(); // FIXME: check 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::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 */
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- 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);
|
||||
|
||||
/*!
|
||||
* 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 */
|
|
@ -0,0 +1,475 @@
|
|||
/* -*- 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_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;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,142 @@
|
|||
/* -*- 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))
|
||||
{
|
||||
// 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::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;
|
||||
}
|
||||
|
||||
void
|
||||
hier_block2::set_processor_affinity(const std::vector<int> &mask)
|
||||
{
|
||||
d_detail->set_processor_affinity(mask);
|
||||
}
|
||||
|
||||
void
|
||||
hier_block2::unset_processor_affinity()
|
||||
{
|
||||
d_detail->unset_processor_affinity();
|
||||
}
|
||||
|
||||
std::vector<int>
|
||||
hier_block2::processor_affinity()
|
||||
{
|
||||
return d_detail->processor_affinity();
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,566 @@
|
|||
/* -*- 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::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();
|
||||
edge_viter_t p;
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void
|
||||
hier_block2_detail::set_processor_affinity(const std::vector<int> &mask)
|
||||
{
|
||||
basic_block_vector_t tmp = d_fg->calc_used_blocks();
|
||||
for(basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
|
||||
(*p)->set_processor_affinity(mask);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hier_block2_detail::unset_processor_affinity()
|
||||
{
|
||||
basic_block_vector_t tmp = d_fg->calc_used_blocks();
|
||||
for(basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
|
||||
(*p)->unset_processor_affinity();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int>
|
||||
hier_block2_detail::processor_affinity()
|
||||
{
|
||||
basic_block_vector_t tmp = d_fg->calc_used_blocks();
|
||||
return tmp[0]->processor_affinity();
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -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 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;
|
||||
|
||||
void set_processor_affinity(const std::vector<int> &mask);
|
||||
void unset_processor_affinity();
|
||||
std::vector<int> processor_affinity();
|
||||
|
||||
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 */
|
|
@ -0,0 +1,8 @@
|
|||
#include <gnuradio/high_res_timer.h>
|
||||
|
||||
#ifdef GNURADIO_HRT_USE_CLOCK_GETTIME
|
||||
clockid_t gr::high_res_timer_source = CLOCK_THREAD_CPUTIME_ID;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_GR_LOCAL_SIGHANDLER_H
|
||||
#define INCLUDED_GR_LOCAL_SIGHANDLER_H
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <string>
|
||||
|
||||
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;
|
||||
#endif
|
||||
|
||||
public:
|
||||
local_sighandler(int signum, void (*new_handler)(int));
|
||||
~local_sighandler();
|
||||
|
||||
/* 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 */
|
|
@ -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::cerr << "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 */
|
|
@ -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 */
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- 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/fxpt.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
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 */
|
|
@ -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 */
|
|
@ -0,0 +1,85 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2004,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
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE // ask for GNU extensions if available
|
||||
#endif
|
||||
|
||||
#include <gnuradio/sincos.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
#if defined (HAVE_SINCOS)
|
||||
|
||||
void
|
||||
sincos(double x, double *sinx, double *cosx)
|
||||
{
|
||||
::sincos(x, sinx, cosx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
sincos(double x, double *sinx, double *cosx)
|
||||
{
|
||||
*sinx = ::sin(x);
|
||||
*cosx = ::cos(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
#if defined (HAVE_SINCOSF)
|
||||
|
||||
void
|
||||
sincosf(float x, float *sinx, float *cosx)
|
||||
{
|
||||
::sincosf(x, sinx, cosx);
|
||||
}
|
||||
|
||||
#elif defined (HAVE_SINF) && defined (HAVE_COSF)
|
||||
|
||||
void
|
||||
sincosf(float x, float *sinx, float *cosx)
|
||||
{
|
||||
*sinx = ::sinf(x);
|
||||
*cosx = ::cosf(x);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
sincosf(float x, float *sinx, float *cosx)
|
||||
{
|
||||
*sinx = ::sin(x);
|
||||
*cosx = ::cos(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} /* namespace gr */
|
File diff suppressed because it is too large
Load Diff
|
@ -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_ */
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- 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 "misc.h"
|
||||
|
||||
namespace gr {
|
||||
|
||||
unsigned int
|
||||
rounduppow2(unsigned int n)
|
||||
{
|
||||
int i;
|
||||
for(i=0;((n-1)>>i) != 0;i++)
|
||||
;
|
||||
return 1<<i;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
void
|
||||
zero_vector(std::vector<float> &v)
|
||||
{
|
||||
for(unsigned int i=0; i < v.size(); i++)
|
||||
v[i] = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
zero_vector(std::vector<gr_complex> &v)
|
||||
{
|
||||
for(unsigned int i=0; i < v.size(); i++)
|
||||
v[i] = 0;
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- 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 INCLUDED_GR_MISC_H
|
||||
#define INCLUDED_GR_MISC_H
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
#include <gnuradio/types.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
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 */
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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 "pagesize.h"
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
#if defined(_WIN32) && defined(HAVE_GETPAGESIZE)
|
||||
extern "C" size_t getpagesize(void);
|
||||
#endif
|
||||
|
||||
int
|
||||
pagesize()
|
||||
{
|
||||
static int s_pagesize = -1;
|
||||
|
||||
if(s_pagesize == -1) {
|
||||
#if defined(HAVE_GETPAGESIZE)
|
||||
s_pagesize = getpagesize();
|
||||
#elif defined (HAVE_SYSCONF)
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
return s_pagesize;
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- 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_PAGESIZE_H_
|
||||
#define GR_PAGESIZE_H_
|
||||
|
||||
#include <gnuradio/api.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
/*!
|
||||
* \brief return the page size in bytes
|
||||
*/
|
||||
GR_RUNTIME_API int pagesize();
|
||||
|
||||
} /* namespace gr */
|
||||
|
||||
#endif /* GR_PAGESIZE_H_ */
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2008,2009 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "posix_memalign.h"
|
||||
|
||||
#ifdef HAVE_MALLOC_H
|
||||
// for Cygwin valloc () prototype
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_POSIX_MEMALIGN
|
||||
|
||||
/* emulate posix_memalign functionality, to some degree */
|
||||
|
||||
#include <errno.h>
|
||||
#include "pagesize.h"
|
||||
|
||||
int posix_memalign
|
||||
(void **memptr, size_t alignment, size_t size)
|
||||
{
|
||||
/* emulate posix_memalign functionality, to some degree */
|
||||
|
||||
/* make sure the return handle is valid; return "bad address" if not valid */
|
||||
if (memptr == 0)
|
||||
return (EFAULT);
|
||||
*memptr = (void*) 0;
|
||||
|
||||
/* make sure 'alignment' is a power of 2
|
||||
* and multiple of sizeof (void*)
|
||||
*/
|
||||
|
||||
/* make sure 'alignment' is a multiple of sizeof (void*) */
|
||||
if ((alignment % sizeof (void*)) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* make sure 'alignment' is a power of 2 */
|
||||
if ((alignment & (alignment - 1)) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
/* good alignment */
|
||||
|
||||
#if (ALIGNED_MALLOC != 0)
|
||||
|
||||
/* if 'malloc' is known to be aligned, and the desired 'alignment'
|
||||
* matches is <= that provided by 'malloc', then use 'malloc'. This
|
||||
* works on, e.g., Darwin 8 & 9: for which malloc is 16-byte aligned.
|
||||
*/
|
||||
size_t am = (size_t) ALIGNED_MALLOC;
|
||||
if (alignment <= am) {
|
||||
/* make sure ALIGNED_MALLOC is a power of 2, to guarantee that the
|
||||
* alignment is correct (since 'alignment' must be a power of 2).
|
||||
*/
|
||||
if ((am & (am - 1)) != 0)
|
||||
return (EINVAL);
|
||||
/* good malloc alignment */
|
||||
*memptr = malloc (size);
|
||||
}
|
||||
|
||||
#endif /* (ALIGNED_MALLOC != 0) */
|
||||
#ifdef HAVE_VALLOC
|
||||
|
||||
if (*memptr == (void*) 0) {
|
||||
/* try valloc if it exists */
|
||||
/* cheap and easy way to make sure alignment is met, so long as it
|
||||
* is <= pagesize () */
|
||||
if (alignment <= (size_t) gr::pagesize ()) {
|
||||
*memptr = valloc (size);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_VALLOC */
|
||||
|
||||
#if (ALIGNED_MALLOC == 0) && !defined (HAVE_VALLOC)
|
||||
/* no posix_memalign, valloc, and malloc isn't known to be aligned
|
||||
* (enough for the input arguments); no idea what to do.
|
||||
*/
|
||||
|
||||
#error gnuradio-runtime/lib/posix_memalign.cc: Cannot find a way to alloc aligned memory.
|
||||
|
||||
#endif
|
||||
|
||||
/* if the pointer wasn't allocated properly, return that there was
|
||||
* not enough memory to allocate; otherwise, return OK (0).
|
||||
*/
|
||||
if (*memptr == (void*) 0)
|
||||
return (ENOMEM);
|
||||
else
|
||||
return (0);
|
||||
};
|
||||
|
||||
#endif /* ! HAVE_POSIX_MEMALIGN */
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- c++ -*- */
|
||||
/*
|
||||
* Copyright 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GNU Radio
|
||||
*
|
||||
* GNU Radio is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Radio is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Radio; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _POSIX_MEMALIGN_H_
|
||||
#define _POSIX_MEMALIGN_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef HAVE_POSIX_MEMALIGN
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int posix_memalign (void** memptr, size_t alignment, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* ! HAVE_POSIX_MEMALIGN */
|
||||
|
||||
#endif /* _POSIX_MEMALIGN_H_ */
|
|
@ -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 §ion)
|
||||
{
|
||||
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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 §ion, 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 */
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- 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 <gnuradio/realtime.h>
|
||||
|
||||
namespace gr {
|
||||
|
||||
rt_status_t
|
||||
enable_realtime_scheduling()
|
||||
{
|
||||
return gr::impl::enable_realtime_scheduling();
|
||||
}
|
||||
|
||||
} /* namespace gr */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue