Merged features/mp-sched -r8915:9335 into the trunk. The trunk now
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Tue, 19 Aug 2008 23:09:56 +0000 (23:09 +0000)
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Tue, 19 Aug 2008 23:09:56 +0000 (23:09 +0000)
contains the SMP aware scheduler.  This changeset
introduces a dependency on boost 1.35 or later.
See source:gnuradio/trunk/README.building-boost for additional info.

git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9336 221aa14e-8319-0410-a670-987f0aec2ac5

118 files changed:
Makefile.am
Makefile.common
README
README.building-boost [new file with mode: 0644]
config/Makefile.am
config/acx_pthread.m4
config/ax_boost_base.m4 [new file with mode: 0644]
config/ax_boost_date_time.m4 [new file with mode: 0644]
config/ax_boost_filesystem.m4 [new file with mode: 0644]
config/ax_boost_iostreams.m4 [new file with mode: 0644]
config/ax_boost_program_options.m4 [new file with mode: 0644]
config/ax_boost_python.m4 [new file with mode: 0644]
config/ax_boost_regex.m4 [new file with mode: 0644]
config/ax_boost_serialization.m4 [new file with mode: 0644]
config/ax_boost_signals.m4 [new file with mode: 0644]
config/ax_boost_system.m4 [new file with mode: 0644]
config/ax_boost_test_exec_monitor.m4 [new file with mode: 0644]
config/ax_boost_thread.m4 [new file with mode: 0644]
config/ax_boost_unit_test_framework.m4 [new file with mode: 0644]
config/ax_boost_wserialization.m4 [new file with mode: 0644]
config/gr_boost.m4 [deleted file]
config/gr_lib64.m4 [new file with mode: 0644]
config/gr_set_md_cpu.m4
config/gr_x86_64.m4 [deleted file]
config/grc_gnuradio_core.m4
config/grc_gnuradio_examples.m4
configure-cell-cross
configure.ac
dtools/bin/check-tarball-h-files
gcell/src/lib/spu/Makefile.am
gcell/src/lib/wrapper/Makefile.am
gnuradio-core/src/lib/Makefile.am
gnuradio-core/src/lib/filter/Makefile.am
gnuradio-core/src/lib/filter/dotprod_fff_altivec.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/dotprod_fff_altivec.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_altivec.c [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_altivec.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cpu.cc [deleted file]
gnuradio-core/src/lib/filter/gr_cpu.h
gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_cpu_x86.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_altivec.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_fff_altivec.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/gr_fir_sysconfig_powerpc.h [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_dotprod_powerpc.cc [new file with mode: 0644]
gnuradio-core/src/lib/filter/qa_filter.cc
gnuradio-core/src/lib/filter/qa_gr_fir_fff.cc
gnuradio-core/src/lib/filter/sysconfig_powerpc.cc [new file with mode: 0644]
gnuradio-core/src/lib/general/gr_math.h
gnuradio-core/src/lib/general/gri_fft.cc
gnuradio-core/src/lib/runtime/Makefile.am
gnuradio-core/src/lib/runtime/gr_block.cc
gnuradio-core/src/lib/runtime/gr_block.h
gnuradio-core/src/lib/runtime/gr_block_detail.h
gnuradio-core/src/lib/runtime/gr_block_executor.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_block_executor.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_buffer.cc
gnuradio-core/src/lib/runtime/gr_buffer.h
gnuradio-core/src/lib/runtime/gr_buffer.i
gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h
gnuradio-core/src/lib/runtime/gr_flowgraph.h
gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
gnuradio-core/src/lib/runtime/gr_scheduler.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_scheduler.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_scheduler_sts.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_scheduler_sts.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_scheduler_thread.cc [deleted file]
gnuradio-core/src/lib/runtime/gr_scheduler_thread.h [deleted file]
gnuradio-core/src/lib/runtime/gr_scheduler_tpb.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_scheduler_tpb.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.cc
gnuradio-core/src/lib/runtime/gr_top_block.cc
gnuradio-core/src/lib/runtime/gr_top_block_impl.cc
gnuradio-core/src/lib/runtime/gr_top_block_impl.h
gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.cc [deleted file]
gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h [deleted file]
gnuradio-core/src/lib/runtime/gr_tpb_detail.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_tpb_detail.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc [new file with mode: 0644]
gnuradio-core/src/lib/runtime/gr_tpb_thread_body.h [new file with mode: 0644]
gnuradio-core/src/lib/runtime/qa_gr_buffer.cc
gnuradio-core/src/python/gnuradio/gr/top_block.py
gnuradio-core/src/tests/Makefile.am
gnuradio-examples/python/Makefile.am
gnuradio-examples/python/mp-sched/Makefile.am [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/core-duo.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/core2-duo.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-2.33-clovertown.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/dual-quad-core-3.00-penryn.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/js21-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/js21.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/ps3-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/ps3.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/qs21-altivec.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/perf-data/qs21.dat [new file with mode: 0644]
gnuradio-examples/python/mp-sched/plot_flops.py [new file with mode: 0755]
gnuradio-examples/python/mp-sched/run_synthetic.py [new file with mode: 0755]
gnuradio-examples/python/mp-sched/synthetic.py [new file with mode: 0755]
gr-pager/src/Makefile.am
gr-pager/src/__init__.py
gr-pager/src/pager_utils.py [new file with mode: 0644]
gr-pager/src/usrp_flex.py
gr-pager/src/usrp_flex_all.py
gr-pager/src/usrp_flex_band.py
gruel/src/include/gruel/Makefile.am
gruel/src/include/gruel/thread_body_wrapper.h [new file with mode: 0644]
gruel/src/include/gruel/thread_group.h [new file with mode: 0644]
gruel/src/lib/Makefile.am
gruel/src/lib/thread_body_wrapper.cc [new file with mode: 0644]
gruel/src/lib/thread_group.cc [new file with mode: 0644]
mblock/src/lib/Makefile.am
pmt/src/lib/Makefile.am
run_tests.sh.in
usrp/host/apps-inband/Makefile.am
usrp/host/apps/Makefile.am
usrp/host/lib/inband/Makefile.am

index ea99890ae563994ffb131086407d31c5f4712c72..9262c5bcc575dcb6753b41d0efc6c1a58f3a1303 100644 (file)
@@ -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@
index a4a3139c647bf277ece1a4f645b4fb95436fd19d..b24be43756807cc67959d419dd39b0cd3844f077 100644 (file)
@@ -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
diff --git a/README b/README
index a3f1d8b0a23ba27f80f5e0256ffaedaee6fbe3c9..6229ecd204e2cf2633af5afa7fcc579670105635 100644 (file)
--- a/README
+++ b/README
@@ -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 (file)
index 0000000..0e7059d
--- /dev/null
@@ -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
+
index 310568bfb05d54837e881f658dbd648d12ce33a5..cc58d96c1ee1c8214b31ec0fa56ad797791e9876 100644 (file)
@@ -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 \
index d318ab01d9aabd21cc71d19b33fa4c761de17c17..eb09f5acc3dea905cf2cd58e8137628839b25c12 100644 (file)
@@ -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 (file)
index 0000000..e979022
--- /dev/null
@@ -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 (file)
index 0000000..7b3f0fe
--- /dev/null
@@ -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 (file)
index 0000000..bcb3fa4
--- /dev/null
@@ -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 (file)
index 0000000..181b1e7
--- /dev/null
@@ -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 (file)
index 0000000..3829373
--- /dev/null
@@ -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 (file)
index 0000000..3c6c666
--- /dev/null
@@ -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 (file)
index 0000000..32b5313
--- /dev/null
@@ -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 (file)
index 0000000..78c9500
--- /dev/null
@@ -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 (file)
index 0000000..3c49717
--- /dev/null
@@ -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 (file)
index 0000000..cb73f25
--- /dev/null
@@ -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 (file)
index 0000000..2c30c0b
--- /dev/null
@@ -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 (file)
index 0000000..4df2322
--- /dev/null
@@ -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 (file)
index 0000000..73affcc
--- /dev/null
@@ -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 (file)
index 0000000..f384988
--- /dev/null
@@ -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 (file)
index 0664d36..0000000
+++ /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 (file)
index 0000000..f34779a
--- /dev/null
@@ -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
+])
index 1ef75a53684a9ad48e0db979ec078ca54d84012d..b9c570eded395c28cbe3a36638cb6088df37776d 100644 (file)
@@ -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 (file)
index 3f56c06..0000000
+++ /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
-])
index 24432a28fc7bdb339a3a0c7d980e5156c1976fa8..562641ebe9af6d4050f734db73ec54e0776f4ce8 100644 (file)
@@ -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:
index 919acee4c80b0df0d15ec80de9cead93be41ac40..451316071d308f616b68ca1eadbb9916b66836de 100644 (file)
@@ -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 \
index 5bcd77b17b13fdf847ad347db64e7c07b5ba0f53..6d6e7e542060661a02921726bb3bd9ec8e3e65f5 100755 (executable)
@@ -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                        \
index 5d4c380e87f1babf100a602093ecc89cd5e4652a..389d74787798bf2cb301c8947bd7ab5e8c120089 100644 (file)
@@ -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
index dae7592d2af8ae1ace4756ed2f56939fa1c233a9..6e3e1e77641a8f693ccf397f6f6721a8e9fce84b 100755 (executable)
@@ -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
 
index 30385f9b4d158500242185a67984ab92a0e0e1bc..7c8e411f7497fe990279200f733338cb08f850ac 100644 (file)
@@ -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 = \
index c8b0fcd82bea2cae5c4ae1bfc8dfda547d7ca366..8d92b7b0a97d7b4a1de1789009fab1f9e5f02b07 100644 (file)
@@ -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
index 66567048cbf0a89ee50dbca23d4cf3a3b5bd09ce..e4646cfcc2ba8c395519a050b349afcfb1bf4ad8 100644 (file)
@@ -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  =       \
index 1ddb84415f9116fc03f2f6385398b83565fa68b5..66946163201ed758ee25374a07bcdd7044d96808 100644 (file)
@@ -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 (file)
index 0000000..ebddeb5
--- /dev/null
@@ -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 (file)
index 0000000..d9ee52c
--- /dev/null
@@ -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 (file)
index 0000000..01ca95f
--- /dev/null
@@ -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 (file)
index 0000000..176579a
--- /dev/null
@@ -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.cc b/gnuradio-core/src/lib/filter/gr_cpu.cc
deleted file mode 100644 (file)
index 517c10e..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- 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.
- */
-
-#include <gr_cpu.h>
-
-/*
- * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
- */
-extern "C" {
-void cpuid_x86 (unsigned int op, unsigned int result[4]);
-};
-
-/*
- * CPUID functions returning a single datum
- */
-
-static inline unsigned int cpuid_eax(unsigned int op)
-{
-  unsigned int regs[4];
-  cpuid_x86 (op, regs);
-  return regs[0];
-}
-
-static inline unsigned int cpuid_ebx(unsigned int op)
-{
-  unsigned int regs[4];
-  cpuid_x86 (op, regs);
-  return regs[1];
-}
-
-static inline unsigned int cpuid_ecx(unsigned int op)
-{
-  unsigned int regs[4];
-  cpuid_x86 (op, regs);
-  return regs[2];
-}
-
-static inline unsigned int cpuid_edx(unsigned int op)
-{
-  unsigned int regs[4];
-  cpuid_x86 (op, regs);
-  return regs[3];
-}
-
-// ----------------------------------------------------------------
-
-bool
-gr_cpu::has_mmx ()
-{
-  unsigned int edx = cpuid_edx (1);    // standard features
-  return (edx & (1 << 23)) != 0;
-}
-
-bool
-gr_cpu::has_sse ()
-{
-  unsigned int edx = cpuid_edx (1);    // standard features
-  return (edx & (1 << 25)) != 0;
-}
-
-bool
-gr_cpu::has_sse2 ()
-{
-  unsigned int edx = cpuid_edx (1);    // standard features
-  return (edx & (1 << 26)) != 0;
-}
-
-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);
-  if (extended_fct_count < 0x80000001)
-    return false;
-
-  unsigned int extended_features = cpuid_edx (0x80000001);
-  return (extended_features & (1 << 31)) != 0;
-}
-
-bool
-gr_cpu::has_3dnowext ()
-{
-  unsigned int extended_fct_count = cpuid_eax (0x80000000);
-  if (extended_fct_count < 0x80000001)
-    return false;
-
-  unsigned int extended_features = cpuid_edx (0x80000001);
-  return (extended_features & (1 << 30)) != 0;
-}
index 5967d986857f3387cc72e7f81f65b6f9667941ca..ef10beae1ff953f53480e623a55709609c444a40 100644 (file)
@@ -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/filter/gr_cpu_powerpc.cc b/gnuradio-core/src/lib/filter/gr_cpu_powerpc.cc
new file mode 100644 (file)
index 0000000..35c342a
--- /dev/null
@@ -0,0 +1,59 @@
+/* -*- 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.
+ */
+
+#include <gr_cpu.h>
+
+bool
+gr_cpu::has_mmx ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+  return false;
+}
+
+bool
+gr_cpu::has_altivec ()
+{
+  return true;         // FIXME assume we've always got it
+}
diff --git a/gnuradio-core/src/lib/filter/gr_cpu_x86.cc b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc
new file mode 100644 (file)
index 0000000..a13a69c
--- /dev/null
@@ -0,0 +1,113 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Radio; see the file COPYING.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gr_cpu.h>
+
+/*
+ * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result
+ */
+extern "C" {
+void cpuid_x86 (unsigned int op, unsigned int result[4]);
+};
+
+/*
+ * CPUID functions returning a single datum
+ */
+
+static inline unsigned int cpuid_eax(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[0];
+}
+
+static inline unsigned int cpuid_ebx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[1];
+}
+
+static inline unsigned int cpuid_ecx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[2];
+}
+
+static inline unsigned int cpuid_edx(unsigned int op)
+{
+  unsigned int regs[4];
+  cpuid_x86 (op, regs);
+  return regs[3];
+}
+
+// ----------------------------------------------------------------
+
+bool
+gr_cpu::has_mmx ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 23)) != 0;
+}
+
+bool
+gr_cpu::has_sse ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 25)) != 0;
+}
+
+bool
+gr_cpu::has_sse2 ()
+{
+  unsigned int edx = cpuid_edx (1);    // standard features
+  return (edx & (1 << 26)) != 0;
+}
+
+bool
+gr_cpu::has_3dnow ()
+{
+  unsigned int extended_fct_count = cpuid_eax (0x80000000);
+  if (extended_fct_count < 0x80000001)
+    return false;
+
+  unsigned int extended_features = cpuid_edx (0x80000001);
+  return (extended_features & (1 << 31)) != 0;
+}
+
+bool
+gr_cpu::has_3dnowext ()
+{
+  unsigned int extended_fct_count = cpuid_eax (0x80000000);
+  if (extended_fct_count < 0x80000001)
+    return false;
+
+  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 (file)
index 0000000..7583f5c
--- /dev/null
@@ -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 (file)
index 0000000..1694f55
--- /dev/null
@@ -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 (file)
index 0000000..34d3f81
--- /dev/null
@@ -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 (file)
index 0000000..9c31cdf
--- /dev/null
@@ -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 (file)
index 0000000..1b02a79
--- /dev/null
@@ -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;
+}
index e36fca45d46febca0a728236a4c7c84215f321a1..e2fa72adda0156a9e27ce3bbdc0f4951c3952898 100644 (file)
@@ -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;
 }
index 380435bf7c4161dde89b8ed7ebb99db0b0aa6121..b921223ed96df2a6fc5b74822bf48ae95bfaed0b 100644 (file)
@@ -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 (file)
index 0000000..e2b2781
--- /dev/null
@@ -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;
+}
index 957a0e12aa7c75472a186698f5306b3777b3119f..f1bd208b8c4c9b7d2b48193d99dbb25f9a5e8734 100644 (file)
@@ -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_ */
index 17ea89e1324f7061d12ba840bfaec123bfcdbd6f..f6e28e1d1e7e055b39decb96b74b3c6f76bf358c 100644 (file)
@@ -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
  * 
 #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);
index 550031b944c32aba1d5dd9fe40d5125260dd5efe..b21b324128c6d7c74717ecb44ba67f41747eb7c3 100644 (file)
@@ -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                              \
index 0a8fb92c2d2be360d88062afe3e2e7d77bce8e71..7c2e9901b05a5901ed6acec60379c18f9c956051 100644 (file)
@@ -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;
+}
+
index 79237ee83b62c5009877e3ab4b4e7151f6766a8f..437b610b458b71e866b52fd4243793e00d920b37 100644 (file)
@@ -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 */
index a3b7731c01728712860dc8c180abc0e088d238ba..2856c402c7a7925a5d8f762adc9d2eb7f5861633 100644 (file)
@@ -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 (file)
index 0000000..fd3a916
--- /dev/null
@@ -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 (file)
index 0000000..41b5ede
--- /dev/null
@@ -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 */
index 77f0c7c43d07df869276c0355598d02c2fe6ff8a..31a471ea75273fd607388576775c66ab7be8d319 100644 (file)
@@ -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);
 }
 
index cf578c89dd1092f706386aace352eccb3357ce6b..75063cc6a1abacdd30164700bb43a643ef496d36 100644 (file)
@@ -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
index 38e1d945da51d5e228e0e5791182049e4c77238a..4c1c5afae5263b115f89de819e895883c8fa6f16 100644 (file)
@@ -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);
 };
 
 
index aa1aa83532d7bb6eadb49c0baa6382dc98dd1825..031eb6dfd5db9b2af06d2c79662a6a3a918f4842 100644 (file)
 
 #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;
+}
index 184ee451442c51c2c7354c0739f04dfd438e2e00..673c4df16ff7b15e107846381eb817a6f26745d4 100644 (file)
@@ -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);
index c97a50782cbc6b25afe380f1030bbd1e3387a1e8..fc407e72be4123800c9b8b152cb9a4035dfad8f9 100644 (file)
@@ -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);
index 32cac2ea8c537e741cfab99938036e831c63d5c2..a026851d20117f4802e1b1fe072f9c3b0fd2fcef 100644 (file)
@@ -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 (file)
index 0000000..e4d8b3d
--- /dev/null
@@ -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 (file)
index 0000000..13bc1ff
--- /dev/null
@@ -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 (file)
index 0000000..fefc0dc
--- /dev/null
@@ -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 (file)
index 0000000..4cf8351
--- /dev/null
@@ -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 (file)
index 07bd605..0000000
+++ /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 (file)
index 89daba4..0000000
+++ /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 (file)
index 0000000..af03385
--- /dev/null
@@ -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 (file)
index 0000000..16a0c02
--- /dev/null
@@ -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 */
index b2fbdb73be7ff01a53675773e8dcdb394c8085d3..7f1b40641ed7dc3b2bdea505bd1d80edfc467451 100644 (file)
@@ -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>
 
 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 ();
 
index 3c8e28f70136d54ebd55e3a0da5417285e01345d..09e46dfbb4bbea367911cd3c25e3d994757bfd47 100644 (file)
@@ -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()
index 5914379384cfd51e5b61617cec3c11249134a613..50d480d009e80875b02744740e84917837a33e0e 100644 (file)
 #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;
-}
index 869f788ef4feca5983de140583eb1ae90ec0ec4c..35fb44ef92ba7110c4c052e3c96d8a89573fcb8d 100644 (file)
 #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 (file)
index b3e9da6..0000000
+++ /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_top_block_impl_sts.h b/gnuradio-core/src/lib/runtime/gr_top_block_impl_sts.h
deleted file mode 100644 (file)
index ec2e51c..0000000
+++ /dev/null
@@ -1,55 +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_TOP_BLOCK_IMPL_STS_H
-#define INCLUDED_GR_TOP_BLOCK_IMPL_STS_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
-{
-public:
-  gr_top_block_impl_sts(gr_top_block *owner);
-  ~gr_top_block_impl_sts();
-
-  // Signal scheduler threads to stop
-  void stop();
-
-  // Wait for scheduler threads to exit
-  void wait();
-
-private:
-    
-  gr_scheduler_thread_vector_t   d_threads;
-  std::vector<gr_basic_block_vector_t> d_graphs;
-
-  void start_threads();
-};
-
-#endif /* INCLUDED_GR_TOP_BLOCK_IMPL_STS_H */
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 (file)
index 0000000..02e8dee
--- /dev/null
@@ -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 (file)
index 0000000..9566312
--- /dev/null
@@ -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 (file)
index 0000000..f61e172
--- /dev/null
@@ -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 (file)
index 0000000..a630b1b
--- /dev/null
@@ -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 */
index ad40f724d0488e07337df17fca33445b613882a3..7434cf657f5e0beafe50954e7a787efc856e52d9 100644 (file)
@@ -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++){
index 8f5754d657f341959a8e5834b780500ad4e0888a..a3161170adca99e197c58440284d28a9e3265e3f 100644 (file)
 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
index 730de2d194eeeab5c37931358a8e95fafb0b4cfb..c6225d972f2949ebcd4f5b37d3c8c497ce525e8b 100644 (file)
@@ -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
index e20bfafd46d8cebac6681c15284b220d9fb9b982..b1780bc6f4b48db02f65e2bc2124f02a0cb10993 100644 (file)
@@ -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 (file)
index 0000000..bd4b4e8
--- /dev/null
@@ -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 (file)
index 0000000..064d1e1
--- /dev/null
@@ -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 (file)
index 0000000..d67dee8
--- /dev/null
@@ -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 (file)
index 0000000..fa182c6
--- /dev/null
@@ -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 (file)
index 0000000..57d49ed
--- /dev/null
@@ -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 (file)
index 0000000..d0b8148
--- /dev/null
@@ -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 (file)
index 0000000..a23bceb
--- /dev/null
@@ -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 (file)
index 0000000..dd01b31
--- /dev/null
@@ -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 (file)
index 0000000..c9bac37
--- /dev/null
@@ -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 (file)
index 0000000..8364be3
--- /dev/null
@@ -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 (file)
index 0000000..cc62874
--- /dev/null
@@ -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 (executable)
index 0000000..b3f8193
--- /dev/null
@@ -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 (executable)
index 0000000..565e6c5
--- /dev/null
@@ -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 (executable)
index 0000000..e1fcb20
--- /dev/null
@@ -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
+    
+    
+    
+
index 5c70db2f5a2bff3b9f7f8e89d34489b3736fa5e3..d0245444a4b6bff9ac3191f41316e8378bc21ecf 100644 (file)
@@ -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
index 6ef60d939b07f86f6b913811ade1ea22981aa117..664b799429f4283951318249b7e83b8877160e3b 100644 (file)
@@ -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 (file)
index 0000000..bbcb633
--- /dev/null
@@ -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
index f636030e9aae5959c4b76c94605ea576070b5a12..6e09b3df6ba922af8f997f6257bfee7471136dc4 100755 (executable)
@@ -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()
index daee3532cd59d7a21fdf85ac6a7c0ba5643f4d88..b37c6a5dae69060bd3b4d017205ef7837891105c 100755 (executable)
@@ -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()
index 2f272575a82a5937d81348ea3543f203ac26bfc7..62307385b4b4c6316cbe34df630dd7aea2553607 100755 (executable)
@@ -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()
index e5970cc4924b6cfa262d1754e51e8fc0dcf36a43..50fad253152d9bab7755812b90e9b01dfe034da6 100644 (file)
@@ -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 (file)
index 0000000..27dbbf7
--- /dev/null
@@ -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 (file)
index 0000000..ae9a425
--- /dev/null
@@ -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 */
index 972ff4ca927c740c963de19ef4bd7f2b8f8bb2b3..7181c9418f2608d8a770d55f55d57c992cd7014d 100644 (file)
 
 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 (file)
index 0000000..86c4edb
--- /dev/null
@@ -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 (file)
index 0000000..fa78567
--- /dev/null
@@ -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
index a005f83008aac3936adaa92e6da1b32eaa159546..e8e5f59af22d7d215a8146f43c78c932550280a8 100644 (file)
@@ -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
index d615836e8de070a0e1581c0e263e1a85c3504c4e..5565e0986c505e3d12df6d0ebf2c3acc63935da5 100644 (file)
@@ -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
index 9b6e9bfad3b74466a950c9d071460e81542f0922..8f467fd2eb6e8370d06b97d9ede7afb1fcd876a9 100644 (file)
@@ -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
index f231b57f7a26ec7395e636f0398f6e544d6d536e..663a861ed4379eec48d683a6c02fe2092e678e60 100644 (file)
@@ -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)
 
 
index b3050a7b0cb143bd013a7e126df094b18c42f011..f4ee5291b2ed6ab08aef000ab6821d161d447e92 100644 (file)
@@ -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 =                         \
index a41ac18b84c6b0892643a7ebcc1f1350ef4f452c..447d0a61d31589b61cf55b283f1cd4c6ba5da37d 100644 (file)
@@ -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