diff options
116 files changed, 5365 insertions, 772 deletions
diff --git a/Makefile.am b/Makefile.am index ea99890ae..9262c5bcc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,8 @@ EXTRA_DIST = \ configure-cell-cross \ config.h.in \ run_tests.sh.in \ - README.hacking + README.hacking \ + README.building-boost SUBDIRS = @build_dirs@ DIST_SUBDIRS = @build_dirs@ @skipped_dirs@ @with_dirs@ diff --git a/Makefile.common b/Makefile.common index a4a3139c6..b24be4375 100644 --- a/Makefile.common +++ b/Makefile.common @@ -105,7 +105,7 @@ GCELL_EMBEDSPU_LIBTOOL = @abs_top_srcdir@/gcell/src/lib/runtime/gcell-embedspu-l # This used to be set in configure.ac but is now defined here for all # Makefiles when this fragment is included. -STD_DEFINES_AND_INCLUDES=$(DEFINES) $(OMNITHREAD_INCLUDES) $(GNURADIO_INCLUDES) $(BOOST_CFLAGS) +STD_DEFINES_AND_INCLUDES=$(DEFINES) $(BOOST_CPPFLAGS) $(OMNITHREAD_INCLUDES) $(GNURADIO_INCLUDES) # Fix for BSD make not defining $(RM). We define it now in configure.ac # using AM_PATH_PROG, but now here have to add a -f to be like GNU make @@ -185,12 +185,12 @@ Provides a high performance array type for Python. http://numpy.scipy.org http://sourceforge.net/project/showfiles.php?group_id=1369&package_id=175103 -(6) The Boost C++ Libraries http://www.boost.org -We use the Smart Pointer library. Most systems already have the boost -libraries available. In the unlikely event that yours doesn't, -download the source and follow the build instructions. They're -different from the normal ./configure && make +(6) The Boost C++ Libraries (1.35 or later) http://www.boost.org + +We use Smart Pointers, the thread library and a bunch of other boost stuff. +If your system doesn't have boost 1.35 or later, see README.building-boost +for additional info. (7) cppunit 1.9.14 or later. http://cppunit.sourceforge.net diff --git a/README.building-boost b/README.building-boost new file mode 100644 index 000000000..0e7059de3 --- /dev/null +++ b/README.building-boost @@ -0,0 +1,35 @@ +Until boost 1.35 (or later) ships with the distributions, you'll need +to download and build it yourself. It's not hard, and it can +peacefully coexist with earlier versions of boost. + +Download the latest version of boost from boost.sourceforge.net. +(boost_1_36_0.tar.bz2 was the latest when this was written) + +unpack it somewhere +cd into the resulting directory + +$ cd boost_1_36_0 + +# Pick a prefix to install it into. I used /opt/boost_1_36_0 + +$ BOOST_PREFIX=/opt/boost_1_36_0 + +$ ./configure --prefix=$BOOST_PREFIX --with-libraries=thread,date_time +$ make +$ make install + +# Done! That was easy! + +---------------------------------------------------------------- + +Now, tell gnuradio where to find it: + +$ export LD_LIBRARY_PATH=$BOOST_PREFIX/lib + +$ cd <path-to-top-of-gnuradio-tree> +$ ./bootstrap +$ ./configure --with-boost=$BOOST_PREFIX # plus whatever config args you usually use + +$ make && make check +$ sudo make install + diff --git a/config/Makefile.am b/config/Makefile.am index 310568bfb..cc58d96c1 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2006 Free Software Foundation, Inc. +# Copyright 2001,2006,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -27,9 +27,22 @@ m4datadir = $(datadir)/aclocal # List your m4 macros here m4macros = \ acx_pthread.m4 \ + ax_boost_base.m4 \ + ax_boost_date_time.m4 \ + ax_boost_filesystem.m4 \ + ax_boost_iostreams.m4 \ + ax_boost_program_options.m4 \ + ax_boost_python.m4 \ + ax_boost_regex.m4 \ + ax_boost_serialization.m4 \ + ax_boost_signals.m4 \ + ax_boost_system.m4 \ + ax_boost_test_exec_monitor.m4 \ + ax_boost_thread.m4 \ + ax_boost_unit_test_framework.m4 \ + ax_boost_wserialization.m4 \ bnv_have_qt.m4 \ cppunit.m4 \ - gr_boost.m4 \ grc_build.m4 \ grc_gcell.m4 \ grc_gnuradio_core.m4 \ @@ -64,6 +77,7 @@ m4macros = \ gr_doxygen.m4 \ gr_fortran.m4 \ gr_gprof.m4 \ + gr_lib64.m4 \ gr_libgnuradio_core_extra_ldflags.m4 \ gr_no_undefined.m4 \ gr_omnithread.m4 \ @@ -75,7 +89,6 @@ m4macros = \ gr_subversion.m4 \ gr_swig.m4 \ gr_sysv_shm.m4 \ - gr_x86_64.m4 \ lf_cc.m4 \ lf_cxx.m4 \ lf_warnings.m4 \ diff --git a/config/acx_pthread.m4 b/config/acx_pthread.m4 index d318ab01d..eb09f5acc 100644 --- a/config/acx_pthread.m4 +++ b/config/acx_pthread.m4 @@ -1,6 +1,84 @@ -dnl Available from the GNU Autoconf Macro Archive at: -dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html -dnl +# =========================================================================== +# http://autoconf-archive.cryp.to/acx_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also link it with them as well. e.g. you should link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threads programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> +# +# This program 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 of the License, or (at your +# option) any later version. +# +# This program 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, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + AC_DEFUN([ACX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_SAVE @@ -37,9 +115,10 @@ fi # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all. +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. -acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt" +acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -56,21 +135,23 @@ acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -m # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) +# ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) case "${host_cpu}-${host_os}" in *solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthread or + # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: - acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" + acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" ;; esac @@ -87,6 +168,13 @@ for flag in $acx_pthread_flags; do PTHREAD_CFLAGS="$flag" ;; + pthread-config) + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) + if test x"$acx_pthread_config" = xno; then continue; fi + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" @@ -133,43 +221,40 @@ if test "x$acx_pthread_ok" = xyes; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - # Detect AIX lossage: threads are created detached by default - # and the JOINABLE attribute has a nonstandard name (UNDETACHED). - AC_MSG_CHECKING([for joinable pthread attribute]) - AC_TRY_LINK([#include <pthread.h>], - [int attr=PTHREAD_CREATE_JOINABLE;], - ok=PTHREAD_CREATE_JOINABLE, ok=unknown) - if test x"$ok" = xunknown; then - AC_TRY_LINK([#include <pthread.h>], - [int attr=PTHREAD_CREATE_UNDETACHED;], - ok=PTHREAD_CREATE_UNDETACHED, ok=unknown) - fi - if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then - AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok, - [Define to the necessary symbol if this constant - uses a non-standard name on your system.]) - fi - AC_MSG_RESULT(${ok}) - if test x"$ok" = xunknown; then - AC_MSG_WARN([we do not know how to create joinable pthreads]) + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_MSG_CHECKING([for joinable pthread attribute]) + attr_name=unknown + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;], + [attr_name=$attr; break]) + done + AC_MSG_RESULT($attr_name) + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case "${host_cpu}-${host_os}" in - *-aix* | *-freebsd*) flag="-D_THREAD_SAFE";; - *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; esac AC_MSG_RESULT(${flag}) if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" - # More AIX lossage: must compile with cc_r - AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) + # More AIX lossage: must compile with xlc_r or cc_r + if test x"$GCC" != xyes; then + AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) + else + PTHREAD_CC=$CC + fi else PTHREAD_CC="$CC" fi diff --git a/config/ax_boost_base.m4 b/config/ax_boost_base.m4 new file mode 100644 index 000000000..e9790227e --- /dev/null +++ b/config/ax_boost_base.m4 @@ -0,0 +1,334 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ax_boost_base.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_BASE([MINIMUM-VERSION]) +# +# DESCRIPTION +# +# Test for the Boost C++ libraries of a particular version (or newer) +# +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt and /opt/local and evaluates the +# $BOOST_ROOT environment variable. Further documentation is available at +# <http://randspringer.de/boost/index.html>. +# +# This macro calls: +# +# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS) +# +# And sets: +# +# HAVE_BOOST +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_BASE], +[ +AC_REQUIRE([GR_LIB64]) +AC_ARG_WITH([boost], + AS_HELP_STRING([--with-boost@<:@=DIR@:>@], + [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ac_boost_path="" + else + want_boost="yes" + ac_boost_path="$withval" + fi + ], + [want_boost="yes"]) + + +AC_ARG_WITH([boost-libdir], + AS_HELP_STRING([--with-boost-libdir=LIB_DIR], + [Force given directory for boost libraries. Note that this + will overwrite library path detection, so use this parameter + only if default library detection fails and you know exactly + where your boost libraries are located.]), + [ + if test -d $withval + then + ac_boost_lib_path="$withval" + else + AC_MSG_ERROR(--with-boost-libdir expected directory name) + fi + ], + [ac_boost_lib_path=""] +) + +if test "x$want_boost" = "xyes"; then + boost_lib_version_req=ifelse([$1], ,1.20.0,$1) + boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'` + boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'` + boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'` + boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'` + if test "x$boost_lib_version_req_sub_minor" = "x" ; then + boost_lib_version_req_sub_minor="0" + fi + WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor` + AC_MSG_CHECKING(for boost >= $boost_lib_version_req) + succeeded=no + + dnl first we check the system location for boost libraries + dnl this location ist chosen if boost libraries are installed with the --layout=system option + dnl or if you install boost with RPM + if test "$ac_boost_path" != ""; then + dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib. + dnl If that directory doesn't exist, fall back to the default behavior + if test -d "$ac_boost_path/lib${gr_libdir_suffix}"; then + BOOST_LDFLAGS="-L$ac_boost_path/lib${gr_libdir_suffix}" + else + BOOST_LDFLAGS="-L$ac_boost_path/lib" + fi + BOOST_CPPFLAGS="-I$ac_boost_path/include" + else + for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do + if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then + dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib. + dnl If that directory doesn't exist, fall back to the default behavior + if test -d "$ac_boost_path_tmp/lib${gr_libdir_suffix}"; then + BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib${gr_libdir_suffix}" + else + BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib" + fi + BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + break; + fi + done + fi + + dnl overwrite ld flags if we have required special directory with + dnl --with-boost-libdir parameter + if test "$ac_boost_lib_path" != ""; then + BOOST_LDFLAGS="-L$ac_boost_lib_path" + fi + + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include <boost/version.hpp> + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ], + []) + AC_LANG_POP([C++]) + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + + + dnl if we found no boost with system layout we search for boost libraries + dnl built and installed without the --layout=system option + if test "$succeeded" != "yes"; then + _version=0 + + if test "$ac_boost_path" != ""; then + path_list="$ac_boost_path" + else + path_list="/usr /usr/local /opt /opt/local" + fi + for ac_boost_path in $path_list ; do + if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then + for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do + _version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's,/include/boost-,,; s,_,.,'` + V_CHECK=`expr $_version_tmp \> $_version` + if test "$V_CHECK" = "1" ; then + _version=$_version_tmp + best_path=$ac_boost_path + fi + done + fi + done + + VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'` + BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE" + + if test "$ac_boost_lib_path" = ""; then + dnl Look first where we think they ought to be, accounting for a possible "64" suffix on lib. + dnl If that directory doesn't exist, fall back to the default behavior + if test -d "$best_path/lib${gr_libdir_suffix}"; then + BOOST_LDFLAGS="-L$best_path/lib${gr_libdir_suffix}" + else + BOOST_LDFLAGS="-L$best_path/lib" + fi + fi + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS + + AC_LANG_PUSH(C++) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + @%:@include <boost/version.hpp> + ]], [[ + #if BOOST_VERSION >= $WANT_BOOST_VERSION + // Everything is okay + #else + # error Boost version is too old + #endif + ]])],[AC_MSG_RESULT(yes) + succeeded=yes + found_system=yes + ], + []) + AC_LANG_POP([C++]) + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi + + if test "$succeeded" != "yes" ; then + AC_MSG_RESULT([no]) + if test "$_version" = "0" ; then + AC_MSG_ERROR([[we could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). +If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>.]]) + else + AC_MSG_ERROR([your boost libraries seem to old (version $_version).]) + fi + else + AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_LDFLAGS) + AC_DEFINE(HAVE_BOOST,1,[Define if the Boost headers are available]) + fi +fi +]) + +dnl +dnl Macros used by the boost items that need libraries. +dnl + +dnl $1 is unit name. E.g., boost_thread +AC_DEFUN([_AX_BOOST_CHECK_LIB],[ + _AX_BOOST_CHECK_LIB_($1,HAVE_[]m4_toupper($1),m4_toupper($1)_LIB) +]) + +dnl $1 is unit name. E.g., boost_thread +dnl $2 is AC_DEFINE name. E.g., HAVE_BOOST_THREAD +dnl $3 is lib var name. E.g., BOOST_THREAD_LIB +AC_DEFUN([_AX_BOOST_CHECK_LIB_],[ + AC_LANG_PUSH([C++]) + AC_DEFINE($2,1,[Define if the $1 library is available]) + BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` + + dnl See if we can find a usable library + link_ok="no" + if test "$ax_boost_user_lib" != ""; then + dnl use what the user supplied + for ax_lib in $ax_boost_user_lib $1-${ax_boost_user_lib}; do + AC_CHECK_LIB($ax_lib, exit, + [$3="-l$ax_lib"; AC_SUBST($3) link_ok="yes"; break]) + done + else + dnl Look in BOOSTLIBDIR for possible candidates + head=$BOOSTLIBDIR/lib[]$1 + for f in ${head}*.so* ${head}*.a* ${head}*.dll* ${head}*.dylib; do + dnl echo 1: $f + case $f in + *\**) continue;; + esac + f=`echo $f | sed -e 's,.*/,,' -e 's,^lib,,'` + dnl echo 2: $f + f=`echo $f | sed -e 's,\($1.*\)\.so.*$,\1,' -e 's,\($1.*\)\.a.*$,\1,' -e 's,\($1.*\)\.dll.*$,\1,' -e 's,\($1.*\)\.dylib.*$,\1,'` + dnl echo 3: $f + + ax_lib=$f + AC_CHECK_LIB($ax_lib, exit, + [$3="-l$ax_lib"; AC_SUBST($3) link_ok="yes"; break]) + done + fi + + if test "$link_ok" != "yes"; then + AC_MSG_ERROR([Could not link against lib[$1]!]) + fi + AC_LANG_POP([C++]) +]) + + +dnl $1 is unit name. E.g., boost_thread +AC_DEFUN([_AX_BOOST_WITH],[ + _AX_BOOST_WITH_($1,m4_bpatsubst($1,_,-)) +]) + +dnl $1 is unit name. E.g., boost_thread +dnl $2 is hyphenated unit name. E.g., boost-thread +AC_DEFUN([_AX_BOOST_WITH_],[ + AC_ARG_WITH([$2], + AC_HELP_STRING([--with-$2@<:@=special-lib@:>@], + [Use the m4_substr($1,6) library from boost. It is possible to specify a certain + library to the linker. E.g., --with-$2=$1-gcc41-mt-1_35]), + [ + if test "$withval" = "no"; then + want_boost="no" + elif test "$withval" = "yes"; then + want_boost="yes" + ax_boost_user_lib="" + else + want_boost="yes" + ax_boost_user_lib="$withval" + fi + ], + [want_boost="yes"]) +]) + +dnl $1 is unit name. E.g., boost_thread +dnl $2 is AC_LANG_PROGRAM argument 1 +dnl $3 is AC_LANG_PROGRAM argument 2 +dnl $4 is cv variable name. E.g., ax_cv_boost_thread +AC_DEFUN([_AX_BOOST_CHECK_],[ + _AX_BOOST_WITH($1) + if test "$want_boost" = "yes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_PROG_CXX]) + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + AC_CACHE_CHECK([whether the boost::m4_substr([$1],6) includes are available], [$4], + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([$2],[$3]),[$4]=yes,[$4]=no) + AC_LANG_POP([C++]) + ]) + if test "$[$4]" = "yes"; then + _AX_BOOST_CHECK_LIB([$1]) + fi + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi +]) + +dnl $1 is unit name. E.g., boost_thread +dnl $2 is AC_LANG_PROGRAM argument 1 +dnl $3 is AC_LANG_PROGRAM argument 2 +AC_DEFUN([_AX_BOOST_CHECK],[ + _AX_BOOST_CHECK_($1,$2,$3,ax_cv_$1) +]) diff --git a/config/ax_boost_date_time.m4 b/config/ax_boost_date_time.m4 new file mode 100644 index 000000000..7b3f0fe3d --- /dev/null +++ b/config/ax_boost_date_time.m4 @@ -0,0 +1,34 @@ +# +# SYNOPSIS +# +# AX_BOOST_DATE_TIME +# +# DESCRIPTION +# +# Test for date_time library from the Boost C++ libraries. +# +# This macro calls: +# +# AC_SUBST(BOOST_DATE_TIME_LIB) +# +# And sets: +# +# HAVE_BOOST_DATE_TIME +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_DATE_TIME], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_date_time], + [@%:@include <boost/date_time/gregorian/gregorian_types.hpp>], + [using namespace boost::gregorian; date d(2002,Jan,10); return 0;]) +]) diff --git a/config/ax_boost_filesystem.m4 b/config/ax_boost_filesystem.m4 new file mode 100644 index 000000000..bcb3fa44f --- /dev/null +++ b/config/ax_boost_filesystem.m4 @@ -0,0 +1,45 @@ +# +# SYNOPSIS +# +# AX_BOOST_FILESYSTEM +# +# DESCRIPTION +# +# Test for Filesystem library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_FILESYSTEM_LIB) +# +# And sets: +# +# HAVE_BOOST_FILESYSTEM +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_FILESYSTEM], +[ + AC_REQUIRE([AX_BOOST_BASE]) + + dnl depends on boost_system + AC_REQUIRE([AX_BOOST_SYSTEM]) + axbf_LDFLAGS_SAVED=$LDFLAGS + LDFLAGS="$LDFLAGS $BOOST_SYSTEM_LIB" + + _AX_BOOST_CHECK([boost_filesystem], + [@%:@include <boost/filesystem/path.hpp>], + [using namespace boost::filesystem; + path my_path( "foo/bar/data.txt" ); + return 0;]) + + LDFLAGS=$axbf_LDFLAGS_SAVED +]) diff --git a/config/ax_boost_iostreams.m4 b/config/ax_boost_iostreams.m4 new file mode 100644 index 000000000..181b1e752 --- /dev/null +++ b/config/ax_boost_iostreams.m4 @@ -0,0 +1,39 @@ +# +# SYNOPSIS +# +# AX_BOOST_IOSTREAMS +# +# DESCRIPTION +# +# Test for IOStreams library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_IOSTREAMS_LIB) +# +# And sets: +# +# HAVE_BOOST_IOSTREAMS +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_IOSTREAMS], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_iostreams], + [@%:@include <boost/iostreams/filtering_stream.hpp> + @%:@include <boost/range/iterator_range.hpp>], + [std::string input = "Hello World!"; + namespace io = boost::iostreams; + io::filtering_istream in(boost::make_iterator_range(input)); + return 0;]) + +]) diff --git a/config/ax_boost_program_options.m4 b/config/ax_boost_program_options.m4 new file mode 100644 index 000000000..3829373be --- /dev/null +++ b/config/ax_boost_program_options.m4 @@ -0,0 +1,35 @@ +# +# SYNOPSIS +# +# AX_BOOST_PROGRAM_OPTIONS +# +# DESCRIPTION +# +# Test for program options library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_PROGRAM_OPTIONS_LIB) +# +# And sets: +# +# HAVE_BOOST_PROGRAM_OPTIONS +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_program_options], + [@%:@include <boost/program_options.hpp>], + [boost::program_options::options_description generic("Generic options"); + return 0;]) +]) diff --git a/config/ax_boost_python.m4 b/config/ax_boost_python.m4 new file mode 100644 index 000000000..3c6c666f7 --- /dev/null +++ b/config/ax_boost_python.m4 @@ -0,0 +1,92 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ax_boost_python.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_PYTHON +# +# DESCRIPTION +# +# This macro checks to see if the Boost.Python library is installed. It +# also attempts to guess the currect library name using several attempts. +# It tries to build the library name using a user supplied name or suffix +# and then just the raw library. +# +# If the library is found, HAVE_BOOST_PYTHON is defined and +# BOOST_PYTHON_LIB is set to the name of the library. +# +# This macro calls AC_SUBST(BOOST_PYTHON_LIB). +# +# In order to ensure that the Python headers are specified on the include +# path, this macro requires AX_PYTHON to be called. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Michael Tindal +# +# This program 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 2 of the License, or (at your +# option) any later version. +# +# This program 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, see <http://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AX_BOOST_PYTHON], +[AC_REQUIRE([AX_PYTHON])dnl +AC_CACHE_CHECK(whether the Boost::Python library is available, +ac_cv_boost_python, +[AC_LANG_SAVE + AC_LANG_CPLUSPLUS + CPPFLAGS_SAVE=$CPPFLAGS + if test x$PYTHON_INCLUDE_DIR != x; then + CPPFLAGS=-I$PYTHON_INCLUDE_DIR $CPPFLAGS + fi + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[ + #include <boost/python/module.hpp> + using namespace boost::python; + BOOST_PYTHON_MODULE(test) { throw "Boost::Python test."; }]], + [[return 0;]]), + ac_cv_boost_python=yes, ac_cv_boost_python=no) + AC_LANG_RESTORE + CPPFLAGS=$CPPFLAGS_SAVE +]) +if test "$ac_cv_boost_python" = "yes"; then + AC_LANG_PUSH([C++]) + AC_DEFINE(HAVE_BOOST_PYTHON,,[define if the Boost::Python library is available]) + ax_python_lib=boost_python + AC_ARG_WITH([boost-python],AS_HELP_STRING([--with-boost-python],[specify the boost python library or suffix to use]), + [if test "x$with_boost_python" != "xno"; then + ax_python_lib=$with_boost_python + ax_boost_python_lib=boost_python-$with_boost_python + fi]) + for ax_lib in $ax_python_lib $ax_boost_python_lib boost_python; do + AC_CHECK_LIB($ax_lib, exit, [BOOST_PYTHON_LIB=$ax_lib break]) + done + AC_SUBST(BOOST_PYTHON_LIB) + AC_LANG_POP([C++]) +fi +])dnl diff --git a/config/ax_boost_regex.m4 b/config/ax_boost_regex.m4 new file mode 100644 index 000000000..32b531369 --- /dev/null +++ b/config/ax_boost_regex.m4 @@ -0,0 +1,35 @@ +# +# SYNOPSIS +# +# AX_BOOST_REGEX +# +# DESCRIPTION +# +# Test for Regex library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_REGEX_LIB) +# +# And sets: +# +# HAVE_BOOST_REGEX +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_REGEX], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_regex], + [@%:@include <boost/regex.hpp>], + [boost::regex r(); return 0;]) +]) diff --git a/config/ax_boost_serialization.m4 b/config/ax_boost_serialization.m4 new file mode 100644 index 000000000..78c950078 --- /dev/null +++ b/config/ax_boost_serialization.m4 @@ -0,0 +1,38 @@ +# +# SYNOPSIS +# +# AX_BOOST_SERIALIZATION +# +# DESCRIPTION +# +# Test for Serialization library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_SERIALIZATION_LIB) +# +# And sets: +# +# HAVE_BOOST_SERIALIZATION +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_SERIALIZATION], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_serialization], + [@%:@include <fstream> + @%:@include <boost/archive/text_oarchive.hpp> + @%:@include <boost/archive/text_iarchive.hpp>], + [std::ofstream ofs("filename"); + boost::archive::text_oarchive oa(ofs); + return 0;]) +]) diff --git a/config/ax_boost_signals.m4 b/config/ax_boost_signals.m4 new file mode 100644 index 000000000..3c4971748 --- /dev/null +++ b/config/ax_boost_signals.m4 @@ -0,0 +1,35 @@ +# +# SYNOPSIS +# +# AX_BOOST_SIGNALS +# +# DESCRIPTION +# +# Test for Signals library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_SIGNALS_LIB) +# +# And sets: +# +# HAVE_BOOST_SIGNALS +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_SIGNALS], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_signals], + [@%:@include <boost/signal.hpp>], + [boost::signal<void ()> sig; return 0;]) +]) diff --git a/config/ax_boost_system.m4 b/config/ax_boost_system.m4 new file mode 100644 index 000000000..cb73f2577 --- /dev/null +++ b/config/ax_boost_system.m4 @@ -0,0 +1,40 @@ +# =========================================================================== +# started with this: http://autoconf-archive.cryp.to/ax_boost_system.html, +# virtually nothing left +# =========================================================================== +# +# SYNOPSIS +# +# AX_BOOST_SYSTEM +# +# DESCRIPTION +# +# Test for System library from the Boost C++ libraries. The macro requires +# a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_SYSTEM_LIB) +# +# And sets: +# +# HAVE_BOOST_SYSTEM +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Daniel Casimiro <dan.casimiro@gmail.com> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_SYSTEM], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_system], + [@%:@include <boost/system/error_code.hpp>], + [boost::system::system_category]) +]) diff --git a/config/ax_boost_test_exec_monitor.m4 b/config/ax_boost_test_exec_monitor.m4 new file mode 100644 index 000000000..2c30c0b4a --- /dev/null +++ b/config/ax_boost_test_exec_monitor.m4 @@ -0,0 +1,35 @@ +# +# SYNOPSIS +# +# AX_BOOST_TEST_EXEC_MONITOR +# +# DESCRIPTION +# +# Test for Test_Exec_Monitor library from the Boost C++ libraries. The +# macro requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_TEST_EXEC_MONITOR_LIB) +# +# And sets: +# +# HAVE_BOOST_TEST_EXEC_MONITOR +# +# COPYLEFT +# +# Copyright (c) 2008 Dodji Seketeli <dodji@seketeli.org> +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_TEST_EXEC_MONITOR], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_test_exec_monitor], + [@%:@include <boost/test/test_tools.hpp>], + [int i=1 ; BOOST_REQUIRE(i==1); ; return 0;]) +]) diff --git a/config/ax_boost_thread.m4 b/config/ax_boost_thread.m4 new file mode 100644 index 000000000..4df23224a --- /dev/null +++ b/config/ax_boost_thread.m4 @@ -0,0 +1,72 @@ +# +# SYNOPSIS +# +# AX_BOOST_THREAD +# +# DESCRIPTION +# +# Test for Thread library from the Boost C++ libraries. +# +# This macro calls: +# +# AC_SUBST(BOOST_THREAD_LIB) +# AC_SUBST(BOOST_CXXFLAGS) +# +# And sets: +# +# HAVE_BOOST_THREAD +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Michael Tindal +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + + +AC_DEFUN([AX_BOOST_THREAD], +[ + AC_REQUIRE([AX_BOOST_BASE]) + AC_REQUIRE([ACX_PTHREAD]) + _AX_BOOST_WITH([boost_thread]) + + if test "$want_boost" = "yes"; then + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([AC_CANONICAL_HOST]) + + CPPFLAGS_SAVED="$CPPFLAGS" + LDFLAGS_SAVED="$LDFLAGS" + CXXFLAGS_SAVED="$CXXFLAGS" + + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS $PTHREAD_LIBS" + CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" + + AC_CACHE_CHECK(whether the boost::thread includes are available, + ax_cv_boost_thread, + [AC_LANG_PUSH([C++]) + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[@%:@include <boost/thread/thread.hpp>]], + [[boost::thread_group thrds; + return 0;]]), + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + AC_LANG_POP([C++]) + ]) + + if test "$ax_cv_boost_thread" = "yes"; then + BOOST_CXXFLAGS="$PTHREAD_CFLAGS" + AC_SUBST(BOOST_CXXFLAGS) + _AX_BOOST_CHECK_LIB([boost_thread]) + if test "$link_ok" = "yes" && test -n "$PTHREAD_LIBS"; then + BOOST_THREAD_LIB="$BOOST_THREAD_LIB $PTHREAD_LIBS" + fi + fi + + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + CXXFLAGS="$CXXFLAGS_SAVED" + fi +]) diff --git a/config/ax_boost_unit_test_framework.m4 b/config/ax_boost_unit_test_framework.m4 new file mode 100644 index 000000000..73affccfd --- /dev/null +++ b/config/ax_boost_unit_test_framework.m4 @@ -0,0 +1,36 @@ +# +# SYNOPSIS +# +# AX_BOOST_UNIT_TEST_FRAMEWORK +# +# DESCRIPTION +# +# Test for Unit_Test_Framework library from the Boost C++ libraries. The +# macro requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) +# +# And sets: +# +# HAVE_BOOST_UNIT_TEST_FRAMEWORK +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], +[ + AC_REQUIRE([AX_BOOST_BASE]) + _AX_BOOST_CHECK([boost_unit_test_framework], + [@%:@include <boost/test/unit_test.hpp>], + [using boost::unit_test::test_suite; + test_suite* test= BOOST_TEST_SUITE( "Unit test example 1" ); + return 0;]) +]) diff --git a/config/ax_boost_wserialization.m4 b/config/ax_boost_wserialization.m4 new file mode 100644 index 000000000..f384988cb --- /dev/null +++ b/config/ax_boost_wserialization.m4 @@ -0,0 +1,46 @@ +# +# SYNOPSIS +# +# AX_BOOST_WSERIALIZATION +# +# DESCRIPTION +# +# Test for WSerialization library from the Boost C++ libraries. The macro +# requires a preceding call to AX_BOOST_BASE. +# +# This macro calls: +# +# AC_SUBST(BOOST_WSERIALIZATION_LIB) +# +# And sets: +# +# HAVE_BOOST_WSERIALIZATION +# +# COPYLEFT +# +# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de> +# Copyright (c) 2008 Free Software Foundation, Inc. +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +AC_DEFUN([AX_BOOST_WSERIALIZATION], +[ + AC_REQUIRE([AX_BOOST_BASE]) + + dnl depends on BOOST_SERIALIZATION + AC_REQUIRE([AX_BOOST_SERIALIZATION]) + axbws_LDFLAGS_SAVED=$LDFLAGS + LDFLAGS="$LDFLAGS $BOOST_SERIALIZATION_LIB" + + _AX_BOOST_CHECK([boost_wserialization], + [@%:@include <fstream> + @%:@include <boost/archive/text_oarchive.hpp> + @%:@include <boost/archive/text_iarchive.hpp>], + [std::ofstream ofs("filename"); + boost::archive::text_oarchive oa(ofs); + return 0;]) + + LDFLAGS=$axbf_LDFLAGS_SAVED +]) diff --git a/config/gr_boost.m4 b/config/gr_boost.m4 deleted file mode 100644 index 0664d36fb..000000000 --- a/config/gr_boost.m4 +++ /dev/null @@ -1,111 +0,0 @@ -dnl -dnl Copyright 2004,2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -dnl This tries to do the "right thing" to locate the boost include files. -dnl If the user explicitly specified --with-boost-include-dir=<foo> -dnl we believe them and use it. Otherwise, -dnl -dnl We look for boost/shared_ptr.hpp in the "normal places". That is, -dnl wherever AC_CHECK_HEADER looks. If the boost includes are in /usr/local/include -dnl this step will find them. -dnl -dnl Otherwise, we check to see if the boost stuff was installed in a version-specific -dnl directory under /usr/local/include. These look like: /usr/local/include/boost-1_33_1 -dnl If there's more than one version installed, we select the -dnl lexicographically greatest one. -dnl -dnl If none of these work, we bail. - -AC_DEFUN([GR_REQUIRE_BOOST_INCLUDES], -[ - AC_LANG_PUSH(C++) - gr_boost_include_dir= - AC_ARG_WITH([boost-include-dir], - AC_HELP_STRING([--with-boost-include-dir=<path>], - [path to boost c++ include files]), - [ - # "yes" and "no" are bogus answers - if test x"$with_boost_include_dir" = xyes || - test x"$with_boost_include_dir" = xno; then - gr_boost_include_dir= - else - gr_boost_include_dir=$with_boost_include_dir - fi - ]) - echo "gr_boost_include_dir = $gr_boost_include_dir" - if test x$gr_boost_include_dir != x; then - # - # If the user specified a directory, then we use it - # - OLD_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$gr_boost_include_dir" - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS="-I$gr_boost_include_dir"], - [AC_MSG_ERROR( - [Failed to locate boost/shared_ptr.hpp. -Try using --with-boost-include-dir=<path>, -E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) - CPPFLAGS=$OLD_CPPFLAGS - else - # - # Otherwise we check in the default places - # - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS=""], - [ # Nope, look for latest version if any in $prefix/include/boost-* - - # Wipe out cached value. KLUDGE: AC should have API for this - unset AS_TR_SH([ac_cv_header_boost/shared_ptr.hpp]) - - boost_last_match(){ - #echo "boost_last_match: [$]*" - pattern="[$]1" - shift - if test "[$]pattern" = "[$]1" - then - LM='' - else - shift `expr [$]# - 1` - LM=[$]1 - fi - #echo "LM(1)='[$]LM'" - } - - pattern="/usr/local/include/boost-*" - boost_last_match "$pattern" $pattern - #echo "LM(2)='$LM'" - - OLD_CPPFLAGS=$CPP_FLAGS - CPPFLAGS="$CPPFLAGS -I$LM" - AC_CHECK_HEADER([boost/shared_ptr.hpp], - [BOOST_CFLAGS="-I$LM"], - [AC_MSG_ERROR( - [Failed to locate boost/shared_ptr.hpp. -Try using --with-boost-include-dir=<path>, -E.g., --with-boost-include-dir=/usr/local/include/boost-1_33_1])]) - CPPFLAGS=$OLD_CPPFLAGS - ]) - - fi - unset boost_last_match LM - AC_LANG_POP - AC_SUBST(BOOST_CFLAGS) -]) diff --git a/config/gr_lib64.m4 b/config/gr_lib64.m4 new file mode 100644 index 000000000..f34779a49 --- /dev/null +++ b/config/gr_lib64.m4 @@ -0,0 +1,57 @@ +dnl +dnl Copyright 2005,2008 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. +dnl + +# GR_LIB64() +# +# Checks to see if we're on a x86_64 or powerpc64 machine, and if so, detemine +# if libdir should end in "64" or not. +# +# May append "64" to libdir. +# Sets gr_libdir_suffix to "" or "64" +# +AC_DEFUN([GR_LIB64],[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_PROG_CXX]) + + # If we're using g++, extract the first SEARCH_DIR("...") entry from the linker script + # and see if it contains a suffix after the final .../lib part of the path. + # (This works because the linker script varies depending on whether we're generating + # 32-bit or 64-bit executables) + + AC_MSG_CHECKING([libdir suffix]) + if test "$ac_cv_cxx_compiler_gnu" = "yes"; + then + gr_libdir_suffix=`$CXX -Wl,--verbose 2>/dev/null | sed -n -e '/SEARCH_DIR/{s/;.*$//; s,^.*/,,; s/".*$//; s/^lib//; p}'` + fi + AC_MSG_RESULT([$gr_libdir_suffix]) + AC_SUBST(gr_libdir_suffix) + + if test "$host_cpu" = "x86_64" || test "$host_cpu" = "powerpc64" ; then + AC_MSG_CHECKING([libdir for lib64 suffix]) + t=${libdir##*/lib} + if test "$t" != 64 && test "$gr_libdir_suffix" = "64"; then + libdir=${libdir}64 + AC_MSG_RESULT([no. Setting libdir to $libdir]) + else + AC_MSG_RESULT([yes]) + fi + fi +]) diff --git a/config/gr_set_md_cpu.m4 b/config/gr_set_md_cpu.m4 index 1ef75a536..b9c570ede 100644 --- a/config/gr_set_md_cpu.m4 +++ b/config/gr_set_md_cpu.m4 @@ -1,5 +1,5 @@ dnl -dnl Copyright 2003 Free Software Foundation, Inc. +dnl Copyright 2003,2008 Free Software Foundation, Inc. dnl dnl This file is part of GNU Radio dnl @@ -28,10 +28,10 @@ AC_DEFUN([GR_SET_MD_CPU],[ AC_MSG_CHECKING([for machine dependent speedups]) case "$cf_with_md_cpu" in - x86 | i[[3-7]]86) MD_CPU=x86 MD_SUBCPU=x86 ;; - x86_64) MD_CPU=x86 MD_SUBCPU=x86_64 ;; -# sparc) MD_CPU=sparc ;; - *) MD_CPU=generic ;; + x86 | i[[3-7]]86) MD_CPU=x86 MD_SUBCPU=x86 ;; + x86_64) MD_CPU=x86 MD_SUBCPU=x86_64 ;; + powerpc*) MD_CPU=powerpc ;; + *) MD_CPU=generic ;; esac AC_MSG_RESULT($MD_CPU) AC_SUBST(MD_CPU) @@ -39,5 +39,6 @@ AC_DEFUN([GR_SET_MD_CPU],[ AM_CONDITIONAL(MD_CPU_x86, test "$MD_CPU" = "x86") AM_CONDITIONAL(MD_SUBCPU_x86_64, test "$MD_SUBCPU" = "x86_64") + AM_CONDITIONAL(MD_CPU_powerpc, test "$MD_CPU" = "powerpc") AM_CONDITIONAL(MD_CPU_generic, test "$MD_CPU" = "generic") ]) diff --git a/config/gr_x86_64.m4 b/config/gr_x86_64.m4 deleted file mode 100644 index 3f56c061e..000000000 --- a/config/gr_x86_64.m4 +++ /dev/null @@ -1,39 +0,0 @@ -dnl -dnl Copyright 2005 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. -dnl - -# GR_X86_64() -# -# Checks to see if we're on a x86_64 machine, and if so, ensure -# that libdir ends in "64" -# -AC_DEFUN([GR_X86_64],[ - AC_REQUIRE([AC_CANONICAL_HOST]) - if test "$host_cpu" = "x86_64"; then - AC_MSG_CHECKING([libdir for lib64 suffix]) - t=${libdir##*/lib} - if test "$t" != 64 && test -d /lib64 && ! test -L /lib64; then - libdir=${libdir}64 - AC_MSG_RESULT([no. Setting libdir to $libdir]) - else - AC_MSG_RESULT([yes]) - fi - fi -]) diff --git a/config/grc_gnuradio_core.m4 b/config/grc_gnuradio_core.m4 index 24432a28f..562641ebe 100644 --- a/config/grc_gnuradio_core.m4 +++ b/config/grc_gnuradio_core.m4 @@ -28,7 +28,8 @@ AC_DEFUN([GRC_GNURADIO_CORE],[ gnuradio_core_PYDIRPATH=$pythondir ]) - dnl Don't do gnuradio-core if omnithread skipped + dnl Don't do gnuradio-core if gruel or omnithread skipped + GRC_CHECK_DEPENDENCY(gnuradio-core, gruel) GRC_CHECK_DEPENDENCY(gnuradio-core, omnithread) dnl If execution gets to here, $passed will be: diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4 index 919acee4c..451316071 100644 --- a/config/grc_gnuradio_examples.m4 +++ b/config/grc_gnuradio_examples.m4 @@ -34,6 +34,7 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/python/dect/Makefile \ gnuradio-examples/python/digital/Makefile \ gnuradio-examples/python/digital_voice/Makefile \ + gnuradio-examples/python/mp-sched/Makefile \ gnuradio-examples/python/multi-antenna/Makefile \ gnuradio-examples/python/multi_usrp/Makefile \ gnuradio-examples/python/network/Makefile \ diff --git a/configure-cell-cross b/configure-cell-cross index 5bcd77b17..6d6e7e542 100755 --- a/configure-cell-cross +++ b/configure-cell-cross @@ -31,8 +31,7 @@ fi arch=ppu cell_root=/mnt/cell-root python_version=2.5 -# compiler_includes="-I${cell_root}/usr/include -I${cell_root}/usr/local/include -I${cell_root}/usr/lib/gcc/ppu/4.1.1/include -I${cell_root}/usr/lib/gcc/ppu/4.1.1/include/c++" -compiler_includes="-I${cell_root}/usr/include" +compiler_includes="-isystem ${cell_root}/usr/include" $scriptdir/configure \ CC=${arch}32-gcc \ diff --git a/configure.ac b/configure.ac index 5d4c380e8..389d74787 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(gnuradio,3.1svn) dnl add ${prefix}/lib/pkgconfig to the head of the PKG_CONFIG_PATH -if test [x]${PKG_CONFIG_PATH} = x; then +if test x${PKG_CONFIG_PATH} = x; then PKG_CONFIG_PATH=${prefix}/lib/pkgconfig else PKG_CONFIG_PATH=${prefix}/lib/pkgconfig:${PKG_CONFIG_PATH} @@ -44,9 +44,9 @@ if test -n "${CXXFLAGS}"; then user_set_cxxflags=yes fi -GR_X86_64 dnl check for lib64 suffix LF_CONFIGURE_CC LF_CONFIGURE_CXX +GR_LIB64 dnl check for lib64 suffix after choosing compilers dnl The three macros above are known to override CXXFLAGS if the user dnl didn't specify them. Though I'm sure somebody thought this was @@ -100,10 +100,10 @@ AM_CONDITIONAL([HAS_XMLTO], [test x$XMLTO = xyes]) dnl Checks for libraries. AC_CHECK_LIB(socket,socket) -dnl check for threads (mandatory) +dnl check for omnithreads (will soon be removed) GR_OMNITHREAD -CFLAGS="${CFLAGS} $PTHREAD_CFLAGS" -CXXFLAGS="${CXXFLAGS} $PTHREAD_CFLAGS" +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" if test x$CXX_FOR_BUILD = x then @@ -204,15 +204,39 @@ PKG_CHECK_EXISTS(cppunit, [AM_PATH_CPPUNIT([1.9.14],[], [AC_MSG_ERROR([GNU Radio requires cppunit. Stop])])]) +CPPUNIT_INCLUDES=$CPPUNIT_CFLAGS +AC_SUBST(CPPUNIT_INCLUDES) + dnl see if GUILE is installed AC_PATH_PROG(GUILE,guile) -CPPUNIT_INCLUDES=$CPPUNIT_CFLAGS -AC_SUBST(CPPUNIT_INCLUDES) +dnl +dnl We require the boost headers, thread lib and date_time lib. +dnl AX_BOOST_BASE finds the headers and the lib dir (-L<foo>) +dnl +dnl calls AC_SUBST(BOOST_CPPFLAGS), AC_SUBST(BOOST_LDFLAGS) and defines HAVE_BOOST +AX_BOOST_BASE([1.35]) + +dnl calls AC_SUBST(BOOST_THREAD_LIB), AC_SUBST(BOOST_CXXFLAGS) and defines HAVE_BOOST_THREAD +AX_BOOST_THREAD +CXXFLAGS="$CXXFLAGS $BOOST_CXXFLAGS" dnl often picks up a -pthread or something similar +CFLAGS="$CFLAGS $BOOST_CXXFLAGS" dnl often picks up a -pthread or something similar + +dnl +dnl all the rest of these call AC_SUBST(BOOST_<foo>_LIB) and define HAVE_BOOST_<foo> +dnl +AX_BOOST_DATE_TIME +dnl AX_BOOST_FILESYSTEM +dnl AX_BOOST_IOSTREAMS +dnl AX_BOOST_PROGRAM_OPTIONS +dnl AX_BOOST_REGEX +dnl AX_BOOST_SERIALIZATION +dnl AX_BOOST_SIGNALS +dnl AX_BOOST_SYSTEM +dnl AX_BOOST_TEST_EXEC_MONITOR +dnl AX_BOOST_UNIT_TEST_FRAMEWORK +dnl AX_BOOST_WSERIALIZATION -dnl Define where to find boost includes -dnl defines BOOST_CFLAGS -GR_REQUIRE_BOOST_INCLUDES dnl If this is being done from a subversion tree, create variables GR_SUBVERSION diff --git a/dtools/bin/check-tarball-h-files b/dtools/bin/check-tarball-h-files index dae7592d2..6e3e1e776 100755 --- a/dtools/bin/check-tarball-h-files +++ b/dtools/bin/check-tarball-h-files @@ -17,7 +17,8 @@ tar tzf $tarball \ find . \( -name '*.h' -o -name '*.py' -o -name '*.v' -o -name '*.vh' \) -print \ | grep -v ./$path | sort >/tmp/build-h-files -comm -23 /tmp/build-h-files /tmp/tarball-h-files +comm -23 /tmp/build-h-files /tmp/tarball-h-files \ + | grep -Ev '(GrAtsc|_swig_|limbo|config\.h|std_paths\.h)' # rm /tmp/tarball-h-files /tmp/build-h-files diff --git a/gcell/src/lib/spu/Makefile.am b/gcell/src/lib/spu/Makefile.am index 30385f9b4..7c8e411f7 100644 --- a/gcell/src/lib/spu/Makefile.am +++ b/gcell/src/lib/spu/Makefile.am @@ -64,6 +64,7 @@ general_spu_sources = \ $(general_srcdir)/memset.S general_spu_headers = \ + $(general_srcdir)/gc_spu_macs.h \ $(general_srcdir)/libfft.h general_spu_noinst_headers = \ diff --git a/gcell/src/lib/wrapper/Makefile.am b/gcell/src/lib/wrapper/Makefile.am index c8b0fcd82..8d92b7b0a 100644 --- a/gcell/src/lib/wrapper/Makefile.am +++ b/gcell/src/lib/wrapper/Makefile.am @@ -62,7 +62,8 @@ gcellinclude_HEADERS = \ noinst_HEADERS = \ qa_gcell_general.h \ - qa_gcell_wrapper.h + qa_gcell_wrapper.h \ + qa_gcp_fft_1d_r2.h CLEANFILES = gcell_all.lo gcell_general_qa.lo diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am index 66567048c..e4646cfcc 100644 --- a/gnuradio-core/src/lib/Makefile.am +++ b/gnuradio-core/src/lib/Makefile.am @@ -36,6 +36,8 @@ libgnuradio_core_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 libgnuradio_core_qa_la_SOURCES = bug_work_around_6.cc libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \ $(LIBGNURADIO_CORE_EXTRA_LDFLAGS) + + libgnuradio_core_la_LIBADD = \ filter/libfilter.la \ g72x/libccitt.la \ @@ -47,6 +49,7 @@ libgnuradio_core_la_LIBADD = \ reed-solomon/librs.la \ runtime/libruntime.la \ $(OMNITHREAD_LA) \ + $(GRUEL_LA) \ $(FFTW3F_LIBS) libgnuradio_core_qa_la_LIBADD = \ diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 1ddb84415..669461632 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -117,7 +117,7 @@ generic_qa_CODE = \ x86_CODE = \ sysconfig_x86.cc \ gr_fir_sysconfig_x86.cc \ - gr_cpu.cc \ + gr_cpu_x86.cc \ gr_fir_ccc_simd.cc \ gr_fir_ccc_x86.cc \ gr_fir_fff_simd.cc \ @@ -166,6 +166,18 @@ x86_qa_CODE = \ qa_complex_dotprod_x86.cc \ qa_ccomplex_dotprod_x86.cc +powerpc_CODE = \ + sysconfig_powerpc.cc \ + gr_fir_sysconfig_powerpc.cc \ + gr_cpu_powerpc.cc \ + gr_fir_fff_altivec.cc \ + gr_altivec.c \ + dotprod_fff_altivec.c + +powerpc_qa_CODE = \ + qa_dotprod_powerpc.cc + + # # include each <foo>_CODE entry here... # @@ -175,7 +187,9 @@ EXTRA_libfilter_la_SOURCES = \ $(x86_CODE) \ $(x86_SUBCODE) \ $(x86_64_SUBCODE) \ - $(x86_qa_CODE) + $(x86_qa_CODE) \ + $(powerpc_CODE) \ + $(powerpc_qa_CODE) EXTRA_DIST = \ @@ -234,6 +248,11 @@ endif libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(x86_qa_CODE) endif +if MD_CPU_powerpc +libfilter_la_SOURCES = $(libfilter_la_common_SOURCES) $(powerpc_CODE) +libfilter_qa_la_SOURCES = $(libfilter_qa_la_common_SOURCES) $(powerpc_qa_CODE) +endif + grinclude_HEADERS = \ $(GENERATED_H) \ @@ -245,12 +264,14 @@ grinclude_HEADERS = \ float_dotprod_generic.h \ float_dotprod_x86.h \ gr_adaptive_fir_ccf.h \ + gr_altivec.h \ gr_cma_equalizer_cc.h \ gr_cpu.h \ gr_fft_filter_ccc.h \ gr_fft_filter_fff.h \ gr_filter_delay_fc.h \ gr_fir_sysconfig_x86.h \ + gr_fir_sysconfig_powerpc.h \ gr_fractional_interpolator_ff.h \ gr_fractional_interpolator_cc.h \ gr_goertzel_fc.h \ @@ -272,6 +293,7 @@ grinclude_HEADERS = \ noinst_HEADERS = \ assembly.h \ + dotprod_fff_altivec.h \ gr_fir_scc_simd.h \ gr_fir_scc_x86.h \ gr_fir_fcc_simd.h \ @@ -280,6 +302,7 @@ noinst_HEADERS = \ gr_fir_ccf_x86.h \ gr_fir_ccc_simd.h \ gr_fir_ccc_x86.h \ + gr_fir_fff_altivec.h \ gr_fir_fff_simd.h \ gr_fir_fff_x86.h \ gr_fir_fsf_simd.h \ diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c new file mode 100644 index 000000000..ebddeb502 --- /dev/null +++ b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.c @@ -0,0 +1,162 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <dotprod_fff_altivec.h> +#include <gr_altivec.h> + +/*! + * \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 +gr_p2_round_down(size_t x, size_t pow2) +{ + return x & -pow2; +} + + +#if 0 + +float +dotprod_fff_altivec(const float *a, const float *b, size_t n) +{ + float sum = 0; + for (size_t i = 0; i < n; i++){ + sum += a[i] * b[i]; + } + return sum; +} + +#else + +/* + * preconditions: + * + * n > 0 and a multiple of 4 + * a 4-byte aligned + * b 16-byte aligned + */ +float +dotprod_fff_altivec(const float *_a, const float *_b, size_t n) +{ + const vector float *a = (const vector float *) _a; + const vector float *b = (const vector float *) _b; + + static const size_t UNROLL_CNT = 4; + + n = gr_p2_round_down(n, 4); + size_t loop_cnt = n / (UNROLL_CNT * FLOATS_PER_VEC); + size_t nleft = n % (UNROLL_CNT * FLOATS_PER_VEC); + + // printf("n = %zd, loop_cnt = %zd, nleft = %zd\n", n, loop_cnt, nleft); + + // Used with vperm to build a* from p* + vector unsigned char lvsl_a = vec_lvsl(0, _a); + + vector float p0, p1, p2, p3; + vector float a0, a1, a2, a3; + vector float b0, b1, b2, b3; + vector float acc0 = {0, 0, 0, 0}; + vector float acc1 = {0, 0, 0, 0}; + vector float acc2 = {0, 0, 0, 0}; + vector float acc3 = {0, 0, 0, 0}; + + // wind in + + p0 = vec_ld(0*VS, a); + p1 = vec_ld(1*VS, a); + p2 = vec_ld(2*VS, a); + p3 = vec_ld(3*VS, a); + a += UNROLL_CNT; + + a0 = vec_perm(p0, p1, lvsl_a); + b0 = vec_ld(0*VS, b); + p0 = vec_ld(0*VS, a); + + size_t i; + for (i = 0; i < loop_cnt; i++){ + + a1 = vec_perm(p1, p2, lvsl_a); + b1 = vec_ld(1*VS, b); + p1 = vec_ld(1*VS, a); + acc0 = vec_madd(a0, b0, acc0); + + a2 = vec_perm(p2, p3, lvsl_a); + b2 = vec_ld(2*VS, b); + p2 = vec_ld(2*VS, a); + acc1 = vec_madd(a1, b1, acc1); + + a3 = vec_perm(p3, p0, lvsl_a); + b3 = vec_ld(3*VS, b); + p3 = vec_ld(3*VS, a); + acc2 = vec_madd(a2, b2, acc2); + + a += UNROLL_CNT; + b += UNROLL_CNT; + + a0 = vec_perm(p0, p1, lvsl_a); + b0 = vec_ld(0*VS, b); + p0 = vec_ld(0*VS, a); + acc3 = vec_madd(a3, b3, acc3); + } + + /* + * The compiler ought to be able to figure out that 0, 4, 8 and 12 + * are the only possible values for nleft. + */ + switch (nleft){ + case 0: + break; + + case 4: + acc0 = vec_madd(a0, b0, acc0); + break; + + case 8: + a1 = vec_perm(p1, p2, lvsl_a); + b1 = vec_ld(1*VS, b); + acc0 = vec_madd(a0, b0, acc0); + acc1 = vec_madd(a1, b1, acc1); + break; + + case 12: + a1 = vec_perm(p1, p2, lvsl_a); + b1 = vec_ld(1*VS, b); + acc0 = vec_madd(a0, b0, acc0); + a2 = vec_perm(p2, p3, lvsl_a); + b2 = vec_ld(2*VS, b); + acc1 = vec_madd(a1, b1, acc1); + acc2 = vec_madd(a2, b2, acc2); + break; + } + + acc0 = acc0 + acc1; + acc2 = acc2 + acc3; + acc0 = acc0 + acc2; + + return horizontal_add_f(acc0); +} + +#endif diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h new file mode 100644 index 000000000..d9ee52cf0 --- /dev/null +++ b/gnuradio-core/src/lib/filter/dotprod_fff_altivec.h @@ -0,0 +1,49 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_DOTPROD_FFF_ALTIVEC_H +#define INCLUDED_DOTPROD_FFF_ALTIVEC_H + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * <pre> + * + * preconditions: + * + * n > 0 and a multiple of 4 + * a 4-byte aligned + * b 16-byte aligned + * + * </pre> + */ +float +dotprod_fff_altivec(const float *a, const float *b, size_t n); + +#ifdef __cplusplus +} +#endif + + +#endif /* INCLUDED_DOTPROD_FFF_ALTIVEC_H */ diff --git a/gnuradio-core/src/lib/filter/gr_altivec.c b/gnuradio-core/src/lib/filter/gr_altivec.c new file mode 100644 index 000000000..01ca95f0d --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_altivec.c @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <gr_altivec.h> + +void +gr_print_vector_float(FILE *fp, vector float v) +{ + union v_float_u u; + u.v = v; + fprintf(fp, "{ %f, %f, %f, %f }", u.f[0], u.f[1], u.f[2], u.f[3]); +} + +void +gr_pvf(FILE *fp, const char *label, vector float v) +{ + fprintf(fp, "%s = ", label); + gr_print_vector_float(fp, v); + putc('\n', fp); +} diff --git a/gnuradio-core/src/lib/filter/gr_altivec.h b/gnuradio-core/src/lib/filter/gr_altivec.h new file mode 100644 index 000000000..176579a6a --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_altivec.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_ALTIVEC_H +#define INCLUDED_GR_ALTIVEC_H + +#include <altivec.h> +#include <stddef.h> +#include <stdio.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define VS sizeof(vector float) +#define FLOATS_PER_VEC (sizeof(vector float)/sizeof(float)) + +union v_float_u { + vector float v; + float f[FLOATS_PER_VEC]; +}; + +void gr_print_vector_float(FILE *fp, vector float v); +void gr_pvf(FILE *fp, const char *label, vector float v); + +static inline float +horizontal_add_f(vector float v) +{ + union v_float_u u; + vector float t0 = vec_add(v, vec_sld(v, v, 8)); + vector float t1 = vec_add(t0, vec_sld(t0, t0, 4)); + u.v = t1; + return u.f[0]; +} + +#ifdef __cplusplus +} +#endif + +#endif /* INCLUDED_GR_ALTIVEC_H */ diff --git a/gnuradio-core/src/lib/filter/gr_cpu.h b/gnuradio-core/src/lib/filter/gr_cpu.h index 5967d9868..ef10beae1 100644 --- a/gnuradio-core/src/lib/filter/gr_cpu.h +++ b/gnuradio-core/src/lib/filter/gr_cpu.h @@ -33,6 +33,7 @@ struct gr_cpu { static bool has_sse4_2 (); static bool has_3dnow (); static bool has_3dnowext (); + static bool has_altivec (); }; #endif /* _GR_CPU_H_ */ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h b/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc index ec2e51cf2..35c342aaa 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h +++ b/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007 Free Software Foundation, Inc. + * Copyright 2002,2008 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,36 +20,40 @@ * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_GR_TOP_BLOCK_IMPL_STS_H -#define INCLUDED_GR_TOP_BLOCK_IMPL_STS_H +#include <gr_cpu.h> -#include <gr_top_block_impl.h> -#include <gr_scheduler_thread.h> - -/*! - *\brief Implementation details of gr_top_block - * \ingroup internal - * - * Concrete implementation of gr_top_block using gr_single_threaded_scheduler. - */ -class gr_top_block_impl_sts : public gr_top_block_impl +bool +gr_cpu::has_mmx () { -public: - gr_top_block_impl_sts(gr_top_block *owner); - ~gr_top_block_impl_sts(); + return false; +} - // Signal scheduler threads to stop - void stop(); +bool +gr_cpu::has_sse () +{ + return false; +} - // Wait for scheduler threads to exit - void wait(); +bool +gr_cpu::has_sse2 () +{ + return false; +} -private: - - gr_scheduler_thread_vector_t d_threads; - std::vector<gr_basic_block_vector_t> d_graphs; +bool +gr_cpu::has_3dnow () +{ + return false; +} - void start_threads(); -}; +bool +gr_cpu::has_3dnowext () +{ + return false; +} -#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_STS_H */ +bool +gr_cpu::has_altivec () +{ + return true; // FIXME assume we've always got it +} diff --git a/gnuradio-core/src/lib/filter/gr_cpu.cc b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc index 517c10e9a..a13a69c06 100644 --- a/gnuradio-core/src/lib/filter/gr_cpu.cc +++ b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2008 Free Software Foundation, Inc. + * Copyright 2002 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -85,35 +85,6 @@ gr_cpu::has_sse2 () } bool -gr_cpu::has_sse3 () -{ - unsigned int ecx = cpuid_ecx (1); // standard features - return (ecx & (1 << 0)) != 0; -} - -bool -gr_cpu::has_ssse3 () -{ - unsigned int ecx = cpuid_ecx (1); // standard features - return (ecx & (1 << 9)) != 0; -} - -bool -gr_cpu::has_sse4_1 () -{ - unsigned int ecx = cpuid_ecx (1); // standard features - return (ecx & (1 << 19)) != 0; -} - -bool -gr_cpu::has_sse4_2 () -{ - unsigned int ecx = cpuid_ecx (1); // standard features - return (ecx & (1 << 20)) != 0; -} - - -bool gr_cpu::has_3dnow () { unsigned int extended_fct_count = cpuid_eax (0x80000000); @@ -134,3 +105,9 @@ gr_cpu::has_3dnowext () unsigned int extended_features = cpuid_edx (0x80000001); return (extended_features & (1 << 30)) != 0; } + +bool +gr_cpu::has_altivec () +{ + return false; +} diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc new file mode 100644 index 000000000..7583f5c1f --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_fir_fff_altivec.h> +#include <stdlib.h> +#include <stdexcept> +#include <assert.h> +#include <gr_math.h> +#include <gr_altivec.h> +#include <dotprod_fff_altivec.h> + +gr_fir_fff_altivec::gr_fir_fff_altivec() + : gr_fir_fff_generic(), + d_naligned_taps(0), d_aligned_taps(0) +{ +} + +gr_fir_fff_altivec::gr_fir_fff_altivec (const std::vector<float> &new_taps) + : gr_fir_fff_generic(new_taps), + d_naligned_taps(0), d_aligned_taps(0) +{ + set_taps(new_taps); +} + +gr_fir_fff_altivec::~gr_fir_fff_altivec() +{ + if (d_aligned_taps){ + free(d_aligned_taps); + d_aligned_taps = 0; + } +} + +void +gr_fir_fff_altivec::set_taps(const std::vector<float> &inew_taps) +{ + gr_fir_fff_generic::set_taps(inew_taps); // call superclass + d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC); + + if (d_aligned_taps){ + free(d_aligned_taps); + d_aligned_taps = 0; + } + void *p; + int r = posix_memalign(&p, sizeof(vector float), d_naligned_taps * sizeof(d_aligned_taps[0])); + if (r != 0){ + throw std::bad_alloc(); + } + d_aligned_taps = (float *) p; + memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0])); + for (size_t i = ntaps(); i < d_naligned_taps; i++) + d_aligned_taps[i] = 0.0; +} + + +float +gr_fir_fff_altivec::filter (const float input[]) +{ + if (d_naligned_taps == 0) + return 0.0; + + return dotprod_fff_altivec(input, d_aligned_taps, d_naligned_taps); +} diff --git a/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h new file mode 100644 index 000000000..1694f5524 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_FIR_FFF_ALTIVEC_H +#define INCLUDED_GR_FIR_FFF_ALTIVEC_H + +#include <gr_fir_fff_generic.h> + +/*! + * \brief altivec version of gr_fir_fff + */ +class gr_fir_fff_altivec : public gr_fir_fff_generic +{ +protected: + + size_t d_naligned_taps; // number of taps (multiple of 4) + float *d_aligned_taps; // 16-byte aligned, and zero padded to multiple of 4 + +public: + gr_fir_fff_altivec(); + gr_fir_fff_altivec(const std::vector<float> &taps); + ~gr_fir_fff_altivec(); + + virtual void set_taps (const std::vector<float> &taps); + virtual float filter (const float input[]); +}; + +#endif /* INCLUDED_GR_FIR_FFF_ALTIVEC_H */ diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc new file mode 100644 index 000000000..34d3f8135 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc @@ -0,0 +1,340 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_fir_sysconfig_powerpc.h> +#include <gr_cpu.h> + +#include <gr_fir_ccf.h> +#include <gr_fir_ccf_generic.h> +//#include <gr_fir_ccf_altivec.h> +#include <gr_fir_fcc.h> +#include <gr_fir_fcc_generic.h> +//#include <gr_fir_fcc_altivec.h> +#include <gr_fir_fff.h> +#include <gr_fir_fff_generic.h> +#include <gr_fir_fff_altivec.h> +#include <gr_fir_fsf.h> +#include <gr_fir_fsf_generic.h> +//#include <gr_fir_fsf_powerpc.h> +#include <gr_fir_ccc.h> +#include <gr_fir_ccc_generic.h> +//#include <gr_fir_ccc_altivec.h> +#include <gr_fir_scc.h> +#include <gr_fir_scc_generic.h> +//#include <gr_fir_scc_altivec.h> + +#include <iostream> +using std::cerr; + +/* + * ---------------------------------------------------------------- + * static functions that serve as constructors... + * ---------------------------------------------------------------- + */ + +#if 0 +static gr_fir_ccf * +make_gr_fir_ccf_altivec(const std::vector<float> &taps) +{ + return new gr_fir_ccf_altivec(taps); +} + +static gr_fir_fcc * +make_gr_fir_fcc_altivec(const std::vector<gr_complex> &taps) +{ + return new gr_fir_fcc_altivec(taps); +} + +static gr_fir_ccc * +make_gr_fir_ccc_altivec (const std::vector<gr_complex> &taps) +{ + return new gr_fir_ccc_altivec (taps); +} +#endif + +static gr_fir_fff * +make_gr_fir_fff_altivec (const std::vector<float> &taps) +{ + return new gr_fir_fff_altivec (taps); +} + +#if 0 +static gr_fir_fsf * +make_gr_fir_fsf_altivec (const std::vector<float> &taps) +{ + return new gr_fir_fsf_altivec (taps); +} + +static gr_fir_scc * +make_gr_fir_scc_altivec(const std::vector<gr_complex> &taps) +{ + return new gr_fir_scc_altivec(taps); +} +#endif + +/* + * ---------------------------------------------------------------- + * Return instances of the fastest powerpc versions of these classes. + * + * check CPUID, if has altivec, return altivec version, + * else return generic version. + * ---------------------------------------------------------------- + */ + +gr_fir_ccf * +gr_fir_sysconfig_powerpc::create_gr_fir_ccf (const std::vector<float> &taps) +{ + static bool first = true; + +#if 0 + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_ccf: using altivec\n"; + first = false; + } + return make_gr_fir_ccf_altivec (taps); + } +#endif + + if (0 && first){ + cerr << ">>> gr_fir_ccf: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_ccf (taps); +} + +gr_fir_fcc * +gr_fir_sysconfig_powerpc::create_gr_fir_fcc (const std::vector<gr_complex> &taps) +{ + static bool first = true; + +#if 0 + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_fcc: using altivec\n"; + first = false; + } + return make_gr_fir_fcc_altivec (taps); + } +#endif + + if (0 && first){ + cerr << ">>> gr_fir_fcc: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_fcc (taps); +} + +gr_fir_ccc * +gr_fir_sysconfig_powerpc::create_gr_fir_ccc (const std::vector<gr_complex> &taps) +{ + static bool first = true; + +#if 0 + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_ccc: using altivec\n"; + first = false; + } + return make_gr_fir_ccc_altivec (taps); + } +#endif + + if (0 && first){ + cerr << ">>> gr_fir_ccc: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_ccc (taps); +} + +gr_fir_fff * +gr_fir_sysconfig_powerpc::create_gr_fir_fff (const std::vector<float> &taps) +{ + static bool first = true; + + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_fff: using altivec\n"; + first = false; + } + return make_gr_fir_fff_altivec (taps); + } + + if (0 && first){ + cerr << ">>> gr_fir_fff: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_fff (taps); +} + +gr_fir_fsf * +gr_fir_sysconfig_powerpc::create_gr_fir_fsf (const std::vector<float> &taps) +{ + static bool first = true; + +#if 0 + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_fsf: using altivec\n"; + first = false; + } + return make_gr_fir_fsf_altivec (taps); + } +#endif + + if (0 && first){ + cerr << ">>> gr_fir_fsf: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_fsf (taps); +} + + +gr_fir_scc * +gr_fir_sysconfig_powerpc::create_gr_fir_scc (const std::vector<gr_complex> &taps) +{ + static bool first = true; + +#if 0 + if (gr_cpu::has_altivec ()){ + if (first){ + cerr << ">>> gr_fir_scc: using altivec\n"; + first = false; + } + return make_gr_fir_scc_altivec (taps); + } +#endif + + if (0 && first){ + cerr << ">>> gr_fir_scc: handing off to parent class\n"; + first = false; + } + return gr_fir_sysconfig_generic::create_gr_fir_scc (taps); +} + +/* + * ---------------------------------------------------------------- + * Return info about available implementations + * ---------------------------------------------------------------- + */ + +void +gr_fir_sysconfig_powerpc::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info); + +#if 0 + // add our stuff... + gr_fir_ccf_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_ccf_altivec; + (*info).push_back (t); + } +#endif +} + +void +gr_fir_sysconfig_powerpc::get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_fcc_info (info); + +#if 0 + // add our stuff... + gr_fir_fcc_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_fcc_altivec; + (*info).push_back (t); + } +#endif +} + +void +gr_fir_sysconfig_powerpc::get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_ccc_info (info); + +#if 0 + // add our stuff... + gr_fir_ccc_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_ccc_altivec; + (*info).push_back (t); + } +#endif +} + +void +gr_fir_sysconfig_powerpc::get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_fff_info (info); + + // add our stuff... + gr_fir_fff_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_fff_altivec; + (*info).push_back (t); + } +} + +void +gr_fir_sysconfig_powerpc::get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_fsf_info (info); + +#if 0 + // add our stuff... + gr_fir_fsf_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_fsf_altivec; + (*info).push_back (t); + } +#endif +} + +void +gr_fir_sysconfig_powerpc::get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info) +{ + // invoke parent.. + gr_fir_sysconfig_generic::get_gr_fir_scc_info (info); + +#if 0 + // add our stuff... + gr_fir_scc_info t; + if (gr_cpu::has_altivec ()){ + t.name = "altivec"; + t.create = make_gr_fir_scc_altivec; + (*info).push_back (t); + } +#endif +} diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h new file mode 100644 index 000000000..9c31cdf1b --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#ifndef INCLUDED_GR_FIR_SYSCONFIG_POWERPC_H +#define INCLUDED_GR_FIR_SYSCONFIG_POWERPC_H + +#include <gr_fir_sysconfig_generic.h> + +class gr_fir_sysconfig_powerpc : public gr_fir_sysconfig_generic { +public: + virtual gr_fir_ccf *create_gr_fir_ccf (const std::vector<float> &taps); + virtual gr_fir_fcc *create_gr_fir_fcc (const std::vector<gr_complex> &taps); + virtual gr_fir_fff *create_gr_fir_fff (const std::vector<float> &taps); + virtual gr_fir_fsf *create_gr_fir_fsf (const std::vector<float> &taps); + virtual gr_fir_scc *create_gr_fir_scc (const std::vector<gr_complex> &taps); + virtual gr_fir_ccc *create_gr_fir_ccc (const std::vector<gr_complex> &taps); +//virtual gr_fir_sss *create_gr_fir_sss (const std::vector<short> &taps); + + virtual void get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *info); + virtual void get_gr_fir_fcc_info (std::vector<gr_fir_fcc_info> *info); + virtual void get_gr_fir_fff_info (std::vector<gr_fir_fff_info> *info); + virtual void get_gr_fir_fsf_info (std::vector<gr_fir_fsf_info> *info); + virtual void get_gr_fir_scc_info (std::vector<gr_fir_scc_info> *info); + virtual void get_gr_fir_ccc_info (std::vector<gr_fir_ccc_info> *info); +//virtual void get_gr_fir_sss_info (std::vector<gr_fir_sss_info> *info); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc b/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc new file mode 100644 index 000000000..1b02a79c8 --- /dev/null +++ b/gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2003 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ +#include "qa_dotprod.h" + +CppUnit::TestSuite * +qa_dotprod_suite () +{ + CppUnit::TestSuite *s = new CppUnit::TestSuite ("dotprod"); + + // empty test suite + + return s; +} diff --git a/gnuradio-core/src/lib/filter/qa_filter.cc b/gnuradio-core/src/lib/filter/qa_filter.cc index e36fca45d..e2fa72add 100644 --- a/gnuradio-core/src/lib/filter/qa_filter.cc +++ b/gnuradio-core/src/lib/filter/qa_filter.cc @@ -42,13 +42,13 @@ qa_filter::suite () CppUnit::TestSuite *s = new CppUnit::TestSuite ("filter"); s->addTest (qa_dotprod_suite ()); - s->addTest (qa_gri_mmse_fir_interpolator::suite ()); - s->addTest (qa_gri_mmse_fir_interpolator_cc::suite ()); s->addTest (qa_gr_fir_fff::suite ()); s->addTest (qa_gr_fir_ccc::suite ()); s->addTest (qa_gr_fir_fcc::suite ()); s->addTest (qa_gr_fir_scc::suite ()); s->addTest (qa_gr_fir_ccf::suite ()); + s->addTest (qa_gri_mmse_fir_interpolator::suite ()); + s->addTest (qa_gri_mmse_fir_interpolator_cc::suite ()); return s; } diff --git a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc index 380435bf7..b921223ed 100644 --- a/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc +++ b/gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc @@ -143,7 +143,7 @@ ref_dotprod (const i_type input[], const tap_type taps[], int ntaps) static void test_random_io (fir_maker_t maker) { - const int MAX_TAPS = 9; + const int MAX_TAPS = 32; const int OUTPUT_LEN = 17; const int INPUT_LEN = MAX_TAPS + OUTPUT_LEN; @@ -187,7 +187,7 @@ test_random_io (fir_maker_t maker) for (int o = 0; o < ol; o++){ CPPUNIT_ASSERT_DOUBLES_EQUAL (expected_output[o], actual_output[o], - fabs (expected_output[o]) * 1e-4); + fabs (expected_output[o]) * 9e-3); } delete f1; diff --git a/gnuradio-core/src/lib/filter/sysconfig_powerpc.cc b/gnuradio-core/src/lib/filter/sysconfig_powerpc.cc new file mode 100644 index 000000000..e2b27815b --- /dev/null +++ b/gnuradio-core/src/lib/filter/sysconfig_powerpc.cc @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_fir_sysconfig_powerpc.h> + +gr_fir_sysconfig * +gr_fir_sysconfig_singleton () +{ + static gr_fir_sysconfig *singleton = 0; + + if (singleton) + return singleton; + + singleton = new gr_fir_sysconfig_powerpc (); + return singleton; +} diff --git a/gnuradio-core/src/lib/general/gr_math.h b/gnuradio-core/src/lib/general/gr_math.h index 957a0e12a..f1bd208b8 100644 --- a/gnuradio-core/src/lib/general/gr_math.h +++ b/gnuradio-core/src/lib/general/gr_math.h @@ -174,4 +174,48 @@ static inline unsigned int gr_branchless_quad_45deg_slicer(gr_complex x) return gr_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 +gr_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 +gr_p2_round_up(size_t x, size_t pow2) +{ + return gr_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 +gr_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 +gr_p2_modulo_neg(size_t x, size_t pow2) +{ + return pow2 - gr_p2_modulo(x, pow2); +} + #endif /* _GR_MATH_H_ */ diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index 17ea89e13..f6e28e1d1 100644 --- a/gnuradio-core/src/lib/general/gri_fft.cc +++ b/gnuradio-core/src/lib/general/gri_fft.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2003,2008 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,11 @@ #include <stdio.h> #include <cassert> #include <stdexcept> +#include <boost/thread.hpp> + +typedef boost::mutex::scoped_lock scoped_lock; +static boost::mutex s_planning_mutex; + static char * wisdom_filename () @@ -80,6 +85,9 @@ gri_fftw_export_wisdom () gri_fft_complex::gri_fft_complex (int fft_size, bool forward) { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -96,10 +104,6 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) throw std::runtime_error ("fftwf_malloc"); } - // FIXME If there's ever a chance that the planning functions - // will be called in multiple threads, we've got to ensure single - // threaded access. They are not thread-safe. - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_1d (fft_size, reinterpret_cast<fftwf_complex *>(d_inbuf), @@ -116,6 +120,9 @@ gri_fft_complex::gri_fft_complex (int fft_size, bool forward) gri_fft_complex::~gri_fft_complex () { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); @@ -131,6 +138,9 @@ gri_fft_complex::execute () gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + assert (sizeof (fftwf_complex) == sizeof (gr_complex)); if (fft_size <= 0) @@ -147,10 +157,6 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) throw std::runtime_error ("fftwf_malloc"); } - // FIXME If there's ever a chance that the planning functions - // will be called in multiple threads, we've got to ensure single - // threaded access. They are not thread-safe. - gri_fftw_import_wisdom (); // load prior wisdom from disk d_plan = fftwf_plan_dft_r2c_1d (fft_size, d_inbuf, @@ -166,6 +172,9 @@ gri_fft_real_fwd::gri_fft_real_fwd (int fft_size) gri_fft_real_fwd::~gri_fft_real_fwd () { + // Hold global mutex during plan construction and destruction. + scoped_lock lock(s_planning_mutex); + fftwf_destroy_plan ((fftwf_plan) d_plan); fftwf_free (d_inbuf); fftwf_free (d_outbuf); diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am index 550031b94..b21b32412 100644 --- a/gnuradio-core/src/lib/runtime/Makefile.am +++ b/gnuradio-core/src/lib/runtime/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(GRUEL_INCLUDES) $(WITH_INCLUDES) noinst_LTLIBRARIES = libruntime.la libruntime-qa.la @@ -35,6 +35,7 @@ libruntime_la_SOURCES = \ gr_flat_flowgraph.cc \ gr_block.cc \ gr_block_detail.cc \ + gr_block_executor.cc \ gr_hier_block2.cc \ gr_hier_block2_detail.cc \ gr_buffer.cc \ @@ -48,16 +49,19 @@ libruntime_la_SOURCES = \ gr_pagesize.cc \ gr_preferences.cc \ gr_realtime.cc \ - gr_scheduler_thread.cc \ + gr_scheduler.cc \ + gr_scheduler_sts.cc \ + gr_scheduler_tpb.cc \ gr_single_threaded_scheduler.cc \ gr_sptr_magic.cc \ gr_sync_block.cc \ gr_sync_decimator.cc \ gr_sync_interpolator.cc \ + gr_tmp_path.cc \ gr_top_block.cc \ gr_top_block_impl.cc \ - gr_top_block_impl_sts.cc \ - gr_tmp_path.cc \ + gr_tpb_detail.cc \ + gr_tpb_thread_body.cc \ gr_vmcircbuf.cc \ gr_vmcircbuf_mmap_shm_open.cc \ gr_vmcircbuf_mmap_tmpfile.cc \ @@ -82,6 +86,7 @@ grinclude_HEADERS = \ gr_flat_flowgraph.h \ gr_block.h \ gr_block_detail.h \ + gr_block_executor.h \ gr_hier_block2.h \ gr_hier_block2_detail.h \ gr_buffer.h \ @@ -97,7 +102,9 @@ grinclude_HEADERS = \ gr_preferences.h \ gr_realtime.h \ gr_runtime_types.h \ - gr_scheduler_thread.h \ + gr_scheduler.h \ + gr_scheduler_sts.h \ + gr_scheduler_tpb.h \ gr_select_handler.h \ gr_single_threaded_scheduler.h \ gr_sptr_magic.h \ @@ -106,7 +113,8 @@ grinclude_HEADERS = \ gr_sync_interpolator.h \ gr_top_block.h \ gr_top_block_impl.h \ - gr_top_block_impl_sts.h \ + gr_tpb_detail.h \ + gr_tpb_thread_body.h \ gr_timer.h \ gr_tmp_path.h \ gr_types.h \ diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index 0a8fb92c2..7c2e9901b 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -110,3 +110,11 @@ gr_block::fixed_rate_noutput_to_ninput(int noutput) { throw std::runtime_error("Unimplemented"); } + +std::ostream& +operator << (std::ostream& os, const gr_block *m) +{ + os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>"; + return os; +} + diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index 79237ee83..437b610b4 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -214,9 +214,13 @@ class gr_block : public gr_basic_block { typedef std::vector<gr_block_sptr> gr_block_vector_t; typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t; -inline gr_block_sptr make_gr_block_sptr(gr_basic_block_sptr p) +inline gr_block_sptr cast_to_block_sptr(gr_basic_block_sptr p) { return boost::dynamic_pointer_cast<gr_block, gr_basic_block>(p); } + +std::ostream& +operator << (std::ostream& os, const gr_block *m); + #endif /* INCLUDED_GR_BLOCK_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index a3b7731c0..2856c402c 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -24,6 +24,7 @@ #define INCLUDED_GR_BLOCK_DETAIL_H #include <gr_runtime_types.h> +#include <gr_tpb_detail.h> #include <stdexcept> /*! @@ -34,7 +35,6 @@ * 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_block_detail { public: ~gr_block_detail (); @@ -73,8 +73,14 @@ class gr_block_detail { */ void consume_each (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); + + gr_tpb_detail d_tpb; // used by thread-per-block scheduler + // ---------------------------------------------------------------------------- private: @@ -84,8 +90,11 @@ class gr_block_detail { std::vector<gr_buffer_sptr> d_output; bool d_done; + gr_block_detail (unsigned int ninputs, unsigned int noutputs); + friend class gr_tpb_detail; + friend gr_block_detail_sptr gr_make_block_detail (unsigned int ninputs, unsigned int noutputs); }; diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc new file mode 100644 index 000000000..fd3a916d4 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -0,0 +1,329 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_block_executor.h> +#include <gr_block.h> +#include <gr_block_detail.h> +#include <gr_buffer.h> +#include <boost/thread.hpp> +#include <iostream> +#include <limits> +#include <assert.h> +#include <stdio.h> + +// must be defined to either 0 or 1 +#define ENABLE_LOGGING 0 + +#if (ENABLE_LOGGING) +#define LOG(x) do { x; } while(0) +#else +#define LOG(x) do {;} while(0) +#endif + +static int which_scheduler = 0; + +inline static unsigned int +round_up (unsigned int n, unsigned int multiple) +{ + return ((n + multiple - 1) / multiple) * multiple; +} + +inline static unsigned int +round_down (unsigned int n, unsigned int multiple) +{ + return (n / multiple) * multiple; +} + +// +// Return minimum available write space in all our downstream buffers +// or -1 if we're output blocked and the output we're blocked +// on is done. +// +static int +min_available_space (gr_block_detail *d, int output_multiple) +{ + int min_space = std::numeric_limits<int>::max(); + + for (int i = 0; i < d->noutputs (); i++){ + gr_buffer::scoped_lock guard(*d->output(i)->mutex()); +#if 0 + int n = round_down(d->output(i)->space_available(), output_multiple); +#else + int n = round_down(std::min(d->output(i)->space_available(), + d->output(i)->bufsize()/2), + output_multiple); +#endif + if (n == 0){ // We're blocked on output. + if (d->output(i)->done()){ // Downstream is done, therefore we're done. + return -1; + } + return 0; + } + min_space = std::min (min_space, n); + } + return min_space; +} + + + +gr_block_executor::gr_block_executor (gr_block_sptr block) + : d_block(block), d_log(0) +{ + if (ENABLE_LOGGING){ + char name[100]; + snprintf(name, sizeof(name), "sst-%03d.log", which_scheduler++); + d_log = new std::ofstream(name); + std::unitbuf(*d_log); // make it unbuffered... + *d_log << "gr_block_executor: " + << d_block << std::endl; + } + + d_block->start(); // enable any drivers, etc. +} + +gr_block_executor::~gr_block_executor () +{ + if (ENABLE_LOGGING) + delete d_log; + + d_block->stop(); // stop any drivers, etc. +} + +gr_block_executor::state +gr_block_executor::run_one_iteration() +{ + int noutput_items; + int max_items_avail; + + gr_block *m = d_block.get(); + gr_block_detail *d = m->detail().get(); + + LOG(*d_log << std::endl << m); + + if (d->done()){ + assert(0); + return DONE; + } + + if (d->source_p ()){ + d_ninput_items_required.resize (0); + d_ninput_items.resize (0); + d_input_items.resize (0); + d_input_done.resize(0); + d_output_items.resize (d->noutputs ()); + + // determine the minimum available output space + noutput_items = min_available_space (d, m->output_multiple ()); + LOG(*d_log << " source\n noutput_items = " << noutput_items << std::endl); + if (noutput_items == -1) // we're done + goto were_done; + + if (noutput_items == 0){ // we're output blocked + LOG(*d_log << " BLKD_OUT\n"); + 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); + 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_buffer::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 ()); + 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 ()); + + 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_buffer::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 ()); + 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); + reqd_noutput_items = round_up(reqd_noutput_items, m->output_multiple()); + if (reqd_noutput_items > 0 && reqd_noutput_items <= noutput_items) + noutput_items = reqd_noutput_items; + } + + // ask the block how much input they need to produce noutput_items + m->forecast (noutput_items, d_ninput_items_required); + + // See if we've got sufficient input available + + int i; + for (i = 0; i < d->ninputs (); i++) + if (d_ninput_items_required[i] > d_ninput_items[i]) // not enough + break; + + if (i < d->ninputs ()){ // not enough input on input[i] + // if we can, try reducing the size of our output request + if (noutput_items > m->output_multiple ()){ + noutput_items /= 2; + noutput_items = round_up (noutput_items, m->output_multiple ()); + goto try_again; + } + + // We're blocked on input + LOG(*d_log << " BLKD_IN\n"); + if (d_input_done[i]) // If the upstream block is done, we're done + goto were_done; + + // Is it possible to ever fulfill this request? + if (d_ninput_items_required[i] > d->input(i)->max_possible_items_available ()){ + // Nope, never going to happen... + std::cerr << "\nsched: <gr_block " << m->name() + << " (" << m->unique_id() << ")>" + << " is requesting more input data\n" + << " than we can provide.\n" + << " ninput_items_required = " + << d_ninput_items_required[i] << "\n" + << " max_possible_items_available = " + << d->input(i)->max_possible_items_available() << "\n" + << " If this is a filter, consider reducing the number of taps.\n"; + goto were_done; + } + + 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: + + for (int i = 0; i < d->noutputs (); i++) + d_output_items[i] = d->output(i)->write_pointer(); + + // Do the actual work of the block + int n = m->general_work (noutput_items, d_ninput_items, + d_input_items, d_output_items); + LOG(*d_log << " general_work: noutput_items = " << noutput_items + << " result = " << n << std::endl); + + if (n == -1) // block is done + goto were_done; + + d->produce_each (n); // advance write pointers + if (n > 0) + return READY; + + // We didn't produce any output even though we called general_work. + // We have (most likely) consumed some input. + + // If this is a source, it's broken. + if (d->source_p()){ + std::cerr << "gr_block_executor: source " << m + << " returned 0 from work. We're marking it DONE.\n"; + // FIXME maybe we ought to raise an exception... + goto were_done; + } + + // Have the caller try again... + return READY_NO_OUTPUT; + } + assert (0); + + were_done: + LOG(*d_log << " were_done\n"); + d->set_done (true); + return DONE; +} diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.h b/gnuradio-core/src/lib/runtime/gr_block_executor.h new file mode 100644 index 000000000..41b5ede7c --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_BLOCK_EXECUTOR_H +#define INCLUDED_GR_BLOCK_EXECUTOR_H + +#include <gr_runtime_types.h> +#include <fstream> + +//class gr_block_executor; +//typedef boost::shared_ptr<gr_block_executor> gr_block_executor_sptr; + + +/*! + * \brief Manage the execution of a single block. + * \ingroup internal + */ + +class gr_block_executor { +protected: + gr_block_sptr d_block; // The block we're trying to run + std::ofstream *d_log; + + // These are allocated here so we don't have to on each iteration + + gr_vector_int d_ninput_items_required; + gr_vector_int d_ninput_items; + gr_vector_const_void_star d_input_items; + std::vector<bool> d_input_done; + gr_vector_void_star d_output_items; + + public: + gr_block_executor(gr_block_sptr block); + ~gr_block_executor (); + + enum state { + READY, // We made progress; everything's cool. + READY_NO_OUTPUT, // We consumed some input, but produced no output. + BLKD_IN, // no progress; we're blocked waiting for input data. + BLKD_OUT, // no progress; we're blocked waiting for output buffer space. + DONE, // we're done; don't call me again. + }; + + /* + * \brief Run one iteration. + */ + state run_one_iteration(); +}; + +#endif /* INCLUDED_GR_BLOCK_EXECUTOR_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc index 77f0c7c43..31a471ea7 100644 --- a/gnuradio-core/src/lib/runtime/gr_buffer.cc +++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc @@ -77,10 +77,10 @@ minimum_buffer_items (long type_size, long page_size) } -gr_buffer::gr_buffer (int nitems, size_t sizeof_item) +gr_buffer::gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link) : d_base (0), d_bufsize (0), d_vmcircbuf (0), - d_sizeof_item (sizeof_item), d_write_index (0), - d_done (false) + d_sizeof_item (sizeof_item), d_link(link), + d_write_index (0), d_done (false) { if (!allocate_buffer (nitems, sizeof_item)) throw std::bad_alloc (); @@ -89,9 +89,9 @@ gr_buffer::gr_buffer (int nitems, size_t sizeof_item) } gr_buffer_sptr -gr_make_buffer (int nitems, size_t sizeof_item) +gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link) { - return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item)); + return gr_buffer_sptr (new gr_buffer (nitems, sizeof_item, link)); } gr_buffer::~gr_buffer () @@ -146,7 +146,7 @@ gr_buffer::allocate_buffer (int nitems, size_t sizeof_item) int -gr_buffer::space_available () const +gr_buffer::space_available () { if (d_readers.empty ()) return d_bufsize - 1; // See comment below @@ -175,18 +175,27 @@ gr_buffer::write_pointer () void gr_buffer::update_write_pointer (int nitems) { + scoped_lock guard(*mutex()); d_write_index = index_add (d_write_index, nitems); } +void +gr_buffer::set_done (bool done) +{ + scoped_lock guard(*mutex()); + d_done = done; +} + gr_buffer_reader_sptr -gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload) +gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link) { if (nzero_preload < 0) throw std::invalid_argument("gr_buffer_add_reader: nzero_preload must be >= 0"); gr_buffer_reader_sptr r (new gr_buffer_reader (buf, buf->index_sub(buf->d_write_index, - nzero_preload))); + nzero_preload), + link)); buf->d_readers.push_back (r.get ()); return r; @@ -214,8 +223,9 @@ gr_buffer_ncurrently_allocated () // ---------------------------------------------------------------------------- -gr_buffer_reader::gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index) - : d_buffer (buffer), d_read_index (read_index) +gr_buffer_reader::gr_buffer_reader(gr_buffer_sptr buffer, unsigned int read_index, + gr_block_sptr link) + : d_buffer(buffer), d_read_index(read_index), d_link(link) { s_buffer_reader_count++; } @@ -241,6 +251,7 @@ gr_buffer_reader::read_pointer () void gr_buffer_reader::update_read_pointer (int nitems) { + scoped_lock guard(*mutex()); d_read_index = d_buffer->index_add (d_read_index, nitems); } diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h index cf578c89d..75063cc6a 100644 --- a/gnuradio-core/src/lib/runtime/gr_buffer.h +++ b/gnuradio-core/src/lib/runtime/gr_buffer.h @@ -24,6 +24,8 @@ #define INCLUDED_GR_BUFFER_H #include <gr_runtime_types.h> +#include <boost/weak_ptr.hpp> +#include <boost/thread.hpp> class gr_vmcircbuf; @@ -33,8 +35,12 @@ class gr_vmcircbuf; * 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_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item); +gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link=gr_block_sptr()); /*! @@ -43,12 +49,20 @@ gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item); */ class gr_buffer { public: + + typedef boost::unique_lock<boost::mutex> scoped_lock; + virtual ~gr_buffer (); /*! * \brief return number of items worth of space available for writing */ - int space_available () const; + int space_available (); + + /*! + * \brief return size of this buffer in items + */ + int bufsize() const { return d_bufsize; } /*! * \brief return pointer to write buffer. @@ -63,17 +77,26 @@ class gr_buffer { */ void update_write_pointer (int nitems); - - void set_done (bool done) { d_done = done; } + void set_done (bool done); bool done () const { return d_done; } + /*! + * \brief Return the block that writes to this buffer. + */ + gr_block_sptr link() { return gr_block_sptr(d_link); } + + size_t nreaders() const { return d_readers.size(); } + gr_buffer_reader* reader(size_t index) { return d_readers[index]; } + + boost::mutex *mutex() { return &d_mutex; } + // ------------------------------------------------------------------------- private: friend class gr_buffer_reader; - friend gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item); - friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload); + friend gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); + friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link); protected: char *d_base; // base address of buffer @@ -81,8 +104,14 @@ class gr_buffer { private: gr_vmcircbuf *d_vmcircbuf; size_t d_sizeof_item; // in bytes - unsigned int d_write_index; // in items [0,d_bufsize) std::vector<gr_buffer_reader *> d_readers; + boost::weak_ptr<gr_block> d_link; // block that writes to this buffer + + // + // The mutex protects d_write_index, d_done and the d_read_index's in the buffer readers. + // + boost::mutex d_mutex; + unsigned int d_write_index; // in items [0,d_bufsize) bool d_done; unsigned @@ -116,11 +145,15 @@ class gr_buffer { * * 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. */ - gr_buffer (int nitems, size_t sizeof_item); + gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); /*! * \brief disassociate \p reader from this buffer @@ -132,8 +165,10 @@ class gr_buffer { /*! * \brief create a new gr_buffer_reader and attach it to buffer \p buf * \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_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload); +gr_buffer_reader_sptr +gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link=gr_block_sptr()); //! returns # of gr_buffers currently allocated long gr_buffer_ncurrently_allocated (); @@ -147,8 +182,10 @@ long gr_buffer_ncurrently_allocated (); */ class gr_buffer_reader { - public: + + typedef gr_buffer::scoped_lock scoped_lock; + ~gr_buffer_reader (); /*! @@ -183,19 +220,29 @@ class gr_buffer_reader { void set_done (bool done) { d_buffer->set_done (done); } bool done () const { return d_buffer->done (); } + boost::mutex *mutex() { return d_buffer->mutex(); } + + + /*! + * \brief Return the block that reads via this reader. + */ + gr_block_sptr link() { return gr_block_sptr(d_link); } + // ------------------------------------------------------------------------- private: friend class gr_buffer; - friend gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload); + friend gr_buffer_reader_sptr + gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link); gr_buffer_sptr d_buffer; unsigned int d_read_index; // in items [0,d->buffer.d_bufsize) + boost::weak_ptr<gr_block> d_link; // block that reads via this buffer reader //! constructor is private. Use gr_buffer::add_reader to create instances - gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index); + gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link); }; //! returns # of gr_buffer_readers currently allocated diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.i b/gnuradio-core/src/lib/runtime/gr_buffer.i index 38e1d945d..4c1c5afae 100644 --- a/gnuradio-core/src/lib/runtime/gr_buffer.i +++ b/gnuradio-core/src/lib/runtime/gr_buffer.i @@ -26,14 +26,14 @@ typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr; %rename(buffer) gr_make_buffer; %ignore gr_buffer; -gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item); +gr_buffer_sptr gr_make_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); class gr_buffer { public: ~gr_buffer (); private: - gr_buffer (int nitems, size_t sizeof_item); + gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link); }; @@ -43,7 +43,7 @@ typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr; %ignore gr_buffer_reader; %rename(buffer_add_reader) gr_buffer_add_reader; -gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload); +gr_buffer_reader_sptr gr_buffer_add_reader (gr_buffer_sptr buf, int nzero_preload, gr_block_sptr link); class gr_buffer_reader { public: @@ -51,7 +51,7 @@ class gr_buffer_reader { private: friend class gr_buffer; - gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index); + gr_buffer_reader (gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link); }; diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc index aa1aa8353..031eb6dfd 100644 --- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc +++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc @@ -33,6 +33,11 @@ #define GR_FLAT_FLOWGRAPH_DEBUG 0 +// 32Kbyte buffer size between blocks +#define GR_FIXED_BUFFER_SIZE (32*(1L<<10)) + +static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE; + gr_flat_flowgraph_sptr gr_make_flat_flowgraph() { @@ -54,7 +59,7 @@ gr_flat_flowgraph::setup_connections() // Assign block details to blocks for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) - make_gr_block_sptr(*p)->set_detail(allocate_block_detail(*p)); + cast_to_block_sptr(*p)->set_detail(allocate_block_detail(*p)); // Connect inputs to outputs for each block for(gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) @@ -84,11 +89,15 @@ gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block) gr_buffer_sptr gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port) { - gr_block_sptr grblock = make_gr_block_sptr(block); + gr_block_sptr grblock = cast_to_block_sptr(block); if (!grblock) throw std::runtime_error("allocate_buffer found non-gr_block"); int item_size = block->output_signature()->sizeof_stream_item(port); - int nitems = s_fixed_buffer_size/item_size; + + // *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() @@ -99,7 +108,7 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port) gr_basic_block_vector_t blocks = calc_downstream_blocks(block, port); for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { - gr_block_sptr dgrblock = make_gr_block_sptr(*p); + gr_block_sptr dgrblock = cast_to_block_sptr(*p); if (!dgrblock) throw std::runtime_error("allocate_buffer found non-gr_block"); @@ -109,13 +118,13 @@ gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port) nitems = std::max(nitems, static_cast<int>(2*(decimation*multiple+history))); } - return gr_make_buffer(nitems, item_size); + return gr_make_buffer(nitems, item_size, grblock); } void gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block) { - gr_block_sptr grblock = make_gr_block_sptr(block); + gr_block_sptr grblock = cast_to_block_sptr(block); if (!grblock) throw std::runtime_error("connect_block_inputs found non-gr_block"); @@ -130,7 +139,7 @@ gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block) int dst_port = e->dst().port(); int src_port = e->src().port(); gr_basic_block_sptr src_block = e->src().block(); - gr_block_sptr src_grblock = make_gr_block_sptr(src_block); + gr_block_sptr src_grblock = cast_to_block_sptr(src_block); if (!src_grblock) throw std::runtime_error("connect_block_inputs found non-gr_block"); gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port); @@ -138,7 +147,7 @@ gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block) if (GR_FLAT_FLOWGRAPH_DEBUG) std::cout << "Setting input " << dst_port << " from edge " << (*e) << std::endl; - detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, grblock->history()-1)); + detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, grblock->history()-1, grblock)); } } @@ -149,7 +158,7 @@ gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) // by flattening will need one; existing blocks still in the new flowgraph will // already have one. for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { - gr_block_sptr block = make_gr_block_sptr(*p); + gr_block_sptr block = cast_to_block_sptr(*p); if (!block->detail()) { if (GR_FLAT_FLOWGRAPH_DEBUG) @@ -177,7 +186,7 @@ gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) if (GR_FLAT_FLOWGRAPH_DEBUG) std::cout << "not in new edge list" << std::endl; // zero the buffer reader on RHS of old edge - gr_block_sptr block(make_gr_block_sptr(old_edge->dst().block())); + gr_block_sptr block(cast_to_block_sptr(old_edge->dst().block())); int port = old_edge->dst().port(); block->detail()->set_input(port, gr_buffer_reader_sptr()); } @@ -189,7 +198,7 @@ gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) // Now connect inputs to outputs, reusing old buffer readers if they exist for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { - gr_block_sptr block = make_gr_block_sptr(*p); + gr_block_sptr block = cast_to_block_sptr(*p); if (GR_FLAT_FLOWGRAPH_DEBUG) std::cout << "merge: merging " << (*p) << "..."; @@ -208,7 +217,7 @@ gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) gr_edge edge = calc_upstream_edge(*p, i); // Fish out old buffer reader and see if it matches correct buffer from edge list - gr_block_sptr src_block = make_gr_block_sptr(edge.src().block()); + gr_block_sptr src_block = cast_to_block_sptr(edge.src().block()); gr_block_detail_sptr src_detail = src_block->detail(); gr_buffer_sptr src_buffer = src_detail->output(edge.src().port()); gr_buffer_reader_sptr old_reader; @@ -225,7 +234,7 @@ gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg) std::cout << "needs a new reader" << std::endl; // Create new buffer reader and assign - detail->set_input(i, gr_buffer_add_reader(src_buffer, block->history()-1)); + detail->set_input(i, gr_buffer_add_reader(src_buffer, block->history()-1, block)); } } } @@ -248,7 +257,7 @@ void gr_flat_flowgraph::dump() for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) { std::cout << " block: " << (*p) << std::endl; - gr_block_detail_sptr detail = make_gr_block_sptr(*p)->detail(); + gr_block_detail_sptr detail = cast_to_block_sptr(*p)->detail(); std::cout << " detail @" << detail << ":" << std::endl; int ni = detail->ninputs(); @@ -269,3 +278,14 @@ void gr_flat_flowgraph::dump() } } + +gr_block_vector_t +gr_flat_flowgraph::make_block_vector(gr_basic_block_vector_t &blocks) +{ + gr_block_vector_t result; + for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { + result.push_back(cast_to_block_sptr(*p)); + } + + return result; +} diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h index 184ee4514..673c4df16 100644 --- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h +++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h @@ -26,9 +26,6 @@ #include <gr_flowgraph.h> #include <gr_block.h> -// 32Kbyte buffer size between blocks -#define GR_FIXED_BUFFER_SIZE (32*(1L<<10)) - // Create a shared pointer to a heap allocated gr_flat_flowgraph // (types defined in gr_runtime_types.h) gr_flat_flowgraph_sptr gr_make_flat_flowgraph(); @@ -55,10 +52,14 @@ public: void dump(); + /*! + * Make a vector of gr_block from a vector of gr_basic_block + */ + static gr_block_vector_t make_block_vector(gr_basic_block_vector_t &blocks); + private: gr_flat_flowgraph(); - static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE; gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block); gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port); void connect_block_inputs(gr_basic_block_sptr block); diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_flowgraph.h index c97a50782..fc407e72b 100644 --- a/gnuradio-core/src/lib/runtime/gr_flowgraph.h +++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.h @@ -122,6 +122,9 @@ public: // Return vector of connected blocks gr_basic_block_vector_t calc_used_blocks(); + // Return toplogically sorted vector of blocks. All the sources come first. + gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks); + // Return vector of vectors of disjointly connected blocks, topologically // sorted. std::vector<gr_basic_block_vector_t> partition(); @@ -149,7 +152,6 @@ private: gr_basic_block_vector_t calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); void reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); gr_basic_block_vector_t calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks); - gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks); gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks); bool source_p(gr_basic_block_sptr block); void topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output); diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc index 32cac2ea8..a026851d2 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc @@ -303,7 +303,7 @@ gr_hier_block2_detail::resolve_endpoint(const gr_endpoint &endp, bool is_input) std::stringstream msg; // Check if endpoint is a leaf node - if (make_gr_block_sptr(endp.block())) + if (cast_to_block_sptr(endp.block())) return endp; // Check if endpoint is a hierarchical block diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_scheduler.cc new file mode 100644 index 000000000..e4d8b3dd9 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler.cc @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_scheduler.h> + +gr_scheduler::gr_scheduler(gr_flat_flowgraph_sptr ffg) +{ +} + +gr_scheduler::~gr_scheduler() +{ +} diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler.h b/gnuradio-core/src/lib/runtime/gr_scheduler.h new file mode 100644 index 000000000..13bc1ff14 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GR_SCHEDULER_H +#define INCLUDED_GR_SCHEDULER_H + +#include <boost/utility.hpp> +#include <gr_block.h> +#include <gr_flat_flowgraph.h> + + +class gr_scheduler; +typedef boost::shared_ptr<gr_scheduler> gr_scheduler_sptr; + + +/*! + * \brief Abstract scheduler that takes a flattened flow graph and runs it. + * + * Preconditions: details, buffers and buffer readers have been assigned. + */ +class gr_scheduler : boost::noncopyable +{ + +public: + /*! + * \brief Construct a scheduler and begin evaluating the graph. + * + * The scheduler will continue running until all blocks until they + * report that they are done or the stop method is called. + */ + gr_scheduler(gr_flat_flowgraph_sptr ffg); + + virtual ~gr_scheduler(); + + /*! + * \brief Tell the scheduler to stop executing. + */ + virtual void stop() = 0; + + /*! + * \brief Block until the graph is done. + */ + virtual void wait() = 0; +}; + +#endif /* INCLUDED_GR_SCHEDULER_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc new file mode 100644 index 000000000..fefc0dc70 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_scheduler_sts.h> +#include <gr_single_threaded_scheduler.h> +#include <gruel/thread_body_wrapper.h> + +class sts_container +{ + gr_block_vector_t d_blocks; + +public: + + sts_container(gr_block_vector_t blocks) + : d_blocks(blocks) {} + + void operator()() + { + gr_make_single_threaded_scheduler(d_blocks)->run(); + } +}; + + +gr_scheduler_sptr +gr_scheduler_sts::make(gr_flat_flowgraph_sptr ffg) +{ + return gr_scheduler_sptr(new gr_scheduler_sts(ffg)); +} + +gr_scheduler_sts::gr_scheduler_sts(gr_flat_flowgraph_sptr ffg) + : gr_scheduler(ffg) +{ + // Split the flattened flow graph into discrete partitions, each + // of which is topologically sorted. + + std::vector<gr_basic_block_vector_t> graphs = ffg->partition(); + + // For each partition, create a thread to evaluate it using + // an instance of the gr_single_threaded_scheduler + + for (std::vector<gr_basic_block_vector_t>::iterator p = graphs.begin(); + p != graphs.end(); p++) { + + gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(*p); + d_threads.create_thread( + gruel::thread_body_wrapper<sts_container>(sts_container(blocks), + "single-threaded-scheduler")); + } +} + +gr_scheduler_sts::~gr_scheduler_sts() +{ + stop(); +} + +void +gr_scheduler_sts::stop() +{ + d_threads.interrupt_all(); +} + +void +gr_scheduler_sts::wait() +{ + d_threads.join_all(); +} diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h new file mode 100644 index 000000000..4cf835156 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_sts.h @@ -0,0 +1,62 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_SCHEDULER_STS_H +#define INCLUDED_GR_SCHEDULER_STS_H + +#include <gr_scheduler.h> +#include <gruel/thread_group.h> + +/*! + * \brief Concrete scheduler that uses the single_threaded_scheduler + */ +class gr_scheduler_sts : public gr_scheduler +{ + gruel::thread_group d_threads; + +protected: + /*! + * \brief Construct a scheduler and begin evaluating the graph. + * + * The scheduler will continue running until all blocks until they + * report that they are done or the stop method is called. + */ + gr_scheduler_sts(gr_flat_flowgraph_sptr ffg); + +public: + static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg); + + ~gr_scheduler_sts(); + + /*! + * \brief Tell the scheduler to stop executing. + */ + void stop(); + + /*! + * \brief Block until the graph is done. + */ + void wait(); +}; + + + + +#endif /* INCLUDED_GR_SCHEDULER_STS_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_thread.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_thread.cc deleted file mode 100644 index 07bd60500..000000000 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_thread.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_scheduler_thread.h> -#include <iostream> -#include <stdio.h> - -#ifdef HAVE_SIGNAL_H -#include <signal.h> -#endif - -#define GR_SCHEDULER_THREAD_DEBUG 0 - -gr_scheduler_thread::gr_scheduler_thread(gr_block_vector_t graph) : - omni_thread(NULL, PRIORITY_NORMAL), - d_sts(gr_make_single_threaded_scheduler(graph)) -{ -} - -gr_scheduler_thread::~gr_scheduler_thread() -{ -} - -void gr_scheduler_thread::start() -{ - if (GR_SCHEDULER_THREAD_DEBUG) - std::cout << "gr_scheduler_thread::start() " - << this << std::endl; - start_undetached(); -} - -void * -gr_scheduler_thread::run_undetached(void *arg) -{ - // This is the first code to run in the new thread context. - - /* - * In general, on a *nix system, any thread of a process can receive - * any asynchronous signal. - * - * http://www.serpentine.com/blog/threads-faq/mixing-threads-and-signals-unix/ - * http://www.linuxjournal.com/article/2121 - * - * We really don't want to be handling asynchronous signals such - * as SIGINT and SIGHUP here. We mask them off in the signal - * processing threads so that they'll get handled by the mainline - * thread. We leave the synchronous signals SIGQUIT, SIGBUS, - * SIGILL, SIGSEGV etc alone - * - * FIXME? It might be better to mask them all off in the parent - * thread then dedicate a single thread to handling all signals - * using sigwait. - */ -#if defined(HAVE_PTHREAD_SIGMASK) || defined(HAVE_SIGPROCMASK) - sigset_t old_set; - sigset_t new_set; - int r; - sigemptyset(&new_set); - sigaddset(&new_set, SIGINT); - sigaddset(&new_set, SIGHUP); - sigaddset(&new_set, SIGPIPE); - sigaddset(&new_set, SIGALRM); - sigaddset(&new_set, SIGCHLD); - -#ifdef HAVE_PTHREAD_SIGMASK - r = pthread_sigmask(SIG_BLOCK, &new_set, &old_set); - if (r != 0) - perror("pthread_sigmask"); -#else - r = sigprocmask(SIG_BLOCK, &new_set, &old_set); - if (r != 0) - perror("sigprocmask"); -#endif -#endif - // Run the single-threaded scheduler - d_sts->run(); - return 0; -} - -void -gr_scheduler_thread::stop() -{ - if (0 && GR_SCHEDULER_THREAD_DEBUG) // FIXME not safe to call from signal handler - std::cout << "gr_scheduler_thread::stop() " - << this << std::endl; - d_sts->stop(); -} diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_thread.h b/gnuradio-core/src/lib/runtime/gr_scheduler_thread.h deleted file mode 100644 index 89daba403..000000000 --- a/gnuradio-core/src/lib/runtime/gr_scheduler_thread.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_GR_SCHEDULER_THREAD_H -#define INCLUDED_GR_SCHEDULER_THREAD_H - -#include <omnithread.h> -#include <gr_single_threaded_scheduler.h> -#include <gr_block.h> - -// omnithread calls delete on itself after thread exits, so can't use shared ptr -class gr_scheduler_thread; -typedef std::vector<gr_scheduler_thread *> gr_scheduler_thread_vector_t; -typedef gr_scheduler_thread_vector_t::iterator gr_scheduler_thread_viter_t; - -/*! - *\brief A single thread of execution for the scheduler - * - * \ingroup internal - * This class implements a single thread that runs undetached, and - * invokes the single-threaded block scheduler. The runtime makes - * one of these for each distinct partition of a flowgraph and runs - * them in parallel. - * - */ -class gr_scheduler_thread : public omni_thread -{ -private: - gr_single_threaded_scheduler_sptr d_sts; - -public: - gr_scheduler_thread(gr_block_vector_t graph); - ~gr_scheduler_thread(); - - virtual void *run_undetached(void *arg); - void start(); - void stop(); -}; - -#endif /* INCLUDED_GR_SCHEDULER_THREAD_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc new file mode 100644 index 000000000..af0338570 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc @@ -0,0 +1,95 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_scheduler_tpb.h> +#include <gr_tpb_thread_body.h> +#include <gruel/thread_body_wrapper.h> +#include <sstream> + +/* + * You know, a lambda expression would be sooo much easier... + */ +class tpb_container +{ + gr_block_sptr d_block; + +public: + tpb_container(gr_block_sptr block) : d_block(block) {} + + void operator()() + { + gr_tpb_thread_body body(d_block); + } +}; + + +gr_scheduler_sptr +gr_scheduler_tpb::make(gr_flat_flowgraph_sptr ffg) +{ + return gr_scheduler_sptr(new gr_scheduler_tpb(ffg)); +} + +gr_scheduler_tpb::gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg) + : gr_scheduler(ffg) +{ + // Get a topologically sorted vector of all the blocks in use. + // Being topologically sorted probably isn't going to matter, but + // there's a non-zero chance it might help... + + gr_basic_block_vector_t used_blocks = ffg->calc_used_blocks(); + used_blocks = ffg->topological_sort(used_blocks); + gr_block_vector_t blocks = gr_flat_flowgraph::make_block_vector(used_blocks); + + // Ensure that the done flag is clear on all blocks + + for (size_t i = 0; i < blocks.size(); i++){ + blocks[i]->detail()->set_done(false); + } + + // Fire off a thead for each block + + for (size_t i = 0; i < blocks.size(); i++){ + std::stringstream name; + name << "thread-per-block[" << i << "]: " << blocks[i]; + d_threads.create_thread( + gruel::thread_body_wrapper<tpb_container>(tpb_container(blocks[i]), name.str())); + } +} + +gr_scheduler_tpb::~gr_scheduler_tpb() +{ + stop(); +} + +void +gr_scheduler_tpb::stop() +{ + d_threads.interrupt_all(); +} + +void +gr_scheduler_tpb::wait() +{ + d_threads.join_all(); +} diff --git a/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h new file mode 100644 index 000000000..16a0c0204 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_SCHEDULER_TPB_H +#define INCLUDED_GR_SCHEDULER_TPB_H + +#include <gr_scheduler.h> +#include <gruel/thread_group.h> + +/*! + * \brief Concrete scheduler that uses a kernel thread-per-block + */ +class gr_scheduler_tpb : public gr_scheduler +{ + gruel::thread_group d_threads; + +protected: + /*! + * \brief Construct a scheduler and begin evaluating the graph. + * + * The scheduler will continue running until all blocks until they + * report that they are done or the stop method is called. + */ + gr_scheduler_tpb(gr_flat_flowgraph_sptr ffg); + +public: + static gr_scheduler_sptr make(gr_flat_flowgraph_sptr ffg); + + ~gr_scheduler_tpb(); + + /*! + * \brief Tell the scheduler to stop executing. + */ + void stop(); + + /*! + * \brief Block until the graph is done. + */ + void wait(); +}; + + +#endif /* INCLUDED_GR_SCHEDULER_TPB_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc index b2fbdb73b..7f1b40641 100644 --- a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc +++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc @@ -28,6 +28,7 @@ #include <gr_block.h> #include <gr_block_detail.h> #include <gr_buffer.h> +#include <boost/thread.hpp> #include <iostream> #include <limits> #include <assert.h> @@ -44,14 +45,6 @@ static int which_scheduler = 0; - -std::ostream& -operator << (std::ostream& os, const gr_block *m) -{ - os << "<gr_block " << m->name() << " (" << m->unique_id() << ")>"; - return os; -} - gr_single_threaded_scheduler_sptr gr_make_single_threaded_scheduler (const std::vector<gr_block_sptr> &blocks) { @@ -162,6 +155,9 @@ gr_single_threaded_scheduler::main_loop () nalive = d_blocks.size (); while (d_enabled && nalive > 0){ + if (boost::this_thread::interruption_requested()) + break; + gr_block *m = d_blocks[bi].get (); gr_block_detail *d = m->detail().get (); diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc index 3c8e28f70..09e46dfbb 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc @@ -27,7 +27,6 @@ #include <unistd.h> #include <gr_top_block.h> #include <gr_top_block_impl.h> -#include <gr_top_block_impl_sts.h> #include <gr_io_signature.h> #include <iostream> @@ -43,7 +42,7 @@ gr_top_block::gr_top_block(const std::string &name) gr_make_io_signature(0,0,0)) { - d_impl = new gr_top_block_impl_sts(this); + d_impl = new gr_top_block_impl(this); } gr_top_block::~gr_top_block() diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc index 591437938..50d480d00 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.cc @@ -27,21 +27,58 @@ #include <gr_top_block.h> #include <gr_top_block_impl.h> #include <gr_flat_flowgraph.h> -#include <gr_scheduler_thread.h> -#include <gr_local_sighandler.h> +#include <gr_scheduler_sts.h> +#include <gr_scheduler_tpb.h> #include <stdexcept> #include <iostream> #include <string.h> #include <unistd.h> +#include <stdlib.h> #define GR_TOP_BLOCK_IMPL_DEBUG 0 + +typedef gr_scheduler_sptr (*scheduler_maker)(gr_flat_flowgraph_sptr ffg); + +static struct scheduler_table { + const char *name; + scheduler_maker f; +} scheduler_table[] = { + { "TPB", gr_scheduler_tpb::make }, // first entry is default + { "STS", gr_scheduler_sts::make } +}; + +static gr_scheduler_sptr +make_scheduler(gr_flat_flowgraph_sptr ffg) +{ + static scheduler_maker factory = 0; + + if (factory == 0){ + char *v = getenv("GR_SCHEDULER"); + if (!v) + factory = scheduler_table[0].f; // use default + else { + for (size_t i = 0; i < sizeof(scheduler_table)/sizeof(scheduler_table[0]); i++){ + if (strcmp(v, scheduler_table[i].name) == 0){ + factory = scheduler_table[i].f; + break; + } + } + if (factory == 0){ + std::cerr << "warning: Invalid GR_SCHEDULER environment variable value \"" + << v << "\". Using \"" << scheduler_table[0].name << "\"\n"; + factory = scheduler_table[0].f; + } + } + } + return factory(ffg); +} + + gr_top_block_impl::gr_top_block_impl(gr_top_block *owner) - : d_owner(owner), - d_running(false), - d_ffg(), - d_lock_count(0) + : d_owner(owner), d_ffg(), + d_state(IDLE), d_lock_count(0) { } @@ -53,14 +90,13 @@ gr_top_block_impl::~gr_top_block_impl() void gr_top_block_impl::start() { - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "start: entered " << this << std::endl; + gr_lock_guard l(d_mutex); - if (d_running) + if (d_state != IDLE) throw std::runtime_error("top_block::start: top block already running or wait() not called after previous stop()"); if (d_lock_count > 0) - throw std::runtime_error("top_block::start: can't call start with flow graph locked"); + throw std::runtime_error("top_block::start: can't start with flow graph locked"); // Create new flat flow graph by flattening hierarchy d_ffg = d_owner->flatten(); @@ -69,77 +105,71 @@ gr_top_block_impl::start() d_ffg->validate(); d_ffg->setup_connections(); - // Execute scheduler threads - start_threads(); - d_running = true; + d_scheduler = make_scheduler(d_ffg); + d_state = RUNNING; } +void +gr_top_block_impl::stop() +{ + if (d_scheduler) + d_scheduler->stop(); +} + + +void +gr_top_block_impl::wait() +{ + if (d_scheduler) + d_scheduler->wait(); + + d_state = IDLE; +} // N.B. lock() and unlock() cannot be called from a flow graph thread or // deadlock will occur when reconfiguration happens void gr_top_block_impl::lock() { - omni_mutex_lock lock(d_reconf); + gr_lock_guard lock(d_mutex); d_lock_count++; - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "runtime: locked, count = " << d_lock_count << std::endl; } void gr_top_block_impl::unlock() { - omni_mutex_lock lock(d_reconf); + gr_lock_guard lock(d_mutex); + if (d_lock_count <= 0){ d_lock_count = 0; // fix it, then complain throw std::runtime_error("unpaired unlock() call"); } d_lock_count--; - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "unlock: unlocked, count = " << d_lock_count << std::endl; + if (d_lock_count > 0 || d_state == IDLE) // nothing to do + return; - if (d_lock_count == 0) { - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "unlock: restarting flowgraph" << std::endl; - restart(); - } + restart(); } +/* + * restart is called with d_mutex held + */ void gr_top_block_impl::restart() { - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "restart: entered" << std::endl; - - if (!d_running) - return; // nothing to do - - // Stop scheduler threads and wait for completion - stop(); + stop(); // Stop scheduler and wait for completion wait(); - if (GR_TOP_BLOCK_IMPL_DEBUG) - std::cout << "restart: threads stopped" << std::endl; // Create new simple flow graph gr_flat_flowgraph_sptr new_ffg = d_owner->flatten(); new_ffg->validate(); // check consistency, sanity, etc - - if (GR_TOP_BLOCK_IMPL_DEBUG) { - std::cout << std::endl << "*** Existing flat flowgraph @" << d_ffg << ":" << std::endl; - d_ffg->dump(); - } new_ffg->merge_connections(d_ffg); // reuse buffers, etc - - if (GR_TOP_BLOCK_IMPL_DEBUG) { - std::cout << std::endl << "*** New flat flowgraph after merge @" << new_ffg << ":" << std::endl; - new_ffg->dump(); - } - d_ffg = new_ffg; - start_threads(); - d_running = true; + // Create a new scheduler to execute it + d_scheduler = make_scheduler(d_ffg); + d_state = RUNNING; } void @@ -148,14 +178,3 @@ gr_top_block_impl::dump() if (d_ffg) d_ffg->dump(); } - -gr_block_vector_t -gr_top_block_impl::make_gr_block_vector(gr_basic_block_vector_t blocks) -{ - gr_block_vector_t result; - for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) { - result.push_back(make_gr_block_sptr(*p)); - } - - return result; -} diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h index 869f788ef..35fb44ef9 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block_impl.h @@ -23,7 +23,11 @@ #ifndef INCLUDED_GR_TOP_BLOCK_IMPL_H #define INCLUDED_GR_TOP_BLOCK_IMPL_H -#include <gr_scheduler_thread.h> +#include <gr_scheduler.h> +#include <boost/thread.hpp> + +typedef boost::mutex gr_mutex; // FIXME move these elsewhere +typedef boost::lock_guard<boost::mutex> gr_lock_guard; /*! *\brief Abstract implementation details of gr_top_block @@ -37,16 +41,16 @@ class gr_top_block_impl { public: gr_top_block_impl(gr_top_block *owner); - virtual ~gr_top_block_impl(); + ~gr_top_block_impl(); // Create and start scheduler threads - virtual void start(); + void start(); // Signal scheduler threads to stop - virtual void stop() = 0; + void stop(); // Wait for scheduler threads to exit - virtual void wait() = 0; + void wait(); // Lock the top block to allow reconfiguration void lock(); @@ -59,22 +63,16 @@ public: protected: + enum tb_state { IDLE, RUNNING }; + gr_top_block *d_owner; - bool d_running; gr_flat_flowgraph_sptr d_ffg; + gr_scheduler_sptr d_scheduler; - omni_mutex d_reconf; // protects d_lock_count + gr_mutex d_mutex; // protects d_state and d_lock_count + tb_state d_state; int d_lock_count; - - virtual void start_threads() = 0; - -/*! - * Make a vector of gr_block from a vector of gr_basic_block - * - * Pass-by-value to avoid problem with possible asynchronous modification - */ - static gr_block_vector_t make_gr_block_vector(gr_basic_block_vector_t blocks); - + private: void restart(); }; diff --git a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc deleted file mode 100644 index b3e9da627..000000000 --- a/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2007,2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3, or (at your option) - * any later version. - * - * GNU Radio is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_top_block.h> -#include <gr_top_block_impl_sts.h> -#include <gr_flat_flowgraph.h> -#include <gr_scheduler_thread.h> -#include <gr_local_sighandler.h> - -#include <stdexcept> -#include <iostream> -#include <string.h> -#include <unistd.h> - -#define GR_TOP_BLOCK_IMPL_STS_DEBUG 0 - -static gr_top_block_impl *s_impl = 0; - - -// FIXME: This prevents using more than one gr_top_block instance - -static void -runtime_sigint_handler(int signum) -{ - if (GR_TOP_BLOCK_IMPL_STS_DEBUG){ - char *msg = "SIGINT received, calling stop()\n"; - ::write(1, msg, strlen(msg)); // write is OK to call from signal handler - } - - if (s_impl) - s_impl->stop(); -} - -// ---------------------------------------------------------------- - -gr_top_block_impl_sts::gr_top_block_impl_sts(gr_top_block *owner) - : gr_top_block_impl(owner) -{ - if (s_impl) - throw std::logic_error("gr_top_block_impl_sts: multiple simultaneous gr_top_blocks not allowed"); - - s_impl = this; -} - -gr_top_block_impl_sts::~gr_top_block_impl_sts() -{ - s_impl = 0; // don't call delete we don't own these -} - -void -gr_top_block_impl_sts::start_threads() -{ - if (GR_TOP_BLOCK_IMPL_STS_DEBUG) - std::cout << "start_threads: entered" << std::endl; - - d_graphs = d_ffg->partition(); - for (std::vector<gr_basic_block_vector_t>::iterator p = d_graphs.begin(); - p != d_graphs.end(); p++) { - gr_scheduler_thread *thread = new gr_scheduler_thread(make_gr_block_vector(*p)); - d_threads.push_back(thread); - if (GR_TOP_BLOCK_IMPL_STS_DEBUG) - std::cout << "start_threads: starting " << thread << std::endl; - thread->start(); - } -} - -/* - * N.B. as currently implemented, it is possible that this may be - * invoked by the SIGINT handler which is fragile as hell... - */ -void -gr_top_block_impl_sts::stop() -{ - if (GR_TOP_BLOCK_IMPL_STS_DEBUG){ - char *msg = "stop: entered\n"; - ::write(1, msg, strlen(msg)); - } - - for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) { - if (*p) - (*p)->stop(); - } -} - -void -gr_top_block_impl_sts::wait() -{ - if (GR_TOP_BLOCK_IMPL_STS_DEBUG) - std::cout << "wait: entered" << std::endl; - - void *dummy_status; // don't ever dereference this - gr_local_sighandler sigint(SIGINT, runtime_sigint_handler); - - for (gr_scheduler_thread_viter_t p = d_threads.begin(); p != d_threads.end(); p++) { - if (GR_TOP_BLOCK_IMPL_STS_DEBUG) - std::cout << "wait: joining thread " << (*p) << std::endl; - (*p)->join(&dummy_status); // omnithreads will self-delete, so pointer is now dead - (*p) = 0; // FIXME: switch to stl::list and actually remove from container - if (GR_TOP_BLOCK_IMPL_STS_DEBUG) - std::cout << "wait: join returned" << std::endl; - } - - d_threads.clear(); - d_running = false; -} diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc new file mode 100644 index 000000000..02e8deed8 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.cc @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_tpb_detail.h> +#include <gr_block.h> +#include <gr_block_detail.h> +#include <gr_buffer.h> + +/* + * We assume that no worker threads are ever running when the + * graph structure is being manipulated, thus it's safe for us to poke + * around in our neighbors w/o holding any locks. + */ + +void +gr_tpb_detail::notify_upstream(gr_block_detail *d) +{ + // For each of our inputs, tell the guy upstream that we've consumed + // some input, and that he most likely has more output buffer space + // available. + + for (size_t i = 0; i < d->d_input.size(); i++){ + // Can you say, "pointer chasing?" + d->d_input[i]->buffer()->link()->detail()->d_tpb.set_output_changed(); + } +} + +void +gr_tpb_detail::notify_downstream(gr_block_detail *d) +{ + // For each of our outputs, tell the guys downstream that they have + // new input available. + + for (size_t i = 0; i < d->d_output.size(); i++){ + gr_buffer_sptr buf = d->d_output[i]; + for (size_t j = 0, k = buf->nreaders(); j < k; j++) + buf->reader(j)->link()->detail()->d_tpb.set_input_changed(); + } +} + +void +gr_tpb_detail::notify_neighbors(gr_block_detail *d) +{ + notify_downstream(d); + notify_upstream(d); +} diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_detail.h b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h new file mode 100644 index 000000000..9566312dc --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_tpb_detail.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_TPB_DETAIL_H +#define INCLUDED_GR_TPB_DETAIL_H + +#include <boost/thread.hpp> + +class gr_block_detail; + +/*! + * \brief used by thread-per-block scheduler + */ +struct gr_tpb_detail { + typedef boost::unique_lock<boost::mutex> scoped_lock; + + boost::mutex mutex; //< protects all vars + bool input_changed; + boost::condition_variable input_cond; + bool output_changed; + boost::condition_variable output_cond; + + gr_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(gr_block_detail *d); + + //! Called by us to tell all our downstream blocks that their input may have changed. + void notify_downstream(gr_block_detail *d); + + //! Called by us to notify both upstream and downstream + void notify_neighbors(gr_block_detail *d); + + //! Called by us + void clear_changed() + { + scoped_lock guard(mutex); + input_changed = false; + output_changed = false; + } + +private: + + //! Used by notify_downstream + void set_input_changed() + { + scoped_lock guard(mutex); + input_changed = true; + input_cond.notify_one(); + } + + //! Used by notify_upstream + void set_output_changed() + { + scoped_lock guard(mutex); + output_changed = true; + output_cond.notify_one(); + } + +}; + +#endif /* INCLUDED_GR_TPB_DETAIL_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc new file mode 100644 index 000000000..f61e17243 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc @@ -0,0 +1,76 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gr_tpb_thread_body.h> +#include <iostream> + +gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) + : d_exec(block) +{ + // std::cerr << "gr_tpb_thread_body: " << block << std::endl; + + gr_block_detail *d = block->detail().get(); + gr_block_executor::state s; + + while (1){ + d->d_tpb.clear_changed(); + s = d_exec.run_one_iteration(); + + switch(s){ + case gr_block_executor::READY: // Tell neighbors we made progress. + d->d_tpb.notify_neighbors(d); + break; + + case gr_block_executor::READY_NO_OUTPUT: // Notify upstream only + d->d_tpb.notify_upstream(d); + break; + + case gr_block_executor::DONE: // Game over. + d->d_tpb.notify_neighbors(d); + return; + + case gr_block_executor::BLKD_IN: // Wait for input. + { + gr_tpb_detail::scoped_lock guard(d->d_tpb.mutex); + while(!d->d_tpb.input_changed) + d->d_tpb.input_cond.wait(guard); + } + break; + + case gr_block_executor::BLKD_OUT: // Wait for output buffer space. + { + gr_tpb_detail::scoped_lock guard(d->d_tpb.mutex); + while(!d->d_tpb.output_changed) + d->d_tpb.output_cond.wait(guard); + } + break; + + default: + assert(0); + } + } +} + +gr_tpb_thread_body::~gr_tpb_thread_body() +{ +} diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h new file mode 100644 index 000000000..a630b1be9 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_TPB_THREAD_BODY_H +#define INCLUDED_GR_TPB_THREAD_BODY_H + +#include <gr_block_executor.h> +#include <gr_block.h> +#include <gr_block_detail.h> + +/*! + * \brief The body of each thread-per-block thread. + * + * One of these is instantiated in its own thread for each block. The + * constructor turns into the main loop which returns when the block is + * done or is interrupted. + */ + +class gr_tpb_thread_body { + gr_block_executor d_exec; + +public: + gr_tpb_thread_body(gr_block_sptr block); + ~gr_tpb_thread_body(); +}; + + +#endif /* INCLUDED_GR_TPB_THREAD_BODY_H */ diff --git a/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc index ad40f724d..7434cf657 100644 --- a/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc +++ b/gnuradio-core/src/lib/runtime/qa_gr_buffer.cc @@ -52,7 +52,7 @@ t0_body () int nitems = 4000 / sizeof (int); int counter = 0; - gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int))); + gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr())); int last_sa; int sa; @@ -87,8 +87,8 @@ t1_body () int write_counter = 0; int read_counter = 0; - gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int))); - gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0)); + gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr())); + gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr())); int sa; @@ -162,8 +162,8 @@ t2_body () int nitems = (64 * (1L << 10)) / sizeof (int); // 64K worth of ints - gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int))); - gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0)); + gr_buffer_sptr buf(gr_make_buffer (nitems, sizeof (int), gr_block_sptr())); + gr_buffer_reader_sptr r1 (gr_buffer_add_reader (buf, 0, gr_block_sptr())); int read_counter = 0; int write_counter = 0; @@ -229,7 +229,7 @@ t3_body () int nitems = (64 * (1L << 10)) / sizeof (int); static const int N = 5; - gr_buffer_sptr buf (gr_make_buffer (nitems, sizeof (int))); + gr_buffer_sptr buf(gr_make_buffer(nitems, sizeof (int), gr_block_sptr())); gr_buffer_reader_sptr reader[N]; int read_counter[N]; int write_counter = 0; @@ -237,7 +237,7 @@ t3_body () for (int i = 0; i < N; i++){ read_counter[i] = 0; - reader[i] = gr_buffer_add_reader (buf, 0); + reader[i] = gr_buffer_add_reader (buf, 0, gr_block_sptr()); } for (int lc = 0; lc < 1000; lc++){ diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py index 8f5754d65..a3161170a 100644 --- a/gnuradio-core/src/python/gnuradio/gr/top_block.py +++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py @@ -22,6 +22,33 @@ from gnuradio_swig_python import top_block_swig, \ top_block_wait_unlocked, top_block_run_unlocked +#import gnuradio.gr.gr_threading as _threading +import gr_threading as _threading + + +# +# There is no problem that can't be solved with an additional +# level of indirection... +# +# This kludge allows ^C to interrupt top_block.run and top_block.wait +# +class _top_block_waiter(_threading.Thread): + def __init__(self, tb): + _threading.Thread.__init__(self) + self.setDaemon(1) + self.tb = tb + self.event = _threading.Event() + self.start() + + def run(self): + top_block_wait_unlocked(self.tb) + self.event.set() + + def wait(self): + while not self.event.isSet(): + self.event.wait(0.100) + + # # This hack forces a 'has-a' relationship to look like an 'is-a' one. # @@ -48,10 +75,12 @@ class top_block(object): self._tb.stop() def run(self): - top_block_run_unlocked(self._tb) + self.start() + self.wait() def wait(self): - top_block_wait_unlocked(self._tb) + _top_block_waiter(self._tb).wait() + # FIXME: these are duplicated from hier_block2.py; they should really be implemented # in the original C++ class (gr_hier_block2), then they would all be inherited here diff --git a/gnuradio-core/src/tests/Makefile.am b/gnuradio-core/src/tests/Makefile.am index 730de2d19..c6225d972 100644 --- a/gnuradio-core/src/tests/Makefile.am +++ b/gnuradio-core/src/tests/Makefile.am @@ -47,10 +47,12 @@ noinst_PROGRAMS = \ benchmark_vco \ test_runtime \ test_general \ - test_all \ test_filter \ test_vmcircbuf +bin_PROGRAMS = \ + test_all + noinst_SCRIPTS = \ benchmark_dotprod diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am index e20bfafd4..b1780bc6f 100644 --- a/gnuradio-examples/python/Makefile.am +++ b/gnuradio-examples/python/Makefile.am @@ -27,6 +27,7 @@ SUBDIRS = \ dect \ digital \ digital_voice \ + mp-sched \ multi-antenna \ multi_usrp \ network \ diff --git a/gnuradio-examples/python/mp-sched/Makefile.am b/gnuradio-examples/python/mp-sched/Makefile.am new file mode 100644 index 000000000..bd4b4e8d4 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/Makefile.am @@ -0,0 +1,31 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = \ + plot_flops.py \ + run_synthetic.py \ + synthetic.py \ + wfm_rcv_pll_to_wav.py + + +ourdatadir = $(exampledir)/mp-sched +ourdata_DATA = $(EXTRA_DIST) diff --git a/gnuradio-examples/python/mp-sched/perf-data/core-duo.dat b/gnuradio-examples/python/mp-sched/perf-data/core-duo.dat new file mode 100644 index 000000000..064d1e128 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/core-duo.dat @@ -0,0 +1,65 @@ +#D Core Duo 1.83 GHz (T2400) + 1 1 5.273e+07 10.010 10.160 0.060 1.021 2.700000e+10 2.697e+09 + 1 2 5.273e+07 10.410 20.180 0.150 1.953 5.400000e+10 5.187e+09 + 1 3 3.516e+07 10.360 20.030 0.150 1.948 5.400000e+10 5.212e+09 + 1 4 2.637e+07 10.100 20.030 0.100 1.993 5.400000e+10 5.347e+09 + 1 5 2.109e+07 10.140 19.980 0.110 1.981 5.400000e+10 5.325e+09 + 1 6 1.758e+07 10.110 20.030 0.110 1.992 5.400000e+10 5.341e+09 + 1 7 1.507e+07 10.120 20.030 0.110 1.990 5.400000e+10 5.336e+09 + 1 8 1.318e+07 10.060 19.980 0.090 1.995 5.400000e+10 5.368e+09 + 2 1 5.273e+07 10.210 20.130 0.260 1.997 5.400000e+10 5.289e+09 + 2 2 2.637e+07 10.110 20.030 0.140 1.995 5.400000e+10 5.341e+09 + 2 3 1.758e+07 10.120 20.010 0.150 1.992 5.400000e+10 5.336e+09 + 2 4 1.318e+07 10.080 19.990 0.110 1.994 5.400000e+10 5.357e+09 + 2 5 1.055e+07 10.050 19.990 0.090 1.998 5.400000e+10 5.373e+09 + 2 6 8.789e+06 10.050 19.980 0.080 1.996 5.400000e+10 5.373e+09 + 2 7 7.533e+06 10.050 19.970 0.090 1.996 5.400000e+10 5.373e+09 + 2 8 6.592e+06 10.040 19.970 0.090 1.998 5.399999e+10 5.378e+09 + 3 1 3.516e+07 10.630 20.130 0.230 1.915 5.400000e+10 5.080e+09 + 3 2 1.758e+07 10.120 20.020 0.170 1.995 5.400000e+10 5.336e+09 + 3 3 1.172e+07 10.140 20.050 0.130 1.990 5.400000e+10 5.325e+09 + 3 4 8.789e+06 10.070 20.010 0.100 1.997 5.400000e+10 5.362e+09 + 3 5 7.031e+06 10.060 19.980 0.100 1.996 5.400000e+10 5.368e+09 + 3 6 5.859e+06 10.060 20.000 0.100 1.998 5.400000e+10 5.368e+09 + 3 7 5.022e+06 10.050 20.010 0.070 1.998 5.400000e+10 5.373e+09 + 3 8 4.395e+06 10.050 19.990 0.070 1.996 5.400000e+10 5.373e+09 + 4 1 2.637e+07 10.180 20.080 0.240 1.996 5.400000e+10 5.305e+09 + 4 2 1.318e+07 10.140 20.000 0.180 1.990 5.400000e+10 5.325e+09 + 4 3 8.789e+06 10.110 20.020 0.120 1.992 5.400000e+10 5.341e+09 + 4 4 6.592e+06 10.080 20.020 0.090 1.995 5.399999e+10 5.357e+09 + 4 5 5.273e+06 10.050 19.990 0.090 1.998 5.399999e+10 5.373e+09 + 4 6 4.395e+06 10.080 20.010 0.080 1.993 5.400000e+10 5.357e+09 + 4 7 3.767e+06 10.070 20.000 0.080 1.994 5.400000e+10 5.362e+09 + 4 8 3.296e+06 10.050 20.000 0.080 1.998 5.399999e+10 5.373e+09 + 5 1 2.109e+07 11.240 20.080 0.260 1.810 5.400000e+10 4.804e+09 + 5 2 1.055e+07 10.130 19.990 0.150 1.988 5.400000e+10 5.331e+09 + 5 3 7.031e+06 10.100 20.020 0.120 1.994 5.400000e+10 5.347e+09 + 5 4 5.273e+06 10.070 20.000 0.090 1.995 5.399999e+10 5.362e+09 + 5 5 4.219e+06 10.100 20.040 0.090 1.993 5.400000e+10 5.347e+09 + 5 6 3.516e+06 10.080 20.000 0.090 1.993 5.400000e+10 5.357e+09 + 5 7 3.013e+06 10.070 20.000 0.100 1.996 5.399998e+10 5.362e+09 + 5 8 2.637e+06 10.070 20.000 0.090 1.995 5.399998e+10 5.362e+09 + 6 1 1.758e+07 10.220 20.100 0.290 1.995 5.400000e+10 5.284e+09 + 6 2 8.789e+06 10.080 20.010 0.130 1.998 5.400000e+10 5.357e+09 + 6 3 5.859e+06 10.090 20.030 0.120 1.997 5.400000e+10 5.352e+09 + 6 4 4.395e+06 10.100 20.030 0.080 1.991 5.400000e+10 5.347e+09 + 6 5 3.516e+06 10.060 20.020 0.080 1.998 5.400000e+10 5.368e+09 + 6 6 2.930e+06 10.070 20.030 0.090 1.998 5.399999e+10 5.362e+09 + 6 7 2.511e+06 10.070 20.030 0.080 1.997 5.399998e+10 5.362e+09 + 6 8 2.197e+06 10.070 20.010 0.090 1.996 5.399998e+10 5.362e+09 + 7 1 1.507e+07 10.420 20.030 0.260 1.947 5.400000e+10 5.182e+09 + 7 2 7.533e+06 10.100 20.010 0.140 1.995 5.400000e+10 5.347e+09 + 7 3 5.022e+06 10.080 20.020 0.120 1.998 5.400000e+10 5.357e+09 + 7 4 3.767e+06 10.080 20.010 0.100 1.995 5.400000e+10 5.357e+09 + 7 5 3.013e+06 10.070 20.030 0.080 1.997 5.399998e+10 5.362e+09 + 7 6 2.511e+06 10.080 20.010 0.090 1.994 5.399998e+10 5.357e+09 + 7 7 2.152e+06 10.080 20.060 0.070 1.997 5.399999e+10 5.357e+09 + 7 8 1.883e+06 10.070 20.040 0.070 1.997 5.399998e+10 5.362e+09 + 8 1 1.318e+07 10.220 20.080 0.270 1.991 5.400000e+10 5.284e+09 + 8 2 6.592e+06 10.100 20.010 0.140 1.995 5.399999e+10 5.347e+09 + 8 3 4.395e+06 10.110 20.020 0.120 1.992 5.400000e+10 5.341e+09 + 8 4 3.296e+06 10.090 20.040 0.090 1.995 5.399999e+10 5.352e+09 + 8 5 2.637e+06 10.090 20.040 0.090 1.995 5.399998e+10 5.352e+09 + 8 6 2.197e+06 10.070 20.040 0.100 2.000 5.399998e+10 5.362e+09 + 8 7 1.883e+06 10.090 20.050 0.080 1.995 5.399998e+10 5.352e+09 + 8 8 1.648e+06 10.090 20.040 0.090 1.995 5.399999e+10 5.352e+09 diff --git a/gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat b/gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat new file mode 100644 index 000000000..d67dee8e5 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat @@ -0,0 +1,65 @@ +#D Core2 Duo 2.66 GHz (6700) + 1 1 1.406e+08 9.890 10.100 0.230 1.044 7.200000e+10 7.280e+09 + 1 2 1.406e+08 10.400 19.900 0.290 1.941 1.440000e+11 1.385e+10 + 1 3 9.375e+07 11.410 19.950 0.200 1.766 1.440000e+11 1.262e+10 + 1 4 7.031e+07 10.230 19.800 0.230 1.958 1.440000e+11 1.408e+10 + 1 5 5.625e+07 10.640 19.800 0.180 1.878 1.440000e+11 1.353e+10 + 1 6 4.688e+07 10.000 19.780 0.130 1.991 1.440000e+11 1.440e+10 + 1 7 4.018e+07 10.500 19.690 0.180 1.892 1.440000e+11 1.371e+10 + 1 8 3.516e+07 10.020 19.750 0.170 1.988 1.440000e+11 1.437e+10 + 2 1 1.406e+08 10.330 20.000 0.460 1.981 1.440000e+11 1.394e+10 + 2 2 7.031e+07 10.160 19.870 0.270 1.982 1.440000e+11 1.417e+10 + 2 3 4.688e+07 10.210 19.780 0.230 1.960 1.440000e+11 1.410e+10 + 2 4 3.516e+07 10.050 19.730 0.210 1.984 1.440000e+11 1.433e+10 + 2 5 2.812e+07 10.060 19.760 0.170 1.981 1.440000e+11 1.431e+10 + 2 6 2.344e+07 10.030 19.780 0.180 1.990 1.440000e+11 1.436e+10 + 2 7 2.009e+07 10.040 19.820 0.180 1.992 1.440000e+11 1.434e+10 + 2 8 1.758e+07 10.050 19.820 0.180 1.990 1.440000e+11 1.433e+10 + 3 1 9.375e+07 13.140 19.950 0.450 1.553 1.440000e+11 1.096e+10 + 3 2 4.688e+07 10.570 19.840 0.290 1.904 1.440000e+11 1.362e+10 + 3 3 3.125e+07 10.420 19.730 0.280 1.920 1.440000e+11 1.382e+10 + 3 4 2.344e+07 10.120 19.710 0.240 1.971 1.440000e+11 1.423e+10 + 3 5 1.875e+07 10.140 19.750 0.190 1.966 1.440000e+11 1.420e+10 + 3 6 1.562e+07 10.030 19.730 0.190 1.986 1.440000e+11 1.436e+10 + 3 7 1.339e+07 10.020 19.720 0.200 1.988 1.440000e+11 1.437e+10 + 3 8 1.172e+07 9.990 19.720 0.170 1.991 1.440000e+11 1.441e+10 + 4 1 7.031e+07 10.310 19.980 0.460 1.983 1.440000e+11 1.397e+10 + 4 2 3.516e+07 10.300 19.830 0.320 1.956 1.440000e+11 1.398e+10 + 4 3 2.344e+07 10.180 19.780 0.230 1.966 1.440000e+11 1.415e+10 + 4 4 1.758e+07 10.070 19.750 0.220 1.983 1.440000e+11 1.430e+10 + 4 5 1.406e+07 10.090 19.750 0.190 1.976 1.440000e+11 1.427e+10 + 4 6 1.172e+07 10.020 19.720 0.190 1.987 1.440000e+11 1.437e+10 + 4 7 1.004e+07 10.040 19.780 0.190 1.989 1.440000e+11 1.434e+10 + 4 8 8.789e+06 10.000 19.750 0.160 1.991 1.440000e+11 1.440e+10 + 5 1 5.625e+07 11.580 19.930 0.500 1.764 1.440000e+11 1.244e+10 + 5 2 2.812e+07 10.300 19.830 0.320 1.956 1.440000e+11 1.398e+10 + 5 3 1.875e+07 10.240 19.760 0.240 1.953 1.440000e+11 1.406e+10 + 5 4 1.406e+07 10.140 19.880 0.230 1.983 1.440000e+11 1.420e+10 + 5 5 1.125e+07 10.040 19.730 0.200 1.985 1.440000e+11 1.434e+10 + 5 6 9.375e+06 10.030 19.770 0.200 1.991 1.440000e+11 1.436e+10 + 5 7 8.036e+06 10.030 19.780 0.170 1.989 1.440000e+11 1.436e+10 + 5 8 7.031e+06 10.000 19.750 0.180 1.993 1.440000e+11 1.440e+10 + 6 1 4.688e+07 10.340 19.910 0.560 1.980 1.440000e+11 1.393e+10 + 6 2 2.344e+07 10.290 19.770 0.330 1.953 1.440000e+11 1.399e+10 + 6 3 1.562e+07 10.150 19.770 0.270 1.974 1.440000e+11 1.419e+10 + 6 4 1.172e+07 10.170 19.880 0.240 1.978 1.440000e+11 1.416e+10 + 6 5 9.375e+06 10.080 19.780 0.240 1.986 1.440000e+11 1.429e+10 + 6 6 7.812e+06 10.020 19.740 0.220 1.992 1.440000e+11 1.437e+10 + 6 7 6.696e+06 10.050 19.760 0.200 1.986 1.440000e+11 1.433e+10 + 6 8 5.859e+06 10.070 19.750 0.210 1.982 1.440000e+11 1.430e+10 + 7 1 4.018e+07 11.220 19.880 0.530 1.819 1.440000e+11 1.283e+10 + 7 2 2.009e+07 10.280 19.790 0.340 1.958 1.440000e+11 1.401e+10 + 7 3 1.339e+07 10.190 19.760 0.250 1.964 1.440000e+11 1.413e+10 + 7 4 1.004e+07 10.060 19.750 0.240 1.987 1.440000e+11 1.431e+10 + 7 5 8.036e+06 10.070 19.750 0.240 1.985 1.440000e+11 1.430e+10 + 7 6 6.696e+06 10.040 19.810 0.220 1.995 1.440000e+11 1.434e+10 + 7 7 5.740e+06 10.050 19.780 0.210 1.989 1.440000e+11 1.433e+10 + 7 8 5.022e+06 10.010 19.790 0.190 1.996 1.440000e+11 1.439e+10 + 8 1 3.516e+07 10.320 19.900 0.470 1.974 1.440000e+11 1.395e+10 + 8 2 1.758e+07 10.340 19.900 0.320 1.956 1.440000e+11 1.393e+10 + 8 3 1.172e+07 10.130 19.770 0.290 1.980 1.440000e+11 1.422e+10 + 8 4 8.789e+06 10.120 19.780 0.230 1.977 1.440000e+11 1.423e+10 + 8 5 7.031e+06 10.040 19.790 0.200 1.991 1.440000e+11 1.434e+10 + 8 6 5.859e+06 10.050 19.770 0.220 1.989 1.440000e+11 1.433e+10 + 8 7 5.022e+06 10.030 19.800 0.200 1.994 1.440000e+11 1.436e+10 + 8 8 4.395e+06 10.050 19.800 0.210 1.991 1.440000e+11 1.433e+10 diff --git a/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat new file mode 100644 index 000000000..fa182c69a --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat @@ -0,0 +1,257 @@ +#D Dual quad-core Xeon 2.33GHz (Clovertown E5345) + 1 1 1.367e+08 10.980 12.080 0.360 1.133 7.000000e+10 6.375e+09 + 1 2 1.367e+08 12.250 24.310 0.400 2.017 1.400000e+11 1.143e+10 + 1 3 1.367e+08 12.830 36.080 0.580 2.857 2.100000e+11 1.637e+10 + 1 4 1.367e+08 12.600 46.820 0.770 3.777 2.800000e+11 2.222e+10 + 1 5 1.367e+08 12.620 58.850 0.720 4.720 3.500000e+11 2.773e+10 + 1 6 1.367e+08 12.310 69.430 0.860 5.710 4.200000e+11 3.412e+10 + 1 7 1.367e+08 12.720 80.580 0.950 6.410 4.900000e+11 3.852e+10 + 1 8 1.367e+08 12.440 91.530 1.010 7.439 5.600000e+11 4.502e+10 + 1 9 1.367e+08 22.310 102.660 1.080 4.650 6.300000e+11 2.824e+10 + 1 10 1.367e+08 22.610 113.670 1.160 5.079 7.000000e+11 3.096e+10 + 1 11 1.367e+08 22.690 124.730 1.030 5.543 7.700000e+11 3.394e+10 + 1 12 1.367e+08 23.260 136.520 1.030 5.914 8.400000e+11 3.611e+10 + 1 13 1.367e+08 23.330 147.270 1.130 6.361 9.100000e+11 3.901e+10 + 1 14 1.367e+08 24.110 158.070 1.010 6.598 9.800000e+11 4.065e+10 + 1 15 1.367e+08 25.380 168.370 1.080 6.677 1.050000e+12 4.137e+10 + 1 16 1.367e+08 26.660 179.130 1.250 6.766 1.120000e+12 4.201e+10 + 2 1 1.367e+08 11.190 23.330 0.420 2.122 1.400000e+11 1.251e+10 + 2 2 1.367e+08 12.650 46.350 0.940 3.738 2.800000e+11 2.213e+10 + 2 3 1.367e+08 12.510 69.010 0.980 5.595 4.200000e+11 3.357e+10 + 2 4 1.367e+08 13.250 89.330 0.890 6.809 5.600000e+11 4.226e+10 + 2 5 1.367e+08 22.540 113.580 1.150 5.090 7.000000e+11 3.106e+10 + 2 6 1.367e+08 22.940 135.790 1.260 5.974 8.400000e+11 3.662e+10 + 2 7 1.367e+08 24.250 158.360 1.520 6.593 9.800000e+11 4.041e+10 + 2 8 1.367e+08 26.610 179.840 1.490 6.814 1.120000e+12 4.209e+10 + 2 9 1.215e+08 26.860 179.400 1.540 6.736 1.120000e+12 4.170e+10 + 2 10 1.094e+08 26.350 178.740 1.430 6.838 1.120000e+12 4.250e+10 + 2 11 9.943e+07 25.790 177.910 1.350 6.951 1.120000e+12 4.343e+10 + 2 12 9.115e+07 25.200 176.980 1.460 7.081 1.120000e+12 4.444e+10 + 2 13 8.413e+07 24.840 177.320 1.260 7.189 1.120000e+12 4.509e+10 + 2 14 7.812e+07 24.450 176.920 1.130 7.282 1.120000e+12 4.581e+10 + 2 15 7.292e+07 24.280 177.400 1.140 7.353 1.120000e+12 4.613e+10 + 2 16 6.836e+07 23.830 176.290 1.100 7.444 1.120000e+12 4.700e+10 + 3 1 1.367e+08 11.360 34.790 0.930 3.144 2.100000e+11 1.849e+10 + 3 2 1.367e+08 12.560 68.800 1.400 5.589 4.200000e+11 3.344e+10 + 3 3 1.367e+08 22.310 103.250 1.310 4.687 6.300000e+11 2.824e+10 + 3 4 1.367e+08 22.940 136.120 1.500 5.999 8.400000e+11 3.662e+10 + 3 5 1.367e+08 25.240 168.550 1.790 6.749 1.050000e+12 4.160e+10 + 3 6 1.215e+08 26.800 178.710 1.610 6.728 1.120000e+12 4.179e+10 + 3 7 1.042e+08 26.090 178.710 1.490 6.907 1.120000e+12 4.293e+10 + 3 8 9.115e+07 25.420 178.140 1.360 7.061 1.120000e+12 4.406e+10 + 3 9 8.102e+07 24.680 177.260 1.410 7.239 1.120000e+12 4.538e+10 + 3 10 7.292e+07 24.270 176.830 1.390 7.343 1.120000e+12 4.615e+10 + 3 11 6.629e+07 23.890 177.060 1.240 7.463 1.120000e+12 4.688e+10 + 3 12 6.076e+07 23.620 176.290 1.300 7.519 1.120000e+12 4.742e+10 + 3 13 5.609e+07 23.340 176.780 1.230 7.627 1.120000e+12 4.799e+10 + 3 14 5.208e+07 23.140 176.330 1.300 7.676 1.120000e+12 4.840e+10 + 3 15 4.861e+07 23.100 176.940 1.080 7.706 1.120000e+12 4.848e+10 + 3 16 4.557e+07 22.850 176.120 1.060 7.754 1.120000e+12 4.902e+10 + 4 1 1.367e+08 11.440 45.520 1.080 4.073 2.800000e+11 2.448e+10 + 4 2 1.367e+08 12.410 90.020 1.440 7.370 5.600000e+11 4.512e+10 + 4 3 1.367e+08 23.060 135.570 1.600 5.948 8.400000e+11 3.643e+10 + 4 4 1.367e+08 26.720 179.780 1.880 6.799 1.120000e+12 4.192e+10 + 4 5 1.094e+08 26.280 178.110 1.890 6.849 1.120000e+12 4.262e+10 + 4 6 9.115e+07 25.250 177.280 1.700 7.088 1.120000e+12 4.436e+10 + 4 7 7.812e+07 24.880 177.830 1.570 7.211 1.120000e+12 4.502e+10 + 4 8 6.836e+07 24.150 177.240 1.350 7.395 1.120000e+12 4.638e+10 + 4 9 6.076e+07 23.730 176.590 1.370 7.499 1.120000e+12 4.720e+10 + 4 10 5.469e+07 23.380 176.570 1.310 7.608 1.120000e+12 4.790e+10 + 4 11 4.972e+07 23.230 176.400 1.290 7.649 1.120000e+12 4.821e+10 + 4 12 4.557e+07 22.950 176.100 1.250 7.728 1.120000e+12 4.880e+10 + 4 13 4.207e+07 22.980 176.430 1.260 7.732 1.120000e+12 4.874e+10 + 4 14 3.906e+07 22.820 176.300 1.350 7.785 1.120000e+12 4.908e+10 + 4 15 3.646e+07 22.750 176.450 1.220 7.810 1.120000e+12 4.923e+10 + 4 16 3.418e+07 22.620 176.350 1.080 7.844 1.120000e+12 4.951e+10 + 5 1 1.367e+08 12.000 56.890 1.600 4.874 3.500000e+11 2.917e+10 + 5 2 1.367e+08 22.390 112.870 1.920 5.127 7.000000e+11 3.126e+10 + 5 3 1.367e+08 25.170 167.880 2.110 6.754 1.050000e+12 4.172e+10 + 5 4 1.094e+08 26.380 178.010 1.900 6.820 1.120000e+12 4.246e+10 + 5 5 8.750e+07 25.190 177.570 1.660 7.115 1.120000e+12 4.446e+10 + 5 6 7.292e+07 24.400 176.750 1.650 7.311 1.120000e+12 4.590e+10 + 5 7 6.250e+07 24.020 177.580 1.570 7.458 1.120000e+12 4.663e+10 + 5 8 5.469e+07 23.470 176.650 1.350 7.584 1.120000e+12 4.772e+10 + 5 9 4.861e+07 23.200 176.350 1.280 7.656 1.120000e+12 4.828e+10 + 5 10 4.375e+07 23.140 176.230 1.410 7.677 1.120000e+12 4.840e+10 + 5 11 3.977e+07 22.930 176.120 1.320 7.738 1.120000e+12 4.884e+10 + 5 12 3.646e+07 22.740 176.060 1.330 7.801 1.120000e+12 4.925e+10 + 5 13 3.365e+07 22.690 176.450 1.210 7.830 1.120000e+12 4.936e+10 + 5 14 3.125e+07 22.690 176.430 1.230 7.830 1.120000e+12 4.936e+10 + 5 15 2.917e+07 22.690 176.410 1.260 7.830 1.120000e+12 4.936e+10 + 5 16 2.734e+07 22.560 176.150 1.110 7.857 1.120000e+12 4.965e+10 + 6 1 1.367e+08 12.600 68.590 2.230 5.621 4.200000e+11 3.333e+10 + 6 2 1.367e+08 22.830 135.260 2.100 6.017 8.400000e+11 3.679e+10 + 6 3 1.215e+08 26.860 178.470 2.140 6.724 1.120000e+12 4.170e+10 + 6 4 9.115e+07 25.450 177.110 2.060 7.040 1.120000e+12 4.401e+10 + 6 5 7.292e+07 24.510 176.850 1.910 7.293 1.120000e+12 4.570e+10 + 6 6 6.076e+07 23.890 176.450 1.760 7.460 1.120000e+12 4.688e+10 + 6 7 5.208e+07 23.460 175.980 1.540 7.567 1.120000e+12 4.774e+10 + 6 8 4.557e+07 23.150 176.480 1.370 7.683 1.120000e+12 4.838e+10 + 6 9 4.051e+07 22.920 176.030 1.400 7.741 1.120000e+12 4.887e+10 + 6 10 3.646e+07 22.880 176.300 1.350 7.764 1.120000e+12 4.895e+10 + 6 11 3.314e+07 22.830 175.970 1.360 7.767 1.120000e+12 4.906e+10 + 6 12 3.038e+07 22.710 176.040 1.190 7.804 1.120000e+12 4.932e+10 + 6 13 2.804e+07 22.690 176.050 1.340 7.818 1.120000e+12 4.936e+10 + 6 14 2.604e+07 22.650 176.410 1.140 7.839 1.120000e+12 4.945e+10 + 6 15 2.431e+07 22.570 175.940 1.250 7.851 1.120000e+12 4.962e+10 + 6 16 2.279e+07 22.500 175.980 1.170 7.873 1.120000e+12 4.978e+10 + 7 1 1.367e+08 12.960 79.970 2.850 6.390 4.900000e+11 3.781e+10 + 7 2 1.367e+08 24.040 156.540 2.500 6.616 9.800000e+11 4.077e+10 + 7 3 1.042e+08 26.130 178.060 2.210 6.899 1.120000e+12 4.286e+10 + 7 4 7.812e+07 24.860 176.880 1.810 7.188 1.120000e+12 4.505e+10 + 7 5 6.250e+07 24.000 176.590 1.790 7.433 1.120000e+12 4.667e+10 + 7 6 5.208e+07 23.540 176.480 1.670 7.568 1.120000e+12 4.758e+10 + 7 7 4.464e+07 23.180 176.030 1.510 7.659 1.120000e+12 4.832e+10 + 7 8 3.906e+07 22.980 176.500 1.340 7.739 1.120000e+12 4.874e+10 + 7 9 3.472e+07 22.870 175.970 1.280 7.750 1.120000e+12 4.897e+10 + 7 10 3.125e+07 22.730 176.220 1.300 7.810 1.120000e+12 4.927e+10 + 7 11 2.841e+07 22.700 176.030 1.300 7.812 1.120000e+12 4.934e+10 + 7 12 2.604e+07 22.650 176.300 1.210 7.837 1.120000e+12 4.945e+10 + 7 13 2.404e+07 22.580 176.140 1.170 7.853 1.120000e+12 4.960e+10 + 7 14 2.232e+07 22.540 176.550 1.130 7.883 1.120000e+12 4.969e+10 + 7 15 2.083e+07 22.570 175.870 1.260 7.848 1.120000e+12 4.962e+10 + 7 16 1.953e+07 22.520 175.980 1.310 7.873 1.120000e+12 4.973e+10 + 8 1 1.367e+08 13.250 91.770 3.010 7.153 5.600000e+11 4.226e+10 + 8 2 1.367e+08 26.280 178.100 2.980 6.890 1.120000e+12 4.262e+10 + 8 3 9.115e+07 25.510 177.140 2.270 7.033 1.120000e+12 4.390e+10 + 8 4 6.836e+07 24.330 176.850 1.870 7.346 1.120000e+12 4.603e+10 + 8 5 5.469e+07 23.680 176.850 1.690 7.540 1.120000e+12 4.730e+10 + 8 6 4.557e+07 23.430 176.210 1.700 7.593 1.120000e+12 4.780e+10 + 8 7 3.906e+07 23.100 176.680 1.440 7.711 1.120000e+12 4.848e+10 + 8 8 3.418e+07 22.890 176.270 1.430 7.763 1.120000e+12 4.893e+10 + 8 9 3.038e+07 22.760 175.980 1.320 7.790 1.120000e+12 4.921e+10 + 8 10 2.734e+07 22.760 176.340 1.290 7.804 1.120000e+12 4.921e+10 + 8 11 2.486e+07 22.660 176.220 1.170 7.828 1.120000e+12 4.943e+10 + 8 12 2.279e+07 22.660 176.050 1.280 7.826 1.120000e+12 4.943e+10 + 8 13 2.103e+07 22.590 176.170 1.350 7.858 1.120000e+12 4.958e+10 + 8 14 1.953e+07 22.550 176.120 1.320 7.869 1.120000e+12 4.967e+10 + 8 15 1.823e+07 22.590 176.130 1.270 7.853 1.120000e+12 4.958e+10 + 8 16 1.709e+07 22.500 176.090 1.230 7.881 1.120000e+12 4.978e+10 + 9 1 1.367e+08 21.110 101.410 2.640 4.929 6.300000e+11 2.984e+10 + 9 2 1.215e+08 27.400 178.180 2.720 6.602 1.120000e+12 4.088e+10 + 9 3 8.102e+07 25.140 177.370 2.230 7.144 1.120000e+12 4.455e+10 + 9 4 6.076e+07 24.110 176.810 1.910 7.413 1.120000e+12 4.645e+10 + 9 5 4.861e+07 23.460 176.240 1.600 7.581 1.120000e+12 4.774e+10 + 9 6 4.051e+07 23.200 176.310 1.620 7.669 1.120000e+12 4.828e+10 + 9 7 3.472e+07 22.970 176.560 1.540 7.754 1.120000e+12 4.876e+10 + 9 8 3.038e+07 22.920 176.300 1.440 7.755 1.120000e+12 4.887e+10 + 9 9 2.701e+07 22.830 176.090 1.370 7.773 1.120000e+12 4.906e+10 + 9 10 2.431e+07 22.730 175.960 1.430 7.804 1.120000e+12 4.927e+10 + 9 11 2.210e+07 22.750 176.160 1.260 7.799 1.120000e+12 4.923e+10 + 9 12 2.025e+07 22.660 176.100 1.380 7.832 1.120000e+12 4.943e+10 + 9 13 1.870e+07 22.700 176.040 1.400 7.817 1.120000e+12 4.934e+10 + 9 14 1.736e+07 22.620 175.940 1.410 7.840 1.120000e+12 4.951e+10 + 9 15 1.620e+07 22.490 175.910 1.340 7.881 1.120000e+12 4.980e+10 + 9 16 1.519e+07 22.540 175.990 1.330 7.867 1.120000e+12 4.969e+10 + 10 1 1.367e+08 21.730 113.690 2.870 5.364 7.000000e+11 3.221e+10 + 10 2 1.094e+08 26.660 177.920 3.180 6.793 1.120000e+12 4.201e+10 + 10 3 7.292e+07 24.740 176.810 2.090 7.231 1.120000e+12 4.527e+10 + 10 4 5.469e+07 23.880 176.280 2.020 7.466 1.120000e+12 4.690e+10 + 10 5 4.375e+07 23.330 176.510 1.610 7.635 1.120000e+12 4.801e+10 + 10 6 3.646e+07 23.170 176.160 1.680 7.675 1.120000e+12 4.834e+10 + 10 7 3.125e+07 22.950 176.490 1.470 7.754 1.120000e+12 4.880e+10 + 10 8 2.734e+07 22.830 176.260 1.360 7.780 1.120000e+12 4.906e+10 + 10 9 2.431e+07 22.770 175.930 1.410 7.788 1.120000e+12 4.919e+10 + 10 10 2.188e+07 22.680 175.870 1.440 7.818 1.120000e+12 4.938e+10 + 10 11 1.989e+07 22.700 176.140 1.310 7.817 1.120000e+12 4.934e+10 + 10 12 1.823e+07 22.630 176.040 1.430 7.842 1.120000e+12 4.949e+10 + 10 13 1.683e+07 22.640 176.000 1.320 7.832 1.120000e+12 4.947e+10 + 10 14 1.562e+07 22.610 176.160 1.230 7.846 1.120000e+12 4.954e+10 + 10 15 1.458e+07 22.570 176.010 1.290 7.856 1.120000e+12 4.962e+10 + 10 16 1.367e+07 22.640 176.060 1.270 7.833 1.120000e+12 4.947e+10 + 11 1 1.367e+08 22.060 124.440 3.050 5.779 7.700000e+11 3.490e+10 + 11 2 9.943e+07 26.060 178.400 3.000 6.961 1.120000e+12 4.298e+10 + 11 3 6.629e+07 24.380 176.690 2.200 7.338 1.120000e+12 4.594e+10 + 11 4 4.972e+07 23.650 176.730 1.830 7.550 1.120000e+12 4.736e+10 + 11 5 3.977e+07 23.310 176.030 1.780 7.628 1.120000e+12 4.805e+10 + 11 6 3.314e+07 23.050 176.210 1.680 7.718 1.120000e+12 4.859e+10 + 11 7 2.841e+07 22.940 176.300 1.540 7.752 1.120000e+12 4.882e+10 + 11 8 2.486e+07 22.830 175.990 1.530 7.776 1.120000e+12 4.906e+10 + 11 9 2.210e+07 22.760 176.060 1.440 7.799 1.120000e+12 4.921e+10 + 11 10 1.989e+07 22.630 176.010 1.430 7.841 1.120000e+12 4.949e+10 + 11 11 1.808e+07 22.720 176.040 1.390 7.809 1.120000e+12 4.930e+10 + 11 12 1.657e+07 22.640 175.890 1.400 7.831 1.120000e+12 4.947e+10 + 11 13 1.530e+07 22.570 176.090 1.260 7.858 1.120000e+12 4.962e+10 + 11 14 1.420e+07 22.610 176.150 1.450 7.855 1.120000e+12 4.954e+10 + 11 15 1.326e+07 22.550 175.980 1.310 7.862 1.120000e+12 4.967e+10 + 11 16 1.243e+07 22.610 175.920 1.400 7.843 1.120000e+12 4.954e+10 + 12 1 1.367e+08 22.220 136.260 3.390 6.285 8.400000e+11 3.780e+10 + 12 2 9.115e+07 25.610 178.090 2.800 7.063 1.120000e+12 4.373e+10 + 12 3 6.076e+07 24.180 176.320 2.230 7.384 1.120000e+12 4.632e+10 + 12 4 4.557e+07 23.570 176.570 2.010 7.577 1.120000e+12 4.752e+10 + 12 5 3.646e+07 23.210 176.420 1.710 7.675 1.120000e+12 4.826e+10 + 12 6 3.038e+07 23.040 175.910 1.640 7.706 1.120000e+12 4.861e+10 + 12 7 2.604e+07 22.980 176.390 1.510 7.742 1.120000e+12 4.874e+10 + 12 8 2.279e+07 22.840 176.110 1.640 7.782 1.120000e+12 4.904e+10 + 12 9 2.025e+07 22.760 175.950 1.500 7.797 1.120000e+12 4.921e+10 + 12 10 1.823e+07 22.660 175.810 1.600 7.829 1.120000e+12 4.943e+10 + 12 11 1.657e+07 22.710 175.940 1.410 7.809 1.120000e+12 4.932e+10 + 12 12 1.519e+07 22.650 175.870 1.400 7.826 1.120000e+12 4.945e+10 + 12 13 1.402e+07 22.640 176.040 1.260 7.831 1.120000e+12 4.947e+10 + 12 14 1.302e+07 22.650 176.130 1.450 7.840 1.120000e+12 4.945e+10 + 12 15 1.215e+07 22.580 175.990 1.370 7.855 1.120000e+12 4.960e+10 + 12 16 1.139e+07 22.640 175.870 1.440 7.832 1.120000e+12 4.947e+10 + 13 1 1.367e+08 22.640 147.020 3.570 6.652 9.100000e+11 4.019e+10 + 13 2 8.413e+07 25.600 177.820 2.870 7.058 1.120000e+12 4.375e+10 + 13 3 5.609e+07 24.020 176.980 2.270 7.463 1.120000e+12 4.663e+10 + 13 4 4.207e+07 23.440 176.430 2.030 7.613 1.120000e+12 4.778e+10 + 13 5 3.365e+07 23.080 176.110 1.790 7.708 1.120000e+12 4.853e+10 + 13 6 2.804e+07 22.870 176.210 1.600 7.775 1.120000e+12 4.897e+10 + 13 7 2.404e+07 22.940 176.340 1.580 7.756 1.120000e+12 4.882e+10 + 13 8 2.103e+07 22.880 176.050 1.520 7.761 1.120000e+12 4.895e+10 + 13 9 1.870e+07 22.740 176.020 1.400 7.802 1.120000e+12 4.925e+10 + 13 10 1.683e+07 22.710 175.880 1.440 7.808 1.120000e+12 4.932e+10 + 13 11 1.530e+07 22.590 176.040 1.350 7.853 1.120000e+12 4.958e+10 + 13 12 1.402e+07 22.600 175.930 1.380 7.846 1.120000e+12 4.956e+10 + 13 13 1.294e+07 22.710 176.010 1.340 7.809 1.120000e+12 4.932e+10 + 13 14 1.202e+07 22.690 176.270 1.350 7.828 1.120000e+12 4.936e+10 + 13 15 1.122e+07 22.590 175.960 1.290 7.846 1.120000e+12 4.958e+10 + 13 16 1.052e+07 22.610 175.960 1.370 7.843 1.120000e+12 4.954e+10 + 14 1 1.367e+08 23.120 157.180 3.810 6.963 9.800000e+11 4.239e+10 + 14 2 7.812e+07 25.310 177.210 3.020 7.121 1.120000e+12 4.425e+10 + 14 3 5.208e+07 24.130 177.110 2.340 7.437 1.120000e+12 4.642e+10 + 14 4 3.906e+07 23.390 176.660 1.800 7.630 1.120000e+12 4.788e+10 + 14 5 3.125e+07 23.060 176.420 1.750 7.726 1.120000e+12 4.857e+10 + 14 6 2.604e+07 22.890 176.180 1.530 7.764 1.120000e+12 4.893e+10 + 14 7 2.232e+07 22.940 176.060 1.550 7.742 1.120000e+12 4.882e+10 + 14 8 1.953e+07 22.810 176.110 1.500 7.786 1.120000e+12 4.910e+10 + 14 9 1.736e+07 22.750 176.370 1.370 7.813 1.120000e+12 4.923e+10 + 14 10 1.562e+07 22.720 176.020 1.450 7.811 1.120000e+12 4.930e+10 + 14 11 1.420e+07 22.680 176.090 1.310 7.822 1.120000e+12 4.938e+10 + 14 12 1.302e+07 22.710 175.950 1.510 7.814 1.120000e+12 4.932e+10 + 14 13 1.202e+07 22.700 176.100 1.500 7.824 1.120000e+12 4.934e+10 + 14 14 1.116e+07 22.660 176.150 1.460 7.838 1.120000e+12 4.943e+10 + 14 15 1.042e+07 22.680 176.120 1.370 7.826 1.120000e+12 4.938e+10 + 14 16 9.766e+06 22.710 176.110 1.430 7.818 1.120000e+12 4.932e+10 + 15 1 1.367e+08 23.710 168.080 4.140 7.264 1.050000e+12 4.429e+10 + 15 2 7.292e+07 25.170 176.640 2.930 7.134 1.120000e+12 4.450e+10 + 15 3 4.861e+07 23.820 176.980 2.110 7.518 1.120000e+12 4.702e+10 + 15 4 3.646e+07 23.250 176.190 1.970 7.663 1.120000e+12 4.817e+10 + 15 5 2.917e+07 23.050 176.450 1.690 7.728 1.120000e+12 4.859e+10 + 15 6 2.431e+07 22.900 175.980 1.680 7.758 1.120000e+12 4.891e+10 + 15 7 2.083e+07 22.830 176.090 1.640 7.785 1.120000e+12 4.906e+10 + 15 8 1.823e+07 22.850 176.160 1.530 7.776 1.120000e+12 4.902e+10 + 15 9 1.620e+07 22.780 176.390 1.360 7.803 1.120000e+12 4.917e+10 + 15 10 1.458e+07 22.660 176.000 1.440 7.831 1.120000e+12 4.943e+10 + 15 11 1.326e+07 22.660 176.110 1.430 7.835 1.120000e+12 4.943e+10 + 15 12 1.215e+07 22.660 176.150 1.380 7.835 1.120000e+12 4.943e+10 + 15 13 1.122e+07 22.760 175.970 1.580 7.801 1.120000e+12 4.921e+10 + 15 14 1.042e+07 22.670 176.290 1.270 7.832 1.120000e+12 4.940e+10 + 15 15 9.722e+06 22.710 176.060 1.550 7.821 1.120000e+12 4.932e+10 + 15 16 9.115e+06 22.800 176.020 1.490 7.786 1.120000e+12 4.912e+10 + 16 1 1.367e+08 25.470 179.270 4.730 7.224 1.120000e+12 4.397e+10 + 16 2 6.836e+07 24.870 176.820 2.960 7.229 1.120000e+12 4.503e+10 + 16 3 4.557e+07 23.810 176.930 2.250 7.525 1.120000e+12 4.704e+10 + 16 4 3.418e+07 23.240 176.650 1.950 7.685 1.120000e+12 4.819e+10 + 16 5 2.734e+07 23.090 175.940 1.940 7.704 1.120000e+12 4.851e+10 + 16 6 2.279e+07 22.900 176.120 1.680 7.764 1.120000e+12 4.891e+10 + 16 7 1.953e+07 22.890 176.290 1.440 7.765 1.120000e+12 4.893e+10 + 16 8 1.709e+07 22.820 176.040 1.610 7.785 1.120000e+12 4.908e+10 + 16 9 1.519e+07 22.890 175.990 1.470 7.753 1.120000e+12 4.893e+10 + 16 10 1.367e+07 22.700 175.890 1.470 7.813 1.120000e+12 4.934e+10 + 16 11 1.243e+07 22.770 175.960 1.520 7.794 1.120000e+12 4.919e+10 + 16 12 1.139e+07 22.730 176.000 1.430 7.806 1.120000e+12 4.927e+10 + 16 13 1.052e+07 22.670 175.990 1.540 7.831 1.120000e+12 4.940e+10 + 16 14 9.766e+06 22.720 176.130 1.440 7.816 1.120000e+12 4.930e+10 + 16 15 9.115e+06 22.740 176.320 1.360 7.814 1.120000e+12 4.925e+10 + 16 16 8.545e+06 22.680 176.170 1.320 7.826 1.120000e+12 4.938e+10 diff --git a/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat new file mode 100644 index 000000000..57d49ed33 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat @@ -0,0 +1,257 @@ +#D Dual quad-core Xeon 3.0 GHz (Penryn E5472, 1600 MHz FSB, 5400 chipset) + 1 1 5.000e+07 2.720 3.020 0.110 1.151 2.560000e+10 9.412e+09 + 1 2 5.000e+07 2.870 5.630 0.170 2.021 5.120000e+10 1.784e+10 + 1 3 5.000e+07 2.880 8.380 0.160 2.965 7.680000e+10 2.667e+10 + 1 4 5.000e+07 2.990 11.080 0.200 3.773 1.024000e+11 3.425e+10 + 1 5 5.000e+07 2.950 13.950 0.190 4.793 1.280000e+11 4.339e+10 + 1 6 5.000e+07 3.020 16.620 0.240 5.583 1.536000e+11 5.086e+10 + 1 7 5.000e+07 2.930 19.250 0.200 6.638 1.792000e+11 6.116e+10 + 1 8 5.000e+07 3.170 22.240 0.290 7.107 2.048000e+11 6.461e+10 + 1 9 5.000e+07 5.450 24.410 0.310 4.536 2.304000e+11 4.228e+10 + 1 10 5.000e+07 5.610 27.400 0.370 4.950 2.560000e+11 4.563e+10 + 1 11 5.000e+07 5.680 29.960 0.370 5.340 2.816000e+11 4.958e+10 + 1 12 5.000e+07 5.440 32.490 0.350 6.037 3.072000e+11 5.647e+10 + 1 13 5.000e+07 5.630 35.270 0.400 6.336 3.328000e+11 5.911e+10 + 1 14 5.000e+07 6.270 38.500 0.480 6.217 3.584000e+11 5.716e+10 + 1 15 5.000e+07 6.080 40.880 0.490 6.804 3.840000e+11 6.316e+10 + 1 16 5.000e+07 7.740 43.390 0.600 5.683 4.096000e+11 5.292e+10 + 2 1 5.000e+07 2.820 5.700 0.210 2.096 5.120000e+10 1.816e+10 + 2 2 5.000e+07 2.820 11.130 0.230 4.028 1.024000e+11 3.631e+10 + 2 3 5.000e+07 2.960 16.570 0.320 5.706 1.536000e+11 5.189e+10 + 2 4 5.000e+07 3.110 21.920 0.390 7.174 2.048000e+11 6.585e+10 + 2 5 5.000e+07 5.650 27.550 0.520 4.968 2.560000e+11 4.531e+10 + 2 6 5.000e+07 5.880 32.890 0.440 5.668 3.072000e+11 5.224e+10 + 2 7 5.000e+07 6.750 38.210 0.560 5.744 3.584000e+11 5.310e+10 + 2 8 5.000e+07 6.360 43.480 0.580 6.928 4.096000e+11 6.440e+10 + 2 9 5.000e+07 8.270 48.750 0.730 5.983 4.608000e+11 5.572e+10 + 2 10 5.000e+07 8.210 54.400 0.610 6.700 5.120000e+11 6.236e+10 + 2 11 5.000e+07 8.750 59.760 0.640 6.903 5.632000e+11 6.437e+10 + 2 12 5.000e+07 9.300 65.050 0.700 7.070 6.144000e+11 6.606e+10 + 2 13 5.000e+07 9.990 70.750 0.750 7.157 6.656000e+11 6.663e+10 + 2 14 5.000e+07 10.610 75.950 0.810 7.235 7.168000e+11 6.756e+10 + 2 15 5.000e+07 11.900 80.400 0.870 6.829 7.680000e+11 6.454e+10 + 2 16 5.000e+07 11.820 86.790 0.900 7.419 8.192000e+11 6.931e+10 + 3 1 5.000e+07 2.970 8.300 0.380 2.923 7.680000e+10 2.586e+10 + 3 2 5.000e+07 2.980 16.660 0.390 5.721 1.536000e+11 5.154e+10 + 3 3 5.000e+07 5.480 24.690 0.420 4.582 2.304000e+11 4.204e+10 + 3 4 5.000e+07 5.620 32.820 0.560 5.940 3.072000e+11 5.466e+10 + 3 5 5.000e+07 6.940 40.800 0.620 5.968 3.840000e+11 5.533e+10 + 3 6 5.000e+07 7.860 49.010 0.710 6.326 4.608000e+11 5.863e+10 + 3 7 5.000e+07 8.470 57.130 0.750 6.834 5.376000e+11 6.347e+10 + 3 8 5.000e+07 9.420 65.310 0.820 7.020 6.144000e+11 6.522e+10 + 3 9 5.000e+07 10.350 73.640 0.940 7.206 6.912000e+11 6.678e+10 + 3 10 5.000e+07 11.460 82.230 1.030 7.265 7.680000e+11 6.702e+10 + 3 11 5.000e+07 12.200 89.590 1.050 7.430 8.448000e+11 6.925e+10 + 3 12 5.000e+07 13.040 97.520 1.140 7.566 9.216000e+11 7.067e+10 + 3 13 5.000e+07 14.000 105.560 1.150 7.622 9.984000e+11 7.131e+10 + 3 14 5.000e+07 14.930 113.630 1.210 7.692 1.075200e+12 7.202e+10 + 3 15 5.000e+07 15.920 121.610 1.350 7.724 1.152000e+12 7.236e+10 + 3 16 5.000e+07 16.870 129.770 1.390 7.775 1.228800e+12 7.284e+10 + 4 1 5.000e+07 2.900 11.100 0.340 3.945 1.024000e+11 3.531e+10 + 4 2 5.000e+07 4.380 21.980 0.480 5.128 2.048000e+11 4.676e+10 + 4 3 5.000e+07 5.720 32.800 0.610 5.841 3.072000e+11 5.371e+10 + 4 4 5.000e+07 6.820 43.880 0.700 6.537 4.096000e+11 6.006e+10 + 4 5 5.000e+07 8.150 54.420 0.760 6.771 5.120000e+11 6.282e+10 + 4 6 5.000e+07 9.510 65.180 0.980 6.957 6.144000e+11 6.461e+10 + 4 7 5.000e+07 10.650 76.080 1.020 7.239 7.168000e+11 6.731e+10 + 4 8 5.000e+07 11.880 86.720 1.110 7.393 8.192000e+11 6.896e+10 + 4 9 5.000e+07 13.150 97.920 1.250 7.541 9.216000e+11 7.008e+10 + 4 10 5.000e+07 14.640 109.260 1.410 7.559 1.024000e+12 6.995e+10 + 4 11 5.000e+07 15.710 119.170 1.440 7.677 1.126400e+12 7.170e+10 + 4 12 5.000e+07 16.950 129.960 1.420 7.751 1.228800e+12 7.250e+10 + 4 13 5.000e+07 18.260 140.520 1.620 7.784 1.331200e+12 7.290e+10 + 4 14 5.000e+07 19.610 151.290 1.780 7.806 1.433600e+12 7.311e+10 + 4 15 5.000e+07 21.060 162.760 1.890 7.818 1.536000e+12 7.293e+10 + 4 16 5.000e+07 22.280 172.870 1.980 7.848 1.638400e+12 7.354e+10 + 5 1 5.000e+07 3.040 13.810 0.390 4.671 1.280000e+11 4.211e+10 + 5 2 5.000e+07 5.590 27.510 0.610 5.030 2.560000e+11 4.580e+10 + 5 3 5.000e+07 6.550 40.970 0.780 6.374 3.840000e+11 5.863e+10 + 5 4 5.000e+07 8.520 54.470 0.940 6.504 5.120000e+11 6.009e+10 + 5 5 5.000e+07 9.920 67.950 1.060 6.957 6.400000e+11 6.452e+10 + 5 6 5.000e+07 11.350 81.490 1.180 7.284 7.680000e+11 6.767e+10 + 5 7 5.000e+07 12.910 94.960 1.300 7.456 8.960000e+11 6.940e+10 + 5 8 5.000e+07 14.520 108.510 1.400 7.570 1.024000e+12 7.052e+10 + 5 9 5.000e+07 16.070 122.120 1.620 7.700 1.152000e+12 7.169e+10 + 5 10 5.000e+07 17.950 136.140 1.730 7.681 1.280000e+12 7.131e+10 + 5 11 5.000e+07 19.470 148.330 1.830 7.712 1.408000e+12 7.232e+10 + 5 12 5.000e+07 20.980 162.100 2.030 7.823 1.536000e+12 7.321e+10 + 5 13 5.000e+07 22.670 175.470 2.160 7.835 1.664000e+12 7.340e+10 + 5 14 5.000e+07 24.440 189.630 2.170 7.848 1.792000e+12 7.332e+10 + 5 15 5.000e+07 26.100 203.010 2.450 7.872 1.920000e+12 7.356e+10 + 5 16 5.000e+07 27.720 216.000 2.550 7.884 2.048000e+12 7.388e+10 + 6 1 5.000e+07 2.950 16.560 0.540 5.797 1.536000e+11 5.207e+10 + 6 2 5.000e+07 5.540 32.900 0.720 6.069 3.072000e+11 5.545e+10 + 6 3 5.000e+07 8.490 48.860 1.000 5.873 4.608000e+11 5.428e+10 + 6 4 5.000e+07 10.000 64.670 1.100 6.577 6.144000e+11 6.144e+10 + 6 5 5.000e+07 11.440 81.430 1.310 7.233 7.680000e+11 6.713e+10 + 6 6 5.000e+07 13.250 97.690 1.360 7.475 9.216000e+11 6.955e+10 + 6 7 5.000e+07 15.270 113.730 1.610 7.553 1.075200e+12 7.041e+10 + 6 8 5.000e+07 17.180 129.780 1.820 7.660 1.228800e+12 7.153e+10 + 6 9 5.000e+07 19.200 146.020 1.870 7.703 1.382400e+12 7.200e+10 + 6 10 5.000e+07 21.220 162.290 2.100 7.747 1.536000e+12 7.238e+10 + 6 11 5.000e+07 23.070 178.420 2.160 7.827 1.689600e+12 7.324e+10 + 6 12 5.000e+07 25.120 194.590 2.450 7.844 1.843200e+12 7.338e+10 + 6 13 5.000e+07 27.110 210.640 2.660 7.868 1.996800e+12 7.366e+10 + 6 14 5.000e+07 29.110 226.820 2.750 7.886 2.150400e+12 7.387e+10 + 6 15 5.000e+07 31.130 242.800 2.940 7.894 2.304000e+12 7.401e+10 + 6 16 5.000e+07 33.100 258.790 3.210 7.915 2.457600e+12 7.425e+10 + 7 1 5.000e+07 2.940 19.140 0.590 6.711 1.792000e+11 6.095e+10 + 7 2 5.000e+07 5.920 37.910 1.030 6.578 3.584000e+11 6.054e+10 + 7 3 5.000e+07 8.570 57.010 1.150 6.786 5.376000e+11 6.273e+10 + 7 4 5.000e+07 10.840 76.060 1.320 7.138 7.168000e+11 6.613e+10 + 7 5 5.000e+07 13.070 94.920 1.540 7.380 8.960000e+11 6.855e+10 + 7 6 5.000e+07 15.270 113.790 1.730 7.565 1.075200e+12 7.041e+10 + 7 7 5.000e+07 17.700 132.560 1.960 7.600 1.254400e+12 7.087e+10 + 7 8 5.000e+07 19.930 151.500 2.130 7.708 1.433600e+12 7.193e+10 + 7 9 5.000e+07 22.250 170.570 2.340 7.771 1.612800e+12 7.249e+10 + 7 10 5.000e+07 24.600 189.280 2.450 7.794 1.792000e+12 7.285e+10 + 7 11 5.000e+07 26.950 208.030 2.700 7.819 1.971200e+12 7.314e+10 + 7 12 5.000e+07 29.280 227.070 2.850 7.852 2.150400e+12 7.344e+10 + 7 13 5.000e+07 31.570 245.750 3.040 7.881 2.329600e+12 7.379e+10 + 7 14 5.000e+07 33.930 264.960 3.160 7.902 2.508800e+12 7.394e+10 + 7 15 5.000e+07 36.310 283.960 3.440 7.915 2.688000e+12 7.403e+10 + 7 16 5.000e+07 38.560 302.120 3.630 7.929 2.867200e+12 7.436e+10 + 8 1 5.000e+07 3.200 21.880 0.860 7.106 2.048000e+11 6.400e+10 + 8 2 5.000e+07 5.890 43.450 0.930 7.535 4.096000e+11 6.954e+10 + 8 3 5.000e+07 9.520 65.180 1.250 6.978 6.144000e+11 6.454e+10 + 8 4 5.000e+07 12.200 86.780 1.480 7.234 8.192000e+11 6.715e+10 + 8 5 5.000e+07 14.760 108.420 1.670 7.459 1.024000e+12 6.938e+10 + 8 6 5.000e+07 17.300 129.850 1.960 7.619 1.228800e+12 7.103e+10 + 8 7 5.000e+07 20.020 151.430 2.190 7.673 1.433600e+12 7.161e+10 + 8 8 5.000e+07 22.750 173.550 2.420 7.735 1.638400e+12 7.202e+10 + 8 9 5.000e+07 25.410 194.560 2.760 7.765 1.843200e+12 7.254e+10 + 8 10 5.000e+07 28.410 217.250 2.920 7.750 2.048000e+12 7.209e+10 + 8 11 5.000e+07 30.720 237.990 3.210 7.852 2.252800e+12 7.333e+10 + 8 12 5.000e+07 33.310 259.340 3.280 7.884 2.457600e+12 7.378e+10 + 8 13 5.000e+07 36.000 280.760 3.670 7.901 2.662400e+12 7.396e+10 + 8 14 5.000e+07 38.800 302.570 3.740 7.895 2.867200e+12 7.390e+10 + 8 15 5.000e+07 41.530 324.520 4.060 7.912 3.072000e+12 7.397e+10 + 8 16 5.000e+07 44.060 345.420 4.250 7.936 3.276800e+12 7.437e+10 + 9 1 5.000e+07 5.460 24.660 1.000 4.700 2.304000e+11 4.220e+10 + 9 2 5.000e+07 8.460 49.010 1.200 5.935 4.608000e+11 5.447e+10 + 9 3 5.000e+07 10.810 71.410 1.400 6.735 6.912000e+11 6.394e+10 + 9 4 5.000e+07 13.470 97.570 1.710 7.370 9.216000e+11 6.842e+10 + 9 5 5.000e+07 16.490 121.780 2.130 7.514 1.152000e+12 6.986e+10 + 9 6 5.000e+07 19.540 146.070 2.280 7.592 1.382400e+12 7.075e+10 + 9 7 5.000e+07 22.660 170.830 2.570 7.652 1.612800e+12 7.117e+10 + 9 8 5.000e+07 25.520 194.720 2.760 7.738 1.843200e+12 7.223e+10 + 9 9 5.000e+07 28.400 219.020 3.060 7.820 2.073600e+12 7.301e+10 + 9 10 5.000e+07 31.490 243.030 3.320 7.823 2.304000e+12 7.317e+10 + 9 11 5.000e+07 34.530 267.230 3.420 7.838 2.534400e+12 7.340e+10 + 9 12 5.000e+07 37.520 291.720 3.860 7.878 2.764800e+12 7.369e+10 + 9 13 5.000e+07 40.550 315.780 4.170 7.890 2.995200e+12 7.386e+10 + 9 14 5.000e+07 43.470 339.930 4.290 7.919 3.225600e+12 7.420e+10 + 9 15 5.000e+07 46.820 364.970 4.640 7.894 3.456000e+12 7.381e+10 + 9 16 5.000e+07 49.660 388.630 4.890 7.924 3.686400e+12 7.423e+10 + 10 1 5.000e+07 5.500 27.290 0.980 5.140 2.560000e+11 4.655e+10 + 10 2 5.000e+07 8.480 54.830 1.420 6.633 5.120000e+11 6.038e+10 + 10 3 5.000e+07 11.540 81.580 1.630 7.211 7.680000e+11 6.655e+10 + 10 4 5.000e+07 14.950 108.480 1.860 7.381 1.024000e+12 6.849e+10 + 10 5 5.000e+07 18.330 135.300 2.280 7.506 1.280000e+12 6.983e+10 + 10 6 5.000e+07 21.680 162.380 2.540 7.607 1.536000e+12 7.085e+10 + 10 7 5.000e+07 24.950 189.360 2.730 7.699 1.792000e+12 7.182e+10 + 10 8 5.000e+07 28.280 216.090 3.110 7.751 2.048000e+12 7.242e+10 + 10 9 5.000e+07 31.730 243.290 3.450 7.776 2.304000e+12 7.261e+10 + 10 10 5.000e+07 35.040 270.380 3.680 7.821 2.560000e+12 7.306e+10 + 10 11 5.000e+07 38.340 297.080 4.050 7.854 2.816000e+12 7.345e+10 + 10 12 5.000e+07 41.770 323.840 4.330 7.857 3.072000e+12 7.355e+10 + 10 13 5.000e+07 45.120 351.380 4.710 7.892 3.328000e+12 7.376e+10 + 10 14 5.000e+07 48.360 377.870 4.880 7.915 3.584000e+12 7.411e+10 + 10 15 5.000e+07 51.760 404.740 5.110 7.918 3.840000e+12 7.419e+10 + 10 16 5.000e+07 55.130 431.760 5.430 7.930 4.096000e+12 7.430e+10 + 11 1 5.000e+07 5.570 30.080 1.080 5.594 2.816000e+11 5.056e+10 + 11 2 5.000e+07 9.000 60.230 1.470 6.856 5.632000e+11 6.258e+10 + 11 3 5.000e+07 12.630 89.890 1.770 7.257 8.448000e+11 6.689e+10 + 11 4 5.000e+07 16.290 119.110 2.140 7.443 1.126400e+12 6.915e+10 + 11 5 5.000e+07 19.940 148.730 2.440 7.581 1.408000e+12 7.061e+10 + 11 6 5.000e+07 23.800 178.620 2.790 7.622 1.689600e+12 7.099e+10 + 11 7 5.000e+07 27.480 208.510 3.160 7.703 1.971200e+12 7.173e+10 + 11 8 5.000e+07 31.140 237.820 3.490 7.749 2.252800e+12 7.234e+10 + 11 9 5.000e+07 34.770 267.390 3.800 7.800 2.534400e+12 7.289e+10 + 11 10 5.000e+07 38.510 297.250 4.240 7.829 2.816000e+12 7.312e+10 + 11 11 5.000e+07 42.080 326.570 4.610 7.870 3.097600e+12 7.361e+10 + 11 12 5.000e+07 45.860 356.540 4.590 7.875 3.379200e+12 7.369e+10 + 11 13 5.000e+07 49.570 386.250 5.150 7.896 3.660800e+12 7.385e+10 + 11 14 5.000e+07 53.220 415.630 5.360 7.910 3.942400e+12 7.408e+10 + 11 15 5.000e+07 57.000 445.200 5.870 7.914 4.224000e+12 7.411e+10 + 11 16 5.000e+07 60.800 474.810 6.250 7.912 4.505600e+12 7.411e+10 + 12 1 5.000e+07 5.600 32.770 1.240 6.073 3.072000e+11 5.486e+10 + 12 2 5.000e+07 10.220 65.660 1.600 6.581 6.144000e+11 6.012e+10 + 12 3 5.000e+07 13.680 97.900 2.000 7.303 9.216000e+11 6.737e+10 + 12 4 5.000e+07 17.790 129.710 2.330 7.422 1.228800e+12 6.907e+10 + 12 5 5.000e+07 21.770 162.420 2.700 7.585 1.536000e+12 7.056e+10 + 12 6 5.000e+07 25.770 194.770 3.090 7.678 1.843200e+12 7.153e+10 + 12 7 5.000e+07 29.940 227.290 3.390 7.705 2.150400e+12 7.182e+10 + 12 8 5.000e+07 34.030 259.370 3.860 7.735 2.457600e+12 7.222e+10 + 12 9 5.000e+07 38.070 291.890 4.310 7.780 2.764800e+12 7.262e+10 + 12 10 5.000e+07 42.080 324.370 4.660 7.819 3.072000e+12 7.300e+10 + 12 11 5.000e+07 45.950 356.370 5.000 7.864 3.379200e+12 7.354e+10 + 12 12 5.000e+07 49.960 388.790 5.250 7.887 3.686400e+12 7.379e+10 + 12 13 5.000e+07 54.010 422.050 5.420 7.915 3.993600e+12 7.394e+10 + 12 14 5.000e+07 58.010 453.330 6.120 7.920 4.300800e+12 7.414e+10 + 12 15 5.000e+07 62.080 485.830 6.310 7.928 4.608000e+12 7.423e+10 + 12 16 5.000e+07 66.200 518.060 6.780 7.928 4.915200e+12 7.425e+10 + 13 1 5.000e+07 5.630 35.420 1.300 6.522 3.328000e+11 5.911e+10 + 13 2 5.000e+07 10.730 71.050 1.830 6.792 6.656000e+11 6.203e+10 + 13 3 5.000e+07 14.690 105.710 2.160 7.343 9.984000e+11 6.796e+10 + 13 4 5.000e+07 19.120 140.630 2.510 7.486 1.331200e+12 6.962e+10 + 13 5 5.000e+07 23.600 175.730 3.000 7.573 1.664000e+12 7.051e+10 + 13 6 5.000e+07 27.910 211.000 3.350 7.680 1.996800e+12 7.154e+10 + 13 7 5.000e+07 32.370 246.320 3.860 7.729 2.329600e+12 7.197e+10 + 13 8 5.000e+07 36.790 281.150 4.260 7.758 2.662400e+12 7.237e+10 + 13 9 5.000e+07 41.080 316.080 4.520 7.804 2.995200e+12 7.291e+10 + 13 10 5.000e+07 45.600 352.020 5.090 7.831 3.328000e+12 7.298e+10 + 13 11 5.000e+07 49.760 386.130 5.470 7.870 3.660800e+12 7.357e+10 + 13 12 5.000e+07 54.080 421.160 5.780 7.895 3.993600e+12 7.385e+10 + 13 13 5.000e+07 58.520 455.980 6.170 7.897 4.326400e+12 7.393e+10 + 13 14 5.000e+07 63.000 491.340 6.710 7.906 4.659200e+12 7.396e+10 + 13 15 5.000e+07 67.250 525.920 6.920 7.923 4.992000e+12 7.423e+10 + 13 16 5.000e+07 72.090 560.640 7.160 7.876 5.324800e+12 7.386e+10 + 14 1 5.000e+07 5.670 38.290 1.330 6.988 3.584000e+11 6.321e+10 + 14 2 5.000e+07 10.850 75.880 1.940 7.172 7.168000e+11 6.606e+10 + 14 3 5.000e+07 15.840 114.160 2.400 7.359 1.075200e+12 6.788e+10 + 14 4 5.000e+07 20.610 151.540 2.710 7.484 1.433600e+12 6.956e+10 + 14 5 5.000e+07 25.330 189.160 3.320 7.599 1.792000e+12 7.075e+10 + 14 6 5.000e+07 30.160 227.510 3.670 7.665 2.150400e+12 7.130e+10 + 14 7 5.000e+07 34.730 265.020 3.960 7.745 2.508800e+12 7.224e+10 + 14 8 5.000e+07 39.530 302.550 4.640 7.771 2.867200e+12 7.253e+10 + 14 9 5.000e+07 44.220 340.330 5.180 7.813 3.225600e+12 7.294e+10 + 14 10 5.000e+07 48.800 378.180 5.430 7.861 3.584000e+12 7.344e+10 + 14 11 5.000e+07 53.550 415.790 5.800 7.873 3.942400e+12 7.362e+10 + 14 12 5.000e+07 58.250 453.340 6.430 7.893 4.300800e+12 7.383e+10 + 14 13 5.000e+07 63.150 492.200 6.960 7.904 4.659200e+12 7.378e+10 + 14 14 5.000e+07 67.850 528.470 6.970 7.892 5.017600e+12 7.395e+10 + 14 15 5.000e+07 72.510 566.950 7.720 7.925 5.376000e+12 7.414e+10 + 14 16 5.000e+07 77.230 604.250 8.170 7.930 5.734400e+12 7.425e+10 + 15 1 5.000e+07 5.800 41.070 1.460 7.333 3.840000e+11 6.621e+10 + 15 2 5.000e+07 11.900 80.380 2.190 6.939 7.680000e+11 6.454e+10 + 15 3 5.000e+07 16.990 121.790 2.610 7.322 1.152000e+12 6.780e+10 + 15 4 5.000e+07 22.040 162.330 3.030 7.503 1.536000e+12 6.969e+10 + 15 5 5.000e+07 27.120 202.750 3.460 7.604 1.920000e+12 7.080e+10 + 15 6 5.000e+07 32.290 243.420 3.870 7.658 2.304000e+12 7.135e+10 + 15 7 5.000e+07 37.450 284.300 4.410 7.709 2.688000e+12 7.178e+10 + 15 8 5.000e+07 42.560 323.740 4.890 7.722 3.072000e+12 7.218e+10 + 15 9 5.000e+07 47.440 364.880 5.330 7.804 3.456000e+12 7.285e+10 + 15 10 5.000e+07 52.440 405.400 5.750 7.840 3.840000e+12 7.323e+10 + 15 11 5.000e+07 57.270 445.500 6.070 7.885 4.224000e+12 7.376e+10 + 15 12 5.000e+07 62.450 485.920 6.770 7.889 4.608000e+12 7.379e+10 + 15 13 5.000e+07 67.680 527.540 7.440 7.905 4.992000e+12 7.376e+10 + 15 14 5.000e+07 72.740 566.990 7.790 7.902 5.376000e+12 7.391e+10 + 15 15 5.000e+07 77.760 607.620 8.060 7.918 5.760000e+12 7.407e+10 + 15 16 5.000e+07 82.750 647.630 8.640 7.931 6.144000e+12 7.425e+10 + 16 1 5.000e+07 6.310 43.540 1.790 7.184 4.096000e+11 6.491e+10 + 16 2 5.000e+07 12.340 87.310 2.190 7.253 8.192000e+11 6.639e+10 + 16 3 5.000e+07 17.930 130.440 2.830 7.433 1.228800e+12 6.853e+10 + 16 4 5.000e+07 23.530 173.540 3.140 7.509 1.638400e+12 6.963e+10 + 16 5 5.000e+07 28.910 216.290 3.710 7.610 2.048000e+12 7.084e+10 + 16 6 5.000e+07 34.310 259.400 4.260 7.685 2.457600e+12 7.163e+10 + 16 7 5.000e+07 39.790 302.740 4.620 7.725 2.867200e+12 7.206e+10 + 16 8 5.000e+07 44.970 346.250 5.340 7.818 3.276800e+12 7.287e+10 + 16 9 5.000e+07 50.470 388.870 5.910 7.822 3.686400e+12 7.304e+10 + 16 10 5.000e+07 55.890 432.480 6.140 7.848 4.096000e+12 7.329e+10 + 16 11 5.000e+07 61.250 475.380 6.770 7.872 4.505600e+12 7.356e+10 + 16 12 5.000e+07 66.670 518.940 7.160 7.891 4.915200e+12 7.372e+10 + 16 13 5.000e+07 72.160 562.230 7.890 7.901 5.324800e+12 7.379e+10 + 16 14 5.000e+07 77.600 604.950 8.230 7.902 5.734400e+12 7.390e+10 + 16 15 5.000e+07 82.970 648.420 8.690 7.920 6.144000e+12 7.405e+10 + 16 16 5.000e+07 88.370 690.730 9.460 7.923 6.553600e+12 7.416e+10 diff --git a/gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat new file mode 100644 index 000000000..d0b8148f0 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat @@ -0,0 +1,65 @@ +#D JS21 4-core PPC970M 2.5 GHz (using Altivec) + 1 1 9.766e+07 9.820 10.210 0.360 1.076 5.000000e+10 5.092e+09 + 1 2 9.766e+07 10.620 19.890 0.640 1.933 1.000000e+11 9.416e+09 + 1 3 9.766e+07 10.310 29.590 0.610 2.929 1.500000e+11 1.455e+10 + 1 4 9.766e+07 10.440 39.290 0.680 3.829 2.000000e+11 1.916e+10 + 1 5 7.812e+07 15.730 39.150 0.590 2.526 2.000000e+11 1.271e+10 + 1 6 6.510e+07 13.100 39.080 0.590 3.028 2.000000e+11 1.527e+10 + 1 7 5.580e+07 11.550 39.030 0.500 3.423 2.000000e+11 1.732e+10 + 1 8 4.883e+07 10.410 39.010 0.510 3.796 2.000000e+11 1.921e+10 + 2 1 9.766e+07 10.080 20.070 0.700 2.061 1.000000e+11 9.921e+09 + 2 2 9.766e+07 11.360 39.650 0.960 3.575 2.000000e+11 1.761e+10 + 2 3 6.510e+07 13.120 39.270 0.740 3.050 2.000000e+11 1.524e+10 + 2 4 4.883e+07 10.410 39.110 0.650 3.819 2.000000e+11 1.921e+10 + 2 5 3.906e+07 11.030 39.080 0.610 3.598 2.000000e+11 1.813e+10 + 2 6 3.255e+07 10.640 39.020 0.560 3.720 2.000000e+11 1.880e+10 + 2 7 2.790e+07 10.510 38.980 0.550 3.761 2.000000e+11 1.903e+10 + 2 8 2.441e+07 10.440 38.970 0.570 3.787 2.000000e+11 1.916e+10 + 3 1 9.766e+07 12.130 29.970 0.920 2.547 1.500000e+11 1.237e+10 + 3 2 6.510e+07 13.100 39.300 0.920 3.070 2.000000e+11 1.527e+10 + 3 3 4.340e+07 11.400 39.200 0.760 3.505 2.000000e+11 1.754e+10 + 3 4 3.255e+07 10.730 39.100 0.690 3.708 2.000000e+11 1.864e+10 + 3 5 2.604e+07 10.470 39.010 0.620 3.785 2.000000e+11 1.910e+10 + 3 6 2.170e+07 10.380 39.010 0.620 3.818 2.000000e+11 1.927e+10 + 3 7 1.860e+07 10.280 39.120 0.580 3.862 2.000000e+11 1.946e+10 + 3 8 1.628e+07 10.230 39.000 0.600 3.871 2.000000e+11 1.955e+10 + 4 1 9.766e+07 10.700 39.990 1.540 3.881 2.000000e+11 1.869e+10 + 4 2 4.883e+07 10.530 39.260 0.940 3.818 2.000000e+11 1.899e+10 + 4 3 3.255e+07 10.840 39.140 0.760 3.681 2.000000e+11 1.845e+10 + 4 4 2.441e+07 10.530 39.040 0.680 3.772 2.000000e+11 1.899e+10 + 4 5 1.953e+07 10.380 39.030 0.650 3.823 2.000000e+11 1.927e+10 + 4 6 1.628e+07 10.310 39.020 0.650 3.848 2.000000e+11 1.940e+10 + 4 7 1.395e+07 10.160 38.980 0.620 3.898 2.000000e+11 1.969e+10 + 4 8 1.221e+07 10.150 38.990 0.580 3.899 2.000000e+11 1.970e+10 + 5 1 7.812e+07 14.750 39.780 1.470 2.797 2.000000e+11 1.356e+10 + 5 2 3.906e+07 11.350 39.240 0.950 3.541 2.000000e+11 1.762e+10 + 5 3 2.604e+07 10.720 39.120 0.800 3.724 2.000000e+11 1.866e+10 + 5 4 1.953e+07 10.440 39.060 0.730 3.811 2.000000e+11 1.916e+10 + 5 5 1.562e+07 10.410 39.060 0.690 3.818 2.000000e+11 1.921e+10 + 5 6 1.302e+07 10.260 38.970 0.650 3.862 2.000000e+11 1.949e+10 + 5 7 1.116e+07 10.270 39.020 0.650 3.863 2.000000e+11 1.947e+10 + 5 8 9.766e+06 10.130 39.010 0.660 3.916 2.000000e+11 1.974e+10 + 6 1 6.510e+07 12.850 39.730 1.450 3.205 2.000000e+11 1.556e+10 + 6 2 3.255e+07 10.700 39.300 0.990 3.765 2.000000e+11 1.869e+10 + 6 3 2.170e+07 10.770 39.110 0.810 3.707 2.000000e+11 1.857e+10 + 6 4 1.628e+07 10.570 39.090 0.750 3.769 2.000000e+11 1.892e+10 + 6 5 1.302e+07 10.310 39.040 0.690 3.854 2.000000e+11 1.940e+10 + 6 6 1.085e+07 10.260 39.030 0.700 3.872 2.000000e+11 1.949e+10 + 6 7 9.301e+06 10.170 39.020 0.680 3.904 2.000000e+11 1.967e+10 + 6 8 8.138e+06 10.150 39.020 0.670 3.910 2.000000e+11 1.970e+10 + 7 1 5.580e+07 11.440 39.730 1.500 3.604 2.000000e+11 1.748e+10 + 7 2 2.790e+07 10.950 39.260 0.990 3.676 2.000000e+11 1.826e+10 + 7 3 1.860e+07 10.620 39.140 0.860 3.766 2.000000e+11 1.883e+10 + 7 4 1.395e+07 10.420 39.070 0.750 3.821 2.000000e+11 1.919e+10 + 7 5 1.116e+07 10.290 39.040 0.710 3.863 2.000000e+11 1.944e+10 + 7 6 9.301e+06 10.200 39.040 0.720 3.898 2.000000e+11 1.961e+10 + 7 7 7.972e+06 10.210 39.020 0.670 3.887 2.000000e+11 1.959e+10 + 7 8 6.975e+06 10.160 39.020 0.650 3.905 2.000000e+11 1.969e+10 + 8 1 4.883e+07 10.870 39.950 1.520 3.815 2.000000e+11 1.840e+10 + 8 2 2.441e+07 10.690 39.270 1.000 3.767 2.000000e+11 1.871e+10 + 8 3 1.628e+07 10.540 39.130 0.860 3.794 2.000000e+11 1.898e+10 + 8 4 1.221e+07 10.410 39.110 0.790 3.833 2.000000e+11 1.921e+10 + 8 5 9.766e+06 10.230 39.040 0.710 3.886 2.000000e+11 1.955e+10 + 8 6 8.138e+06 10.260 39.050 0.700 3.874 2.000000e+11 1.949e+10 + 8 7 6.975e+06 10.220 39.100 0.690 3.893 2.000000e+11 1.957e+10 + 8 8 6.104e+06 10.170 39.020 0.650 3.901 2.000000e+11 1.967e+10 diff --git a/gnuradio-examples/python/mp-sched/perf-data/js21.dat b/gnuradio-examples/python/mp-sched/perf-data/js21.dat new file mode 100644 index 000000000..a23bcebe7 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/js21.dat @@ -0,0 +1,65 @@ +#D JS21 4-core PPC970MP 2.5 GHz + 1 1 5.273e+07 10.050 10.180 0.290 1.042 2.700000e+10 2.687e+09 + 1 2 5.273e+07 10.240 20.210 0.260 1.999 5.400000e+10 5.273e+09 + 1 3 5.273e+07 10.300 30.090 0.340 2.954 8.100000e+10 7.864e+09 + 1 4 5.273e+07 10.490 40.120 0.490 3.871 1.080000e+11 1.030e+10 + 1 5 4.219e+07 16.010 39.900 0.380 2.516 1.080000e+11 6.746e+09 + 1 6 3.516e+07 13.360 39.920 0.370 3.016 1.080000e+11 8.084e+09 + 1 7 3.013e+07 11.510 39.900 0.330 3.495 1.080000e+11 9.383e+09 + 1 8 2.637e+07 10.420 39.880 0.320 3.858 1.080000e+11 1.036e+10 + 2 1 5.273e+07 10.370 20.340 0.470 2.007 5.400000e+10 5.207e+09 + 2 2 5.273e+07 10.320 40.080 0.550 3.937 1.080000e+11 1.047e+10 + 2 3 3.516e+07 13.340 39.990 0.470 3.033 1.080000e+11 8.096e+09 + 2 4 2.637e+07 10.480 39.970 0.400 3.852 1.080000e+11 1.031e+10 + 2 5 2.109e+07 10.910 39.920 0.390 3.695 1.080000e+11 9.899e+09 + 2 6 1.758e+07 10.610 39.860 0.360 3.791 1.080000e+11 1.018e+10 + 2 7 1.507e+07 10.520 39.890 0.360 3.826 1.080000e+11 1.027e+10 + 2 8 1.318e+07 10.470 39.980 0.350 3.852 1.080000e+11 1.032e+10 + 3 1 5.273e+07 10.230 30.320 0.600 3.022 8.100000e+10 7.918e+09 + 3 2 3.516e+07 13.250 40.050 0.560 3.065 1.080000e+11 8.151e+09 + 3 3 2.344e+07 11.160 40.010 0.470 3.627 1.080000e+11 9.677e+09 + 3 4 1.758e+07 10.710 39.950 0.420 3.769 1.080000e+11 1.008e+10 + 3 5 1.406e+07 10.520 39.920 0.400 3.833 1.080000e+11 1.027e+10 + 3 6 1.172e+07 10.420 39.880 0.380 3.864 1.080000e+11 1.036e+10 + 3 7 1.004e+07 10.340 39.880 0.370 3.893 1.080000e+11 1.044e+10 + 3 8 8.789e+06 10.380 39.960 0.380 3.886 1.080000e+11 1.040e+10 + 4 1 5.273e+07 10.570 40.390 0.890 3.905 1.080000e+11 1.022e+10 + 4 2 2.637e+07 10.690 40.020 0.560 3.796 1.080000e+11 1.010e+10 + 4 3 1.758e+07 10.790 39.980 0.480 3.750 1.080000e+11 1.001e+10 + 4 4 1.318e+07 10.570 39.950 0.430 3.820 1.080000e+11 1.022e+10 + 4 5 1.055e+07 10.440 39.950 0.420 3.867 1.080000e+11 1.034e+10 + 4 6 8.789e+06 10.340 39.900 0.420 3.899 1.080000e+11 1.044e+10 + 4 7 7.533e+06 10.290 39.870 0.410 3.914 1.080000e+11 1.050e+10 + 4 8 6.592e+06 10.270 39.950 0.390 3.928 1.080000e+11 1.052e+10 + 5 1 4.219e+07 15.110 40.290 0.830 2.721 1.080000e+11 7.148e+09 + 5 2 2.109e+07 11.240 40.000 0.580 3.610 1.080000e+11 9.609e+09 + 5 3 1.406e+07 10.710 39.970 0.490 3.778 1.080000e+11 1.008e+10 + 5 4 1.055e+07 10.490 39.980 0.460 3.855 1.080000e+11 1.030e+10 + 5 5 8.438e+06 10.430 39.940 0.440 3.872 1.080000e+11 1.035e+10 + 5 6 7.031e+06 10.280 39.890 0.420 3.921 1.080000e+11 1.051e+10 + 5 7 6.027e+06 10.290 39.870 0.400 3.914 1.080000e+11 1.050e+10 + 5 8 5.273e+06 10.290 39.940 0.400 3.920 1.080000e+11 1.050e+10 + 6 1 3.516e+07 12.880 40.250 0.850 3.191 1.080000e+11 8.385e+09 + 6 2 1.758e+07 10.730 39.980 0.580 3.780 1.080000e+11 1.007e+10 + 6 3 1.172e+07 10.740 39.980 0.490 3.768 1.080000e+11 1.006e+10 + 6 4 8.789e+06 10.510 39.940 0.460 3.844 1.080000e+11 1.028e+10 + 6 5 7.031e+06 10.430 39.920 0.450 3.871 1.080000e+11 1.035e+10 + 6 6 5.859e+06 10.300 39.910 0.430 3.917 1.080000e+11 1.049e+10 + 6 7 5.022e+06 10.290 39.870 0.420 3.915 1.080000e+11 1.050e+10 + 6 8 4.395e+06 10.300 39.950 0.420 3.919 1.080000e+11 1.049e+10 + 7 1 3.013e+07 11.240 40.270 0.860 3.659 1.080000e+11 9.609e+09 + 7 2 1.507e+07 11.040 40.000 0.590 3.677 1.080000e+11 9.783e+09 + 7 3 1.004e+07 10.660 39.970 0.520 3.798 1.080000e+11 1.013e+10 + 7 4 7.533e+06 10.430 39.930 0.470 3.873 1.080000e+11 1.035e+10 + 7 5 6.027e+06 10.390 39.920 0.470 3.887 1.080000e+11 1.039e+10 + 7 6 5.022e+06 10.320 39.910 0.430 3.909 1.080000e+11 1.047e+10 + 7 7 4.305e+06 10.330 39.890 0.420 3.902 1.080000e+11 1.045e+10 + 7 8 3.767e+06 10.300 39.930 0.420 3.917 1.080000e+11 1.049e+10 + 8 1 2.637e+07 10.530 40.290 0.910 3.913 1.080000e+11 1.026e+10 + 8 2 1.318e+07 10.850 40.040 0.610 3.747 1.080000e+11 9.954e+09 + 8 3 8.789e+06 10.500 39.960 0.540 3.857 1.080000e+11 1.029e+10 + 8 4 6.592e+06 10.490 39.960 0.500 3.857 1.080000e+11 1.030e+10 + 8 5 5.273e+06 10.330 39.930 0.480 3.912 1.080000e+11 1.045e+10 + 8 6 4.395e+06 10.340 39.900 0.450 3.902 1.080000e+11 1.044e+10 + 8 7 3.767e+06 10.260 39.900 0.430 3.931 1.080000e+11 1.053e+10 + 8 8 3.296e+06 10.250 39.960 0.430 3.940 1.080000e+11 1.054e+10 diff --git a/gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat new file mode 100644 index 000000000..dd01b31bd --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat @@ -0,0 +1,65 @@ +#D Playstation 3 (using Altivec) + 1 1 3.906e+07 10.500 10.580 0.440 1.050 2.000000e+10 1.905e+09 + 1 2 1.953e+07 7.010 13.200 0.400 1.940 2.000000e+10 2.853e+09 + 1 3 1.302e+07 7.540 13.140 0.380 1.793 2.000000e+10 2.653e+09 + 1 4 9.766e+06 7.200 13.620 0.370 1.943 2.000000e+10 2.778e+09 + 1 5 7.812e+06 7.170 13.670 0.340 1.954 2.000000e+10 2.789e+09 + 1 6 6.510e+06 7.010 13.590 0.320 1.984 2.000000e+10 2.853e+09 + 1 7 5.580e+06 6.990 13.530 0.330 1.983 2.000000e+10 2.861e+09 + 1 8 4.883e+06 6.980 13.490 0.320 1.979 2.000000e+10 2.865e+09 + 2 1 1.953e+07 8.110 14.730 0.530 1.882 2.000000e+10 2.466e+09 + 2 2 9.766e+06 7.090 13.570 0.420 1.973 2.000000e+10 2.821e+09 + 2 3 6.510e+06 7.040 13.590 0.410 1.989 2.000000e+10 2.841e+09 + 2 4 4.883e+06 6.990 13.490 0.370 1.983 2.000000e+10 2.861e+09 + 2 5 3.906e+06 6.970 13.480 0.360 1.986 2.000000e+10 2.869e+09 + 2 6 3.255e+06 6.990 13.530 0.370 1.989 2.000000e+10 2.861e+09 + 2 7 2.790e+06 6.890 13.390 0.350 1.994 2.000000e+10 2.903e+09 + 2 8 2.441e+06 6.880 13.380 0.350 1.996 2.000000e+10 2.907e+09 + 3 1 1.302e+07 8.220 13.720 0.510 1.731 2.000000e+10 2.433e+09 + 3 2 6.510e+06 7.050 13.480 0.450 1.976 2.000000e+10 2.837e+09 + 3 3 4.340e+06 6.990 13.460 0.400 1.983 2.000000e+10 2.861e+09 + 3 4 3.255e+06 6.990 13.550 0.380 1.993 2.000000e+10 2.861e+09 + 3 5 2.604e+06 6.920 13.430 0.360 1.993 1.999999e+10 2.890e+09 + 3 6 2.170e+06 6.940 13.460 0.360 1.991 1.999999e+10 2.882e+09 + 3 7 1.860e+06 6.920 13.440 0.360 1.994 2.000000e+10 2.890e+09 + 3 8 1.628e+06 6.890 13.380 0.350 1.993 2.000000e+10 2.903e+09 + 4 1 9.766e+06 7.620 14.550 0.590 1.987 2.000000e+10 2.625e+09 + 4 2 4.883e+06 7.010 13.460 0.440 1.983 2.000000e+10 2.853e+09 + 4 3 3.255e+06 7.040 13.580 0.410 1.987 2.000000e+10 2.841e+09 + 4 4 2.441e+06 6.960 13.470 0.390 1.991 2.000000e+10 2.874e+09 + 4 5 1.953e+06 6.920 13.410 0.370 1.991 2.000000e+10 2.890e+09 + 4 6 1.628e+06 6.950 13.490 0.370 1.994 2.000000e+10 2.878e+09 + 4 7 1.395e+06 6.890 13.350 0.370 1.991 2.000000e+10 2.903e+09 + 4 8 1.221e+06 6.940 13.490 0.360 1.996 2.000000e+10 2.882e+09 + 5 1 7.812e+06 7.680 14.000 0.560 1.896 2.000000e+10 2.604e+09 + 5 2 3.906e+06 7.070 13.460 0.460 1.969 2.000000e+10 2.829e+09 + 5 3 2.604e+06 6.990 13.430 0.420 1.981 1.999999e+10 2.861e+09 + 5 4 1.953e+06 7.010 13.550 0.390 1.989 2.000000e+10 2.853e+09 + 5 5 1.562e+06 6.920 13.430 0.380 1.996 2.000000e+10 2.890e+09 + 5 6 1.302e+06 6.920 13.410 0.380 1.993 1.999999e+10 2.890e+09 + 5 7 1.116e+06 6.920 13.420 0.370 1.993 1.999999e+10 2.890e+09 + 5 8 9.766e+05 6.910 13.360 0.370 1.987 1.999999e+10 2.894e+09 + 6 1 6.510e+06 7.350 13.970 0.630 1.986 2.000000e+10 2.721e+09 + 6 2 3.255e+06 7.040 13.470 0.470 1.980 2.000000e+10 2.841e+09 + 6 3 2.170e+06 7.050 13.600 0.420 1.989 1.999999e+10 2.837e+09 + 6 4 1.628e+06 6.970 13.480 0.400 1.991 2.000000e+10 2.869e+09 + 6 5 1.302e+06 6.990 13.540 0.390 1.993 1.999999e+10 2.861e+09 + 6 6 1.085e+06 6.970 13.470 0.380 1.987 1.999999e+10 2.869e+09 + 6 7 9.301e+05 6.890 13.350 0.380 1.993 1.999999e+10 2.903e+09 + 6 8 8.138e+05 6.920 13.420 0.370 1.993 2.000000e+10 2.890e+09 + 7 1 5.580e+06 7.530 14.030 0.580 1.940 2.000000e+10 2.656e+09 + 7 2 2.790e+06 7.000 13.370 0.460 1.976 2.000000e+10 2.857e+09 + 7 3 1.860e+06 7.000 13.520 0.420 1.991 2.000000e+10 2.857e+09 + 7 4 1.395e+06 7.060 13.590 0.410 1.983 2.000000e+10 2.833e+09 + 7 5 1.116e+06 6.950 13.460 0.390 1.993 1.999999e+10 2.878e+09 + 7 6 9.301e+05 6.950 13.420 0.380 1.986 1.999999e+10 2.878e+09 + 7 7 7.972e+05 6.880 13.300 0.380 1.988 1.999998e+10 2.907e+09 + 7 8 6.975e+05 6.920 13.390 0.380 1.990 1.999998e+10 2.890e+09 + 8 1 4.883e+06 7.440 14.150 0.620 1.985 2.000000e+10 2.688e+09 + 8 2 2.441e+06 6.990 13.400 0.480 1.986 2.000000e+10 2.861e+09 + 8 3 1.628e+06 6.990 13.460 0.430 1.987 2.000000e+10 2.861e+09 + 8 4 1.221e+06 7.020 13.550 0.410 1.989 2.000000e+10 2.849e+09 + 8 5 9.766e+05 6.920 13.370 0.390 1.988 1.999999e+10 2.890e+09 + 8 6 8.138e+05 6.950 13.400 0.390 1.984 2.000000e+10 2.878e+09 + 8 7 6.975e+05 6.930 13.360 0.390 1.984 1.999998e+10 2.886e+09 + 8 8 6.104e+05 6.920 13.390 0.380 1.990 1.999998e+10 2.890e+09 diff --git a/gnuradio-examples/python/mp-sched/perf-data/ps3.dat b/gnuradio-examples/python/mp-sched/perf-data/ps3.dat new file mode 100644 index 000000000..c9bac37cc --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/ps3.dat @@ -0,0 +1,65 @@ +#D Playstation 3 + 1 1 2.344e+07 9.970 9.960 0.280 1.027 1.200000e+10 1.204e+09 + 1 2 1.172e+07 12.590 24.430 0.400 1.972 1.200000e+10 9.531e+08 + 1 3 7.812e+06 12.200 22.790 0.360 1.898 1.200000e+10 9.836e+08 + 1 4 5.859e+06 12.450 24.440 0.360 1.992 1.200000e+10 9.639e+08 + 1 5 4.688e+06 12.390 24.100 0.360 1.974 1.200000e+10 9.685e+08 + 1 6 3.906e+06 12.360 24.200 0.370 1.988 1.200000e+10 9.709e+08 + 1 7 3.348e+06 12.460 24.390 0.360 1.986 1.200000e+10 9.631e+08 + 1 8 2.930e+06 12.440 24.400 0.360 1.990 1.200000e+10 9.646e+08 + 2 1 1.172e+07 12.580 24.660 0.490 1.999 1.200000e+10 9.539e+08 + 2 2 5.859e+06 12.480 24.290 0.420 1.980 1.200000e+10 9.615e+08 + 2 3 3.906e+06 12.500 24.500 0.400 1.992 1.200000e+10 9.600e+08 + 2 4 2.930e+06 12.440 24.400 0.390 1.993 1.200000e+10 9.646e+08 + 2 5 2.344e+06 12.500 24.510 0.380 1.991 1.200000e+10 9.600e+08 + 2 6 1.953e+06 12.450 24.480 0.380 1.997 1.200000e+10 9.639e+08 + 2 7 1.674e+06 12.450 24.430 0.380 1.993 1.200000e+10 9.639e+08 + 2 8 1.465e+06 12.430 24.450 0.380 1.998 1.199999e+10 9.654e+08 + 3 1 7.812e+06 12.280 23.600 0.460 1.959 1.200000e+10 9.772e+08 + 3 2 3.906e+06 12.690 24.760 0.430 1.985 1.200000e+10 9.456e+08 + 3 3 2.604e+06 12.610 24.700 0.410 1.991 1.200000e+10 9.516e+08 + 3 4 1.953e+06 12.440 24.410 0.400 1.994 1.200000e+10 9.646e+08 + 3 5 1.562e+06 12.400 24.370 0.380 1.996 1.200000e+10 9.677e+08 + 3 6 1.302e+06 12.440 24.450 0.380 1.996 1.200000e+10 9.646e+08 + 3 7 1.116e+06 12.470 24.470 0.380 1.993 1.200000e+10 9.623e+08 + 3 8 9.766e+05 12.440 24.440 0.380 1.995 1.199999e+10 9.646e+08 + 4 1 5.859e+06 12.670 24.710 0.500 1.990 1.200000e+10 9.471e+08 + 4 2 2.930e+06 12.600 24.600 0.440 1.987 1.200000e+10 9.524e+08 + 4 3 1.953e+06 12.490 24.480 0.410 1.993 1.200000e+10 9.608e+08 + 4 4 1.465e+06 12.400 24.340 0.400 1.995 1.199999e+10 9.677e+08 + 4 5 1.172e+06 12.440 24.410 0.390 1.994 1.200000e+10 9.646e+08 + 4 6 9.766e+05 12.440 24.440 0.390 1.996 1.199999e+10 9.646e+08 + 4 7 8.371e+05 12.450 24.420 0.390 1.993 1.199999e+10 9.639e+08 + 4 8 7.324e+05 12.370 24.310 0.380 1.996 1.199999e+10 9.701e+08 + 5 1 4.688e+06 12.890 24.790 0.500 1.962 1.200000e+10 9.310e+08 + 5 2 2.344e+06 12.620 24.680 0.450 1.991 1.200000e+10 9.509e+08 + 5 3 1.562e+06 12.430 24.360 0.410 1.993 1.200000e+10 9.654e+08 + 5 4 1.172e+06 12.420 24.390 0.410 1.997 1.200000e+10 9.662e+08 + 5 5 9.375e+05 12.430 24.380 0.400 1.994 1.200000e+10 9.654e+08 + 5 6 7.812e+05 12.400 24.340 0.400 1.995 1.200000e+10 9.677e+08 + 5 7 6.696e+05 12.360 24.290 0.390 1.997 1.199998e+10 9.709e+08 + 5 8 5.859e+05 12.420 24.370 0.390 1.994 1.199999e+10 9.662e+08 + 6 1 3.906e+06 12.990 25.320 0.560 1.992 1.200000e+10 9.238e+08 + 6 2 1.953e+06 12.610 24.550 0.440 1.982 1.200000e+10 9.516e+08 + 6 3 1.302e+06 12.520 24.310 0.420 1.975 1.200000e+10 9.585e+08 + 6 4 9.766e+05 12.460 24.310 0.420 1.985 1.199999e+10 9.631e+08 + 6 5 7.812e+05 12.440 24.240 0.410 1.982 1.200000e+10 9.646e+08 + 6 6 6.510e+05 12.430 24.170 0.410 1.977 1.199999e+10 9.654e+08 + 6 7 5.580e+05 12.450 24.230 0.410 1.979 1.199998e+10 9.639e+08 + 6 8 4.883e+05 12.490 24.190 0.420 1.970 1.199999e+10 9.608e+08 + 7 1 3.348e+06 13.150 24.280 0.500 1.884 1.200000e+10 9.125e+08 + 7 2 1.674e+06 12.480 24.170 0.430 1.971 1.200000e+10 9.615e+08 + 7 3 1.116e+06 12.480 24.430 0.440 1.993 1.200000e+10 9.615e+08 + 7 4 8.371e+05 12.380 24.270 0.420 1.994 1.199999e+10 9.693e+08 + 7 5 6.696e+05 12.390 24.290 0.430 1.995 1.199998e+10 9.685e+08 + 7 6 5.580e+05 12.430 24.300 0.430 1.990 1.199998e+10 9.654e+08 + 7 7 4.783e+05 12.460 24.360 0.430 1.990 1.199999e+10 9.631e+08 + 7 8 4.185e+05 12.460 24.340 0.430 1.988 1.199998e+10 9.631e+08 + 8 1 2.930e+06 12.960 24.600 0.530 1.939 1.200000e+10 9.259e+08 + 8 2 1.465e+06 12.580 24.240 0.440 1.962 1.199999e+10 9.539e+08 + 8 3 9.766e+05 12.520 24.060 0.430 1.956 1.199999e+10 9.585e+08 + 8 4 7.324e+05 12.420 24.200 0.410 1.981 1.199999e+10 9.662e+08 + 8 5 5.859e+05 12.430 24.310 0.430 1.990 1.199999e+10 9.654e+08 + 8 6 4.883e+05 12.430 24.130 0.420 1.975 1.199999e+10 9.654e+08 + 8 7 4.185e+05 12.800 24.220 0.490 1.930 1.199998e+10 9.375e+08 + 8 8 3.662e+05 12.460 24.340 0.430 1.988 1.199997e+10 9.631e+08 diff --git a/gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat b/gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat new file mode 100644 index 000000000..8364be363 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat @@ -0,0 +1,65 @@ +#D QS21 dual cell 3.2 GHz (using Altivec) + 1 1 3.516e+07 9.810 10.240 0.430 1.088 1.800000e+10 1.835e+09 + 1 2 3.516e+07 11.650 22.840 0.750 2.025 3.600000e+10 3.090e+09 + 1 3 2.344e+07 9.400 24.860 0.680 2.717 3.600000e+10 3.830e+09 + 1 4 1.758e+07 7.800 26.820 0.740 3.533 3.600000e+10 4.615e+09 + 1 5 1.406e+07 8.810 25.970 0.760 3.034 3.600000e+10 4.086e+09 + 1 6 1.172e+07 8.110 25.710 0.740 3.261 3.600000e+10 4.439e+09 + 1 7 1.004e+07 7.750 26.020 0.710 3.449 3.600000e+10 4.645e+09 + 1 8 8.789e+06 7.290 26.600 0.690 3.743 3.600000e+10 4.938e+09 + 2 1 3.516e+07 10.130 20.690 0.770 2.118 3.600000e+10 3.554e+09 + 2 2 1.758e+07 7.240 26.820 0.920 3.831 3.600000e+10 4.972e+09 + 2 3 1.172e+07 8.090 26.670 0.840 3.400 3.600000e+10 4.450e+09 + 2 4 8.789e+06 7.480 27.010 0.790 3.717 3.600000e+10 4.813e+09 + 2 5 7.031e+06 7.180 26.530 0.740 3.798 3.600000e+10 5.014e+09 + 2 6 5.859e+06 7.060 26.590 0.730 3.870 3.600000e+10 5.099e+09 + 2 7 5.022e+06 7.040 26.610 0.740 3.885 3.600000e+10 5.114e+09 + 2 8 4.395e+06 7.090 27.020 0.730 3.914 3.600000e+10 5.078e+09 + 3 1 2.344e+07 9.670 25.850 1.020 2.779 3.600000e+10 3.723e+09 + 3 2 1.172e+07 7.700 25.940 0.930 3.490 3.600000e+10 4.675e+09 + 3 3 7.812e+06 7.290 26.760 0.830 3.785 3.600000e+10 4.938e+09 + 3 4 5.859e+06 7.210 26.900 0.800 3.842 3.600000e+10 4.993e+09 + 3 5 4.688e+06 7.060 26.690 0.770 3.890 3.600000e+10 5.099e+09 + 3 6 3.906e+06 7.060 26.830 0.810 3.915 3.600000e+10 5.099e+09 + 3 7 3.348e+06 6.960 26.680 0.780 3.945 3.600000e+10 5.172e+09 + 3 8 2.930e+06 6.960 26.600 0.770 3.932 3.599999e+10 5.172e+09 + 4 1 1.758e+07 7.640 28.700 1.250 3.920 3.600000e+10 4.712e+09 + 4 2 8.789e+06 7.230 26.640 0.940 3.815 3.600000e+10 4.979e+09 + 4 3 5.859e+06 7.200 26.800 0.860 3.842 3.600000e+10 5.000e+09 + 4 4 4.395e+06 7.110 26.900 0.840 3.902 3.600000e+10 5.063e+09 + 4 5 3.516e+06 7.020 26.680 0.800 3.915 3.600000e+10 5.128e+09 + 4 6 2.930e+06 6.950 26.700 0.800 3.957 3.599999e+10 5.180e+09 + 4 7 2.511e+06 6.930 26.590 0.800 3.952 3.599999e+10 5.195e+09 + 4 8 2.197e+06 6.960 26.570 0.790 3.931 3.599999e+10 5.172e+09 + 5 1 1.406e+07 8.730 26.540 1.190 3.176 3.600000e+10 4.124e+09 + 5 2 7.031e+06 7.270 26.450 0.960 3.770 3.600000e+10 4.952e+09 + 5 3 4.688e+06 7.100 26.630 0.880 3.875 3.600000e+10 5.070e+09 + 5 4 3.516e+06 7.050 26.700 0.850 3.908 3.600000e+10 5.106e+09 + 5 5 2.812e+06 6.970 26.610 0.830 3.937 3.600000e+10 5.165e+09 + 5 6 2.344e+06 6.980 26.710 0.840 3.947 3.600000e+10 5.158e+09 + 5 7 2.009e+06 6.900 26.470 0.800 3.952 3.599999e+10 5.217e+09 + 5 8 1.758e+06 6.940 26.580 0.820 3.948 3.599999e+10 5.187e+09 + 6 1 1.172e+07 8.200 26.510 1.190 3.378 3.600000e+10 4.390e+09 + 6 2 5.859e+06 7.210 26.590 0.970 3.822 3.600000e+10 4.993e+09 + 6 3 3.906e+06 7.070 26.580 0.910 3.888 3.600000e+10 5.092e+09 + 6 4 2.930e+06 7.090 26.750 0.860 3.894 3.599999e+10 5.078e+09 + 6 5 2.344e+06 7.040 26.830 0.830 3.929 3.600000e+10 5.114e+09 + 6 6 1.953e+06 6.960 26.600 0.830 3.941 3.600000e+10 5.172e+09 + 6 7 1.674e+06 6.940 26.500 0.810 3.935 3.600000e+10 5.187e+09 + 6 8 1.465e+06 6.940 26.540 0.830 3.944 3.599998e+10 5.187e+09 + 7 1 1.004e+07 7.730 26.940 1.190 3.639 3.600000e+10 4.657e+09 + 7 2 5.022e+06 7.240 26.600 0.980 3.809 3.600000e+10 4.972e+09 + 7 3 3.348e+06 7.120 26.680 0.930 3.878 3.600000e+10 5.056e+09 + 7 4 2.511e+06 7.070 26.840 0.890 3.922 3.599999e+10 5.092e+09 + 7 5 2.009e+06 6.980 26.570 0.850 3.928 3.599999e+10 5.158e+09 + 7 6 1.674e+06 6.950 26.530 0.840 3.938 3.600000e+10 5.180e+09 + 7 7 1.435e+06 6.940 26.570 0.860 3.952 3.599998e+10 5.187e+09 + 7 8 1.256e+06 6.980 26.590 0.840 3.930 3.599999e+10 5.158e+09 + 8 1 8.789e+06 7.570 27.360 1.260 3.781 3.600000e+10 4.756e+09 + 8 2 4.395e+06 7.130 26.460 0.980 3.849 3.600000e+10 5.049e+09 + 8 3 2.930e+06 7.060 26.680 0.920 3.909 3.599999e+10 5.099e+09 + 8 4 2.197e+06 7.040 26.670 0.880 3.913 3.599999e+10 5.114e+09 + 8 5 1.758e+06 6.970 26.600 0.860 3.940 3.599999e+10 5.165e+09 + 8 6 1.465e+06 6.940 26.490 0.840 3.938 3.599998e+10 5.187e+09 + 8 7 1.256e+06 6.980 26.630 0.850 3.937 3.599999e+10 5.158e+09 + 8 8 1.099e+06 7.010 26.820 0.860 3.949 3.599997e+10 5.136e+09 diff --git a/gnuradio-examples/python/mp-sched/perf-data/qs21.dat b/gnuradio-examples/python/mp-sched/perf-data/qs21.dat new file mode 100644 index 000000000..cc628740a --- /dev/null +++ b/gnuradio-examples/python/mp-sched/perf-data/qs21.dat @@ -0,0 +1,65 @@ +#D QS21 dual cell 3.2 GHz + 1 1 1.953e+07 8.480 8.730 0.270 1.061 1.000000e+10 1.179e+09 + 1 2 1.953e+07 8.750 17.210 0.460 2.019 2.000000e+10 2.286e+09 + 1 3 1.302e+07 12.390 29.530 0.540 2.427 2.000000e+10 1.614e+09 + 1 4 9.766e+06 10.120 31.500 0.590 3.171 2.000000e+10 1.976e+09 + 1 5 7.812e+06 10.200 31.350 0.610 3.133 2.000000e+10 1.961e+09 + 1 6 6.510e+06 9.520 31.690 0.590 3.391 2.000000e+10 2.101e+09 + 1 7 5.580e+06 9.430 32.610 0.600 3.522 2.000000e+10 2.121e+09 + 1 8 4.883e+06 9.400 34.160 0.620 3.700 2.000000e+10 2.128e+09 + 2 1 1.953e+07 8.800 17.750 0.500 2.074 2.000000e+10 2.273e+09 + 2 2 9.766e+06 8.990 28.900 0.640 3.286 2.000000e+10 2.225e+09 + 2 3 6.510e+06 9.390 32.450 0.660 3.526 2.000000e+10 2.130e+09 + 2 4 4.883e+06 9.220 34.450 0.660 3.808 2.000000e+10 2.169e+09 + 2 5 3.906e+06 9.180 34.730 0.650 3.854 2.000000e+10 2.179e+09 + 2 6 3.255e+06 9.150 34.960 0.650 3.892 2.000000e+10 2.186e+09 + 2 7 2.790e+06 9.140 35.290 0.650 3.932 2.000000e+10 2.188e+09 + 2 8 2.441e+06 9.080 35.240 0.650 3.953 2.000000e+10 2.203e+09 + 3 1 1.302e+07 11.720 28.890 0.740 2.528 2.000000e+10 1.706e+09 + 3 2 6.510e+06 9.390 32.700 0.730 3.560 2.000000e+10 2.130e+09 + 3 3 4.340e+06 9.150 33.930 0.690 3.784 2.000000e+10 2.186e+09 + 3 4 3.255e+06 9.040 34.650 0.680 3.908 2.000000e+10 2.212e+09 + 3 5 2.604e+06 9.090 34.990 0.680 3.924 1.999999e+10 2.200e+09 + 3 6 2.170e+06 9.050 34.870 0.670 3.927 1.999999e+10 2.210e+09 + 3 7 1.860e+06 9.010 34.850 0.660 3.941 2.000000e+10 2.220e+09 + 3 8 1.628e+06 8.980 34.860 0.670 3.957 2.000000e+10 2.227e+09 + 4 1 9.766e+06 9.000 34.680 0.940 3.958 2.000000e+10 2.222e+09 + 4 2 4.883e+06 9.020 34.180 0.740 3.871 2.000000e+10 2.217e+09 + 4 3 3.255e+06 9.150 34.640 0.710 3.863 2.000000e+10 2.186e+09 + 4 4 2.441e+06 9.010 34.780 0.690 3.937 2.000000e+10 2.220e+09 + 4 5 1.953e+06 8.980 34.680 0.690 3.939 2.000000e+10 2.227e+09 + 4 6 1.628e+06 9.050 35.120 0.690 3.957 2.000000e+10 2.210e+09 + 4 7 1.395e+06 9.010 34.900 0.670 3.948 2.000000e+10 2.220e+09 + 4 8 1.221e+06 8.960 34.900 0.680 3.971 2.000000e+10 2.232e+09 + 5 1 7.812e+06 10.150 31.760 0.840 3.212 2.000000e+10 1.970e+09 + 5 2 3.906e+06 9.090 34.040 0.750 3.827 2.000000e+10 2.200e+09 + 5 3 2.604e+06 9.030 34.650 0.720 3.917 1.999999e+10 2.215e+09 + 5 4 1.953e+06 8.990 34.610 0.700 3.928 2.000000e+10 2.225e+09 + 5 5 1.562e+06 9.000 34.920 0.700 3.958 2.000000e+10 2.222e+09 + 5 6 1.302e+06 9.120 35.370 0.690 3.954 1.999999e+10 2.193e+09 + 5 7 1.116e+06 8.910 34.680 0.690 3.970 1.999999e+10 2.245e+09 + 5 8 9.766e+05 8.930 34.790 0.680 3.972 1.999999e+10 2.240e+09 + 6 1 6.510e+06 9.390 31.810 0.840 3.477 2.000000e+10 2.130e+09 + 6 2 3.255e+06 9.000 34.320 0.760 3.898 2.000000e+10 2.222e+09 + 6 3 2.170e+06 8.960 34.310 0.740 3.912 1.999999e+10 2.232e+09 + 6 4 1.628e+06 8.970 34.640 0.730 3.943 2.000000e+10 2.230e+09 + 6 5 1.302e+06 9.110 35.360 0.710 3.959 1.999999e+10 2.195e+09 + 6 6 1.085e+06 8.970 34.750 0.710 3.953 1.999999e+10 2.230e+09 + 6 7 9.301e+05 8.950 34.710 0.700 3.956 1.999999e+10 2.235e+09 + 6 8 8.138e+05 8.920 34.570 0.710 3.955 2.000000e+10 2.242e+09 + 7 1 5.580e+06 9.290 32.840 0.870 3.629 2.000000e+10 2.153e+09 + 7 2 2.790e+06 9.040 34.400 0.770 3.890 2.000000e+10 2.212e+09 + 7 3 1.860e+06 8.940 34.380 0.740 3.928 2.000000e+10 2.237e+09 + 7 4 1.395e+06 8.990 34.820 0.730 3.954 2.000000e+10 2.225e+09 + 7 5 1.116e+06 8.990 34.820 0.720 3.953 1.999999e+10 2.225e+09 + 7 6 9.301e+05 8.940 34.720 0.720 3.964 1.999999e+10 2.237e+09 + 7 7 7.972e+05 8.930 34.700 0.710 3.965 1.999998e+10 2.240e+09 + 7 8 6.975e+05 8.910 34.510 0.700 3.952 1.999998e+10 2.245e+09 + 8 1 4.883e+06 9.070 33.770 0.910 3.824 2.000000e+10 2.205e+09 + 8 2 2.441e+06 9.000 34.340 0.780 3.902 2.000000e+10 2.222e+09 + 8 3 1.628e+06 8.990 34.510 0.740 3.921 2.000000e+10 2.225e+09 + 8 4 1.221e+06 8.980 34.650 0.740 3.941 2.000000e+10 2.227e+09 + 8 5 9.766e+05 8.960 34.700 0.720 3.953 1.999999e+10 2.232e+09 + 8 6 8.138e+05 8.920 34.680 0.710 3.967 2.000000e+10 2.242e+09 + 8 7 6.975e+05 8.900 34.580 0.720 3.966 1.999998e+10 2.247e+09 + 8 8 6.104e+05 8.930 34.590 0.710 3.953 1.999998e+10 2.240e+09 diff --git a/gnuradio-examples/python/mp-sched/plot_flops.py b/gnuradio-examples/python/mp-sched/plot_flops.py new file mode 100755 index 000000000..b3f819397 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/plot_flops.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +""" +Reads output from run_synthetic.py and runs gnuplot showing +GFLOPS as f(npipes, nstages) +""" + +import re +import sys +import os +import tempfile +from optparse import OptionParser + + +def parse_file(input_filename, output): + last = None + desc = '' + for line in open(input_filename, 'r'): + s = line.strip() + if s.startswith('>>>'): # ignore ">>> using SSE cruft" + continue + + if s.startswith('#D'): # machine description + desc = s[2:].strip() + continue + + fields = s.split() + npipes, nstages, flops = fields[0], fields[1], fields[8] + + if last is not None and npipes != last: + output.write('\n') + last = npipes + + output.write(' '.join((npipes, nstages, flops))) + output.write('\n') + + output.flush() + return desc + + +def handle_file(input_filename): + cmd_file = tempfile.NamedTemporaryFile(mode='w+', prefix='pf', suffix='.cmd') + cmd_file_name = cmd_file.name + data_file = tempfile.NamedTemporaryFile(mode='w+', prefix='pf', suffix='.dat') + data_file_name = data_file.name + desc = parse_file(input_filename, data_file) + if len(desc) > 0: + cmd_file.write("set title '%s'\n" % (desc,)) + cmd_file.write("set xlabel 'N pipes'\n") + cmd_file.write("set ylabel 'N stages'\n") + cmd_file.write("set zlabel 'GFLOPS'\n") + cmd_file.write("set key off\n") + cmd_file.write("set view 60, 312\n") + cmd_file.write("set pm3d\n") + cmd_file.write("splot '%s' using 1:2:($3*1e-9) with pm3d at b, '%s' using 1:2:($3*1e-9) with pm3d\n" % ( + data_file_name, data_file_name)) + + cmd_file.flush() + data_file.flush() + + os.system("gnuplot " + cmd_file_name + " -") + + #sys.stdout.write(open(cmd_file_name,'r').read()) + #sys.stdout.write(open(data_file_name,'r').read()) + + +def main(): + usage = "usage: %prog [options] file.dat" + parser = OptionParser(usage=usage) + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + raise SystemExit, 1 + + handle_file(args[0]) + + +if __name__ == '__main__': + main() diff --git a/gnuradio-examples/python/mp-sched/run_synthetic.py b/gnuradio-examples/python/mp-sched/run_synthetic.py new file mode 100755 index 000000000..565e6c5c7 --- /dev/null +++ b/gnuradio-examples/python/mp-sched/run_synthetic.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +""" +Run synthetic.py for npipes in [1,16], nstages in [1,16] +""" + +import re +import sys +import os +import tempfile +from optparse import OptionParser + + +def write_shell_script(f, data_filename, description, ncores, gflops, max_pipes_and_stages): + """ + f is the file to write the script to + data_filename is the where the data ends up + description describes the machine + ncores is the number of cores (used to size the workload) + gflops is the estimated GFLOPS per core (used to size the workload) + """ + + f.write("#!/bin/sh\n") + f.write("(\n") + if description: + f.write("echo '#D %s'\n" % (description,)) + + for npipes in range(1, max_pipes_and_stages + 1): + for nstages in range(1, max_pipes_and_stages + 1): + # We'd like each run of synthetic to take ~10 seconds + desired_time_per_run = 10 + est_gflops_avail = min(nstages * npipes, ncores) * gflops + nsamples = (est_gflops_avail * desired_time_per_run)/(512.0 * nstages * npipes) + nsamples = int(nsamples * 1e9) + + cmd = "./synthetic.py -m -s %d -p %d -N %d\n" % (nstages, npipes, nsamples) + f.write(cmd) + f.write('if test $? -ge 128; then exit 128; fi\n') + + f.write(") 2>&1 | grep --line-buffered -v '^>>>' | tee %s\n" % (data_filename,)) + f.flush() + + + +def main(): + description = """%prog gathers multiprocessor scaling data using the ./synthetic.py benchmark. +All combinations of npipes and nstages between 1 and --max-pipes-and-stages are tried. +The -n and -f options provides hints used to size the workload. We'd like each run +of synthetic to take about 10 seconds. For the full 16x16 case this results in a +total runtime of about 43 minutes, assuming that your values for -n and -f are reasonable. +For x86 machines, assume 3 FLOPS per processor Hz. E.g., 3 GHz machine -> 9 GFLOPS. +plot_flops.py will make pretty graphs from the output data generated by %prog. +""" + usage = "usage: %prog [options] output.dat" + parser = OptionParser(usage=usage, description=description) + parser.add_option("-d", "--description", metavar="DESC", + help="machine description, e.g., \"Dual quad-core Xeon 3 GHz\"", default=None) + parser.add_option("-n", "--ncores", type="int", default=1, + help="number of processor cores [default=%default]") + parser.add_option("-g", "--gflops", metavar="GFLOPS", type="float", default=3.0, + help="estimated GFLOPS per core [default=%default]") + parser.add_option("-m", "--max-pipes-and-stages", metavar="MAX", type="int", default=16, + help="maximum number of pipes and stages to use [default=%default]") + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + raise SystemExit, 1 + + output_filename = args[0] + + shell = os.popen("/bin/sh", "w") + + write_shell_script(shell, + output_filename, + options.description, + options.ncores, + options.gflops, + options.max_pipes_and_stages) + +if __name__ == '__main__': + main() + diff --git a/gnuradio-examples/python/mp-sched/synthetic.py b/gnuradio-examples/python/mp-sched/synthetic.py new file mode 100755 index 000000000..e1fcb20bd --- /dev/null +++ b/gnuradio-examples/python/mp-sched/synthetic.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +from gnuradio import gr, gru, eng_notation, blks2 +from gnuradio.eng_option import eng_option +from optparse import OptionParser +import os + + +class pipeline(gr.hier_block2): + def __init__(self, nstages, ntaps=256): + """ + Create a pipeline of nstages of gr.fir_filter_fff's connected in serial + terminating in a gr.null_sink. + """ + gr.hier_block2.__init__(self, "pipeline", + gr.io_signature(1, 1, gr.sizeof_float), + gr.io_signature(0, 0, 0)) + taps = ntaps*[1.0/ntaps] + upstream = self + for i in range(nstages): + op = gr.fir_filter_fff(1, taps) + self.connect(upstream, op) + upstream = op + + self.connect(upstream, gr.null_sink(gr.sizeof_float)) + + +class top(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + default_nsamples = 10e6 + parser=OptionParser(option_class=eng_option) + parser.add_option("-p", "--npipelines", type="intx", default=1, + metavar="NPIPES", help="the number of pipelines to create (default=%default)") + parser.add_option("-s", "--nstages", type="intx", default=1, + metavar="NSTAGES", help="the number of stages in each pipeline (default=%default)") + parser.add_option("-N", "--nsamples", type="eng_float", default=default_nsamples, + help=("the number of samples to run through the graph (default=%s)" % + (eng_notation.num_to_str(default_nsamples)))) + parser.add_option("-m", "--machine-readable", action="store_true", default=False, + help="enable machine readable output") + + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + raise SystemExit, 1 + + self.npipes = options.npipelines + self.nstages = options.nstages + self.nsamples = options.nsamples + self.machine_readable = options.machine_readable + + ntaps = 256 + + # Something vaguely like floating point ops + self.flop = 2 * ntaps * options.npipelines * options.nstages * options.nsamples + + src = gr.null_source(gr.sizeof_float) + head = gr.head(gr.sizeof_float, int(options.nsamples)) + self.connect(src, head) + + for n in range(options.npipelines): + self.connect(head, pipeline(options.nstages, ntaps)) + + +def time_it(tb): + start = os.times() + tb.run() + stop = os.times() + delta = map((lambda a, b: a-b), stop, start) + user, sys, childrens_user, childrens_sys, real = delta + total_user = user + childrens_user + total_sys = sys + childrens_sys + if tb.machine_readable: + print "%3d %3d %.3e %7.3f %7.3f %7.3f %7.3f %.6e %.3e" % ( + tb.npipes, tb.nstages, tb.nsamples, real, total_user, total_sys, (total_user+total_sys)/real, tb.flop, tb.flop/real) + else: + print "npipes %7d" % (tb.npipes,) + print "nstages %7d" % (tb.nstages,) + print "nsamples %s" % (eng_notation.num_to_str(tb.nsamples),) + print "real %7.3f" % (real,) + print "user %7.3f" % (total_user,) + print "sys %7.3f" % (total_sys,) + print "(user+sys)/real %7.3f" % ((total_user + total_sys)/real,) + print "pseudo_flop %s" % (eng_notation.num_to_str(tb.flop),) + print "pseudo_flop/real %s" % (eng_notation.num_to_str(tb.flop/real),) + + +if __name__ == "__main__": + try: + tb = top() + time_it(tb) + except KeyboardInterrupt: + raise SystemExit, 128 + + + + diff --git a/gr-pager/src/Makefile.am b/gr-pager/src/Makefile.am index 5c70db2f5..d0245444a 100644 --- a/gr-pager/src/Makefile.am +++ b/gr-pager/src/Makefile.am @@ -71,8 +71,9 @@ BUILT_SOURCES = \ ourpython_PYTHON = \ __init__.py \ pager_swig.py \ + pager_utils.py \ flex_demod.py - + ourlib_LTLIBRARIES = _pager_swig.la # These are the source files that go into the shared library diff --git a/gr-pager/src/__init__.py b/gr-pager/src/__init__.py index 6ef60d939..664b79942 100644 --- a/gr-pager/src/__init__.py +++ b/gr-pager/src/__init__.py @@ -23,3 +23,4 @@ from pager_swig import * from flex_demod import flex_demod +from pager_utils import * diff --git a/gr-pager/src/pager_utils.py b/gr-pager/src/pager_utils.py new file mode 100644 index 000000000..bbcb633fd --- /dev/null +++ b/gr-pager/src/pager_utils.py @@ -0,0 +1,47 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +import gnuradio.gr.gr_threading as _threading + +def make_trans_table(): + table = 256 * ['.'] + for i in range(256): + if (i < 32): + table[i] = '.' + else: + table[i] = chr(i) + return ''.join(table) + +_trans_table = make_trans_table() + +def make_printable(s): + return s.translate(_trans_table) + +class top_block_runner(_threading.Thread): + def __init__(self, tb): + _threading.Thread.__init__(self) + self.setDaemon(1) + self.tb = tb + self.done = False + self.start() + + def run(self): + self.tb.run() + self.done = True diff --git a/gr-pager/src/usrp_flex.py b/gr-pager/src/usrp_flex.py index f636030e9..6e09b3df6 100755 --- a/gr-pager/src/usrp_flex.py +++ b/gr-pager/src/usrp_flex.py @@ -160,27 +160,24 @@ def main(): # Flow graph emits pages into message queue queue = gr.msg_queue() tb = app_top_block(options, queue) + runner = pager.top_block_runner(tb) try: - tb.start() while 1: if not queue.empty_p(): msg = queue.delete_head() # Blocking read page = join(split(msg.to_string(), chr(128)), '|') - disp = [] - for n in range(len(page)): - if ord(page[n]) < 32: - disp.append('.') - else: - disp.append(page[n]) - print join(disp, '') + s = pager.make_printable(page) + print s tb.adjust_freq() - + elif runner.done: + break else: time.sleep(1) except KeyboardInterrupt: tb.stop() + runner = None if __name__ == "__main__": main() diff --git a/gr-pager/src/usrp_flex_all.py b/gr-pager/src/usrp_flex_all.py index daee3532c..b37c6a5da 100755 --- a/gr-pager/src/usrp_flex_all.py +++ b/gr-pager/src/usrp_flex_all.py @@ -77,25 +77,22 @@ def main(): queue = gr.msg_queue() tb = app_top_block(options, queue) + runner = pager.top_block_runner(tb) try: - tb.start() while 1: if not queue.empty_p(): msg = queue.delete_head() # Blocking read page = join(split(msg.to_string(), chr(128)), '|') - disp = [] - for n in range(len(page)): - if ord(page[n]) < 32: - disp.append('.') - else: - disp.append(page[n]) - print join(disp, '') - + s = pager.make_printable(page) + print s + elif runner.done: + break else: - time.sleep(1) + time.sleep(0.05) except KeyboardInterrupt: tb.stop() + runner = None if __name__ == "__main__": main() diff --git a/gr-pager/src/usrp_flex_band.py b/gr-pager/src/usrp_flex_band.py index 2f272575a..62307385b 100755 --- a/gr-pager/src/usrp_flex_band.py +++ b/gr-pager/src/usrp_flex_band.py @@ -9,6 +9,7 @@ import time class app_top_block(gr.top_block): def __init__(self, options, queue): gr.top_block.__init__(self, "usrp_flex_all") + self.subdev = None if options.from_file is not None: self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file) @@ -57,6 +58,7 @@ class app_top_block(gr.top_block): # Avoid weak-ref error del self.subdev + def main(): parser = OptionParser(option_class=eng_option) parser.add_option("-f", "--frequency", type="eng_float", default=929.5e6, @@ -81,25 +83,22 @@ def main(): queue = gr.msg_queue() tb = app_top_block(options, queue) + runner = pager.top_block_runner(tb) try: - tb.start() while 1: if not queue.empty_p(): msg = queue.delete_head() # Blocking read page = join(split(msg.to_string(), chr(128)), '|') - disp = [] - for n in range(len(page)): - if ord(page[n]) < 32: - disp.append('.') - else: - disp.append(page[n]) - print join(disp, '') - + s = pager.make_printable(page) + print s + elif runner.done: + break else: - time.sleep(1) + time.sleep(0.05) except KeyboardInterrupt: tb.stop() + runner = None if __name__ == "__main__": main() diff --git a/gruel/src/include/gruel/Makefile.am b/gruel/src/include/gruel/Makefile.am index e5970cc49..50fad2531 100644 --- a/gruel/src/include/gruel/Makefile.am +++ b/gruel/src/include/gruel/Makefile.am @@ -28,4 +28,6 @@ gruelincludedir = $(prefix)/include/gruel gruelinclude_HEADERS = \ $(BUILT_SOURCES) \ - realtime.h + realtime.h \ + thread_body_wrapper.h \ + thread_group.h diff --git a/gruel/src/include/gruel/thread_body_wrapper.h b/gruel/src/include/gruel/thread_body_wrapper.h new file mode 100644 index 000000000..27dbbf7bb --- /dev/null +++ b/gruel/src/include/gruel/thread_body_wrapper.h @@ -0,0 +1,68 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_THREAD_BODY_WRAPPER_H +#define INCLUDED_THREAD_BODY_WRAPPER_H + +#include <boost/thread.hpp> +#include <exception> +#include <iostream> + +namespace gruel +{ + + void mask_signals(); + + template <class F> + class thread_body_wrapper + { + 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"; + } + } + }; +} + +#endif /* INCLUDED_THREAD_BODY_WRAPPER_H */ diff --git a/gruel/src/include/gruel/thread_group.h b/gruel/src/include/gruel/thread_group.h new file mode 100644 index 000000000..ae9a4250b --- /dev/null +++ b/gruel/src/include/gruel/thread_group.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2001-2003 William E. Kempf + * Copyright (C) 2007 Anthony Williams + * Copyright 2008 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_GRUEL_THREAD_GROUP_H +#define INCLUDED_GRUEL_THREAD_GROUP_H + +#include <boost/utility.hpp> +#include <boost/thread.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/function.hpp> + +namespace gruel +{ + class 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; + }; +} + +#endif /* INCLUDED_GRUEL_THREAD_GROUP_H */ diff --git a/gruel/src/lib/Makefile.am b/gruel/src/lib/Makefile.am index 972ff4ca9..7181c9418 100644 --- a/gruel/src/lib/Makefile.am +++ b/gruel/src/lib/Makefile.am @@ -21,19 +21,21 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(DEFINES) $(BOOST_CFLAGS) $(GRUEL_INCLUDES) $(WITH_INCLUDES) +AM_CPPFLAGS = $(DEFINES) $(BOOST_CPPFLAGS) $(GRUEL_INCLUDES) $(WITH_INCLUDES) lib_LTLIBRARIES = libgruel.la +# magic flags +libgruel_la_LDFLAGS = $(NO_UNDEFINED) $(BOOST_LDFLAGS) -version-info 0:0:0 + # These are the source files that go into the gruel shared library libgruel_la_SOURCES = \ - realtime.cc - -# magic flags -libgruel_la_LDFLAGS = $(NO_UNDEFINED) + realtime.cc \ + thread_body_wrapper.cc \ + thread_group.cc -# link the library against the c++ standard library libgruel_la_LIBADD = \ + $(BOOST_THREAD_LIB) -lstdc++ noinst_HEADERS = diff --git a/gruel/src/lib/thread_body_wrapper.cc b/gruel/src/lib/thread_body_wrapper.cc new file mode 100644 index 000000000..86c4edb5b --- /dev/null +++ b/gruel/src/lib/thread_body_wrapper.cc @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <gruel/thread_body_wrapper.h> +#ifdef HAVE_SIGNAL_H +#include <signal.h> +#endif +#include <stdio.h> + +namespace gruel { + +#if defined(HAVE_PTHREAD_SIGMASK) && defined(HAVE_SIGNAL_H) + + void mask_signals() + { + sigset_t new_set; + int r; + + sigemptyset(&new_set); + sigaddset(&new_set, SIGHUP); // block these... + sigaddset(&new_set, SIGINT); + sigaddset(&new_set, SIGPIPE); + sigaddset(&new_set, SIGALRM); + sigaddset(&new_set, SIGTERM); + sigaddset(&new_set, SIGUSR1); + sigaddset(&new_set, SIGCHLD); +#ifdef SIGPOLL + sigaddset(&new_set, SIGPOLL); +#endif +#ifdef SIGPROF + sigaddset(&new_set, SIGPROF); +#endif +#ifdef SIGSYS + sigaddset(&new_set, SIGSYS); +#endif +#ifdef SIGTRAP + sigaddset(&new_set, SIGTRAP); +#endif +#ifdef SIGURG + sigaddset(&new_set, SIGURG); +#endif +#ifdef SIGVTALRM + sigaddset(&new_set, SIGVTALRM); +#endif +#ifdef SIGXCPU + sigaddset(&new_set, SIGXCPU); +#endif +#ifdef SIGXFSZ + sigaddset(&new_set, SIGXFSZ); +#endif + r = pthread_sigmask(SIG_BLOCK, &new_set, 0); + if (r != 0) + perror("pthread_sigmask"); + } + +#else + + void mask_signals() + { + } + +#endif + +}; diff --git a/gruel/src/lib/thread_group.cc b/gruel/src/lib/thread_group.cc new file mode 100644 index 000000000..fa78567ec --- /dev/null +++ b/gruel/src/lib/thread_group.cc @@ -0,0 +1,99 @@ +/* -*- c++ -*- */ +/* + * Copyright (C) 2001-2003 William E. Kempf + * Copyright (C) 2007 Anthony Williams + * Copyright 2008 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. + */ + +#include <gruel/thread_group.h> + +namespace gruel +{ + thread_group::thread_group() + { + } + + thread_group::~thread_group() + { + // We shouldn't have to scoped_lock here, since referencing this object + // from another thread while we're deleting it in the current thread is + // going to lead to undefined behavior any way. + for (std::list<boost::thread*>::iterator it = m_threads.begin(); + it != m_threads.end(); ++it) + { + delete (*it); + } + } + + boost::thread* thread_group::create_thread(const boost::function0<void>& threadfunc) + { + // No scoped_lock required here since the only "shared data" that's + // modified here occurs inside add_thread which does scoped_lock. + std::auto_ptr<boost::thread> thrd(new boost::thread(threadfunc)); + add_thread(thrd.get()); + return thrd.release(); + } + + void thread_group::add_thread(boost::thread* thrd) + { + boost::lock_guard<boost::shared_mutex> guard(m_mutex); + + // For now we'll simply ignore requests to add a thread object multiple + // times. Should we consider this an error and either throw or return an + // error value? + std::list<boost::thread*>::iterator it = std::find(m_threads.begin(), + m_threads.end(), thrd); + BOOST_ASSERT(it == m_threads.end()); + if (it == m_threads.end()) + m_threads.push_back(thrd); + } + + void thread_group::remove_thread(boost::thread* thrd) + { + boost::lock_guard<boost::shared_mutex> guard(m_mutex); + + // For now we'll simply ignore requests to remove a thread object that's + // not in the group. Should we consider this an error and either throw or + // return an error value? + std::list<boost::thread*>::iterator it = std::find(m_threads.begin(), + m_threads.end(), thrd); + BOOST_ASSERT(it != m_threads.end()); + if (it != m_threads.end()) + m_threads.erase(it); + } + + void thread_group::join_all() + { + boost::shared_lock<boost::shared_mutex> guard(m_mutex); + for (std::list<boost::thread*>::iterator it = m_threads.begin(); + it != m_threads.end(); ++it) + { + (*it)->join(); + } + } + + void thread_group::interrupt_all() + { + boost::shared_lock<boost::shared_mutex> guard(m_mutex); + for(std::list<boost::thread*>::iterator it=m_threads.begin(),end=m_threads.end(); + it!=end; + ++it) + { + (*it)->interrupt(); + } + } + + size_t thread_group::size() const + { + boost::shared_lock<boost::shared_mutex> guard(m_mutex); + return m_threads.size(); + } + +} // namespace gruel diff --git a/mblock/src/lib/Makefile.am b/mblock/src/lib/Makefile.am index a005f8300..e8e5f59af 100644 --- a/mblock/src/lib/Makefile.am +++ b/mblock/src/lib/Makefile.am @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) \ - $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) + $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) # disable test until we fix ticket:180 # TESTS = test_mblock diff --git a/pmt/src/lib/Makefile.am b/pmt/src/lib/Makefile.am index d615836e8..5565e0986 100644 --- a/pmt/src/lib/Makefile.am +++ b/pmt/src/lib/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(BOOST_CFLAGS) \ +AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(BOOST_CPPFLAGS) \ $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) TESTS = test_pmt diff --git a/run_tests.sh.in b/run_tests.sh.in index 9b6e9bfad..8f467fd2e 100644 --- a/run_tests.sh.in +++ b/run_tests.sh.in @@ -138,8 +138,15 @@ export GR_DONT_LOAD_PREFS ok=yes for file in $3/qa_*.py do - if ! @PYTHON@ $file + # echo $file + @PYTHON@ $file + r=$? + if [ $r -ne 0 ] then + if [ $r -ge 128 ] # killed by a signal + then + exit $r + fi ok=no fi done diff --git a/usrp/host/apps-inband/Makefile.am b/usrp/host/apps-inband/Makefile.am index f231b57f7..663a861ed 100644 --- a/usrp/host/apps-inband/Makefile.am +++ b/usrp/host/apps-inband/Makefile.am @@ -23,7 +23,7 @@ include $(top_srcdir)/Makefile.common AM_CPPFLAGS = \ $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \ - $(USRP_INCLUDES) $(USRP_INBAND_INCLUDES) $(BOOST_CFLAGS) \ + $(USRP_INCLUDES) $(USRP_INBAND_INCLUDES) $(BOOST_CPPFLAGS) \ $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) diff --git a/usrp/host/apps/Makefile.am b/usrp/host/apps/Makefile.am index b3050a7b0..f4ee5291b 100644 --- a/usrp/host/apps/Makefile.am +++ b/usrp/host/apps/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(USRP_INCLUDES) $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES) \ +AM_CPPFLAGS = $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \ $(WITH_INCLUDES) bin_PROGRAMS = \ diff --git a/usrp/host/lib/inband/Makefile.am b/usrp/host/lib/inband/Makefile.am index a41ac18b8..447d0a61d 100644 --- a/usrp/host/lib/inband/Makefile.am +++ b/usrp/host/lib/inband/Makefile.am @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common AM_CPPFLAGS = \ $(DEFINES) $(OMNITHREAD_INCLUDES) $(PMT_INCLUDES) $(MBLOCK_INCLUDES) \ - $(USRP_INCLUDES) $(BOOST_CFLAGS) $(CPPUNIT_INCLUDES) \ + $(USRP_INCLUDES) $(BOOST_CPPFLAGS) $(CPPUNIT_INCLUDES) \ -I$(srcdir)/../../apps-inband $(WITH_INCLUDES) TESTS = test_inband |