Merged gcell, the Cell SPE scheduler and RPC mechanism into the trunk.
authoreb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 24 Mar 2008 06:09:29 +0000 (06:09 +0000)
committereb <eb@221aa14e-8319-0410-a670-987f0aec2ac5>
Mon, 24 Mar 2008 06:09:29 +0000 (06:09 +0000)
(eb/trunk-with-gcell r8037:8085).  Expect additional tweaks, but
currently works and passes distcheck.

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

146 files changed:
Makefile.am
Makefile.common
Makefile.common.spu [new file with mode: 0644]
bootstrap
config/Makefile.am
config/grc_gcell.m4 [new file with mode: 0644]
configure.ac
gcell/Makefile.am [new file with mode: 0644]
gcell/gcell.pc.in [new file with mode: 0644]
gcell/src/Makefile.am [new file with mode: 0644]
gcell/src/apps/Makefile.am [new file with mode: 0644]
gcell/src/apps/benchmark_dma.cc [new file with mode: 0644]
gcell/src/apps/benchmark_nop.cc [new file with mode: 0644]
gcell/src/apps/gen_script.py [new file with mode: 0755]
gcell/src/apps/plot_speedup.py [new file with mode: 0755]
gcell/src/apps/results-071223 [new file with mode: 0644]
gcell/src/apps/split_and_avg_results.py [new file with mode: 0755]
gcell/src/apps/spu/Makefile.am [new file with mode: 0644]
gcell/src/apps/spu/benchmark_procs.c [new file with mode: 0644]
gcell/src/apps/test_all.cc [new file with mode: 0644]
gcell/src/ibm/Makefile.am [new file with mode: 0644]
gcell/src/ibm/README [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_add.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_add_return.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_dec.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_dec_return.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_inc.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_inc_return.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_read.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_set.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_sub.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/atomic_sub_return.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/complete.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/complete_all.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/completion.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/cond.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/cond_broadcast.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/cond_init.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/cond_signal.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/cond_wait.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/init_completion.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/libsync.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/mutex.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/mutex_init.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/mutex_lock.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/mutex_trylock.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/mutex_unlock.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/pdt_libsync.xml [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/sync_utils.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/trace_libsync.h [new file with mode: 0644]
gcell/src/ibm/sync/ppu_source/wait_for_completion.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_add.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_add_return.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_dec.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_dec_return.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_inc.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_inc_return.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_read.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_set.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_sub.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/atomic_sub_return.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/complete.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/complete_all.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/completion.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/cond.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/cond_broadcast.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/cond_init.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/cond_signal.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/cond_wait.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/init_completion.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/libsync.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/mutex.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/mutex_init.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/mutex_lock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/mutex_trylock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/mutex_unlock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/read_lock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/read_trylock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/read_unlock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/rwlock_init.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/sync_irq.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/sync_utils.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/trace_libsync.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/wait_for_completion.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/write_lock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/write_trylock.h [new file with mode: 0644]
gcell/src/ibm/sync/spu_source/write_unlock.h [new file with mode: 0644]
gcell/src/include/Makefile.am [new file with mode: 0644]
gcell/src/include/compiler.h [new file with mode: 0644]
gcell/src/include/gc_atomic.h [new file with mode: 0644]
gcell/src/include/gc_cdefs.h [new file with mode: 0644]
gcell/src/include/gc_declare_proc.h [new file with mode: 0644]
gcell/src/include/gc_jd_queue.h [new file with mode: 0644]
gcell/src/include/gc_jd_queue_data.h [new file with mode: 0644]
gcell/src/include/gc_jd_stack.h [new file with mode: 0644]
gcell/src/include/gc_job_desc.h [new file with mode: 0644]
gcell/src/include/gc_job_desc_private.h [new file with mode: 0644]
gcell/src/include/gc_logging.h [new file with mode: 0644]
gcell/src/include/gc_mbox.h [new file with mode: 0644]
gcell/src/include/gc_spu_args.h [new file with mode: 0644]
gcell/src/include/gc_types.h [new file with mode: 0644]
gcell/src/include/memory_barrier.h [new file with mode: 0644]
gcell/src/include/spu/Makefile.am [new file with mode: 0644]
gcell/src/include/spu/gc_delay.h [new file with mode: 0644]
gcell/src/include/spu/gc_jd_queue.h [new file with mode: 0644]
gcell/src/lib/Makefile.am [new file with mode: 0644]
gcell/src/lib/general/Makefile.am [new file with mode: 0644]
gcell/src/lib/procs/Makefile.am [new file with mode: 0644]
gcell/src/lib/runtime/Makefile.am [new file with mode: 0644]
gcell/src/lib/runtime/gc_client_thread_info.h [new file with mode: 0644]
gcell/src/lib/runtime/gc_jd_queue.c [new file with mode: 0644]
gcell/src/lib/runtime/gc_jd_stack.c [new file with mode: 0644]
gcell/src/lib/runtime/gc_job_manager.cc [new file with mode: 0644]
gcell/src/lib/runtime/gc_job_manager.h [new file with mode: 0644]
gcell/src/lib/runtime/gc_job_manager_impl.cc [new file with mode: 0644]
gcell/src/lib/runtime/gc_job_manager_impl.h [new file with mode: 0644]
gcell/src/lib/runtime/gc_proc_def_utils.cc [new file with mode: 0644]
gcell/src/lib/runtime/gc_proc_def_utils.h [new file with mode: 0644]
gcell/src/lib/runtime/qa_jd_queue.cc [new file with mode: 0644]
gcell/src/lib/runtime/qa_jd_queue.h [new file with mode: 0644]
gcell/src/lib/runtime/qa_jd_stack.cc [new file with mode: 0644]
gcell/src/lib/runtime/qa_jd_stack.h [new file with mode: 0644]
gcell/src/lib/runtime/qa_job_manager.cc [new file with mode: 0644]
gcell/src/lib/runtime/qa_job_manager.h [new file with mode: 0644]
gcell/src/lib/runtime/qa_lib.cc [new file with mode: 0644]
gcell/src/lib/runtime/qa_lib.h [new file with mode: 0644]
gcell/src/lib/runtime/spu/gc_delay.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/gc_logging.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/gc_main.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/gc_spu_config.h [new file with mode: 0644]
gcell/src/lib/runtime/spu/gc_spu_jd_queue.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/gcell_qa.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/spu_buffers.c [new file with mode: 0644]
gcell/src/lib/runtime/spu/spu_buffers.h [new file with mode: 0644]
gcell/src/lib/spu/Makefile.am [new file with mode: 0644]
usrp/firmware/include/fpga_regs_common.v
usrp/firmware/include/fpga_regs_standard.v

index 89ad013c8ab966ec000d9c15f5e21b29eb166e82..8196bd0536081e6805b51c8713c17b8f8f422626 100644 (file)
@@ -25,6 +25,7 @@ include $(top_srcdir)/Makefile.common
 
 EXTRA_DIST = \
        configure \
+       configure-cell-cross \
        config.h.in \
        run_tests.sh.in \
        README.hacking
index 300e92fc47035cc2092aaf809315bfe302ae7d51..ace03b90ca2b7936f80876502425d63d2c1dd6ee 100644 (file)
@@ -42,6 +42,14 @@ grpyexecdir = $(pyexecdir)/gnuradio
 usrppythondir = $(pythondir)/usrpm
 usrppyexecdir = $(pyexecdir)/usrpm
 
+# gcell includes
+gcellincludedir = $(includedir)/gcell
+gcellspuincludedir = $(includedir)/gcell/spu
+
+# Cell spu libs
+libspudir = $(libdir)spu
+
+
 # when including for compilation from pre-installed libraries and such,
 # need to make sure those are put last on the compile command
 WITH_INCLUDES = @with_INCLUDES@
@@ -80,6 +88,14 @@ PMT_LA = @pmt_LA@
 MBLOCK_INCLUDES = @mblock_INCLUDES@
 MBLOCK_LA = @mblock_LA@
 
+# How to link the gcell library from inside the tree (the PPU part)
+GCELL_INCLUDES = @gcell_INCLUDES@
+GCELL_LA = @gcell_LA@
+
+# How to link the gcell library from inside the tree (the SPU part)
+GCELL_SPU_INCLUDES = @gcell_spu_INCLUDES@
+GCELL_SPU_LA = @gcell_spu_LA@
+
 # 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)
diff --git a/Makefile.common.spu b/Makefile.common.spu
new file mode 100644 (file)
index 0000000..27d789c
--- /dev/null
@@ -0,0 +1,45 @@
+# -*- Makefile -*-
+#
+# 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 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
+
+# We're abusing automake, getting it to generate code for two
+# architectures under the same tree.  If you've got a better way to do
+# this, please let us know
+
+AR=spu-ar
+RANLIB=spu-ranlib
+CC=spu-cc
+LD=spu-ld
+
+C_WARNINGS = \
+  -Wall -Wextra -Wstrict-prototypes -Werror-implicit-function-declaration
+
+# Need to override user stuff even though it gives a warning.
+# (Otherwise these contain PPE related info.)
+
+CPPFLAGS=
+LDFLAGS=
+CFLAGS=
+
+AM_CFLAGS = -O3 -g --std=gnu99 -fstrict-aliasing $(C_WARNINGS)
+
+
index 525a6b06cea1c8b077b1ff1801a3a14b37f4d669..7daff90d1b4f203d8ae412a10b43184afac1e94d 100755 (executable)
--- a/bootstrap
+++ b/bootstrap
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright 2001,2005 Free Software Foundation, Inc.
+# Copyright 2001,2005,2008 Free Software Foundation, Inc.
 # 
 # This file is part of GNU Radio
 # 
@@ -26,4 +26,5 @@ aclocal -I config
 autoconf
 autoheader
 libtoolize --automake
-automake --add-missing
+automake --add-missing -Wno-portability -Wno-override -Wnone
+#automake --add-missing -Wno-portability
index be258b71e1066802a5ca8765a2c00808a2e0d8de..46c84da76ee59940d435800828355df89929bbe4 100644 (file)
@@ -31,6 +31,7 @@ m4macros = \
        cppunit.m4 \
        gr_boost.m4 \
        grc_build.m4 \
+       grc_gcell.m4 \
        grc_gnuradio_core.m4 \
        grc_gnuradio_examples.m4 \
        grc_gr_atsc.m4 \
diff --git a/config/grc_gcell.m4 b/config/grc_gcell.m4
new file mode 100644 (file)
index 0000000..6d71441
--- /dev/null
@@ -0,0 +1,87 @@
+dnl Copyright 2001,2002,2003,2004,2005,2006,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.
+
+AC_DEFUN([GRC_GCELL],[
+    GRC_ENABLE(gcell)
+    dnl GRC_WITH(gcell)
+
+    dnl Don't do gcell if omnithread or mblock skipped
+    dnl (The mblock dependency should be refactored, we're just using some timing utilities)
+    GRC_CHECK_DEPENDENCY(gcell, omnithread)
+    GRC_CHECK_DEPENDENCY(gcell, mblock)
+
+    dnl If execution gets to here, $passed will be:
+    dnl   with : if the --with code didn't error out
+    dnl   yes  : if the --enable code passed muster and all dependencies are met
+    dnl   no   : otherwise
+    if test $passed = yes; then
+       dnl Don't build gcell if host_cpu isn't powerpc
+       AC_MSG_CHECKING([whether host_cpu is powerpc*])
+       case "$host_cpu" in
+           powerpc*)
+               AC_MSG_RESULT(yes)
+               ;;
+            *)
+               passed=no
+               AC_MSG_RESULT(no)
+               ;;
+       esac
+
+        dnl Don't build gcell if we can't find spu-gcc.
+       AC_CHECK_PROG([SPU_GCC_PROG],[spu-gcc],[yes],[no])
+       if test $SPU_GCC_PROG = no; then
+            passed=no
+        fi
+    fi
+
+    if test $passed != with; then
+       dnl how and where to find INCLUDES and LA
+       gcell_INCLUDES="-I\${abs_top_srcdir}/gcell/src/include \
+                -I\${abs_top_srcdir}/gcell/src/lib/runtime \
+                -I\${abs_top_srcdir}/gcell/src/lib/general \
+                -I\${abs_top_srcdir}/gcell/src/lib/procs"
+        gcell_LA="\${abs_top_builddir}/gcell/src/lib/libgcell.la"
+       gcell_spu_INCLUDES="-I\${abs_top_srcdir}/gcell/src/include/spu \
+                -I\${abs_top_srcdir}/gcell/src/include \
+                -I\${abs_top_srcdir}/gcell/src/lib/runtime/spu \
+                -I\${abs_top_srcdir}/gcell/src/lib/general/spu \
+                -I\${abs_top_srcdir}/gcell/src/lib/procs/spu"
+       gcell_spu_LA="\${abs_top_builddir}/gcell/src/lib/spu/libgcell_spu.a"
+       AC_SUBST(gcell_spu_INCLUDES)
+       AC_SUBST(gcell_spu_LA)
+    fi
+
+    AC_CONFIG_FILES([ \
+        gcell/Makefile \
+        gcell/gcell.pc \
+        gcell/src/Makefile \
+        gcell/src/include/Makefile \
+        gcell/src/include/spu/Makefile \
+        gcell/src/lib/Makefile \
+        gcell/src/lib/spu/Makefile \
+        gcell/src/lib/general/Makefile \
+        gcell/src/lib/procs/Makefile \
+        gcell/src/lib/runtime/Makefile \
+        gcell/src/apps/Makefile \
+       gcell/src/apps/spu/Makefile \
+       gcell/src/ibm/Makefile \
+    ])
+
+    GRC_BUILD_CONDITIONAL(gcell)
+])
index f918f9b0d2c72a5828ceda97fdd42267df493001..9917d1ff4925b7803cedece5cf9f7926488f6da7 100644 (file)
@@ -25,11 +25,6 @@ AC_CONFIG_SRCDIR([gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc])
 AC_CANONICAL_BUILD
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
-if test x$cross_compiling != xno; then
-  AC_MSG_NOTICE([Configuring GNU Radio for cross compilation])
-else
-  AC_MSG_NOTICE([Configuring GNU Radio for native compilation])
-fi
 
 AM_INIT_AUTOMAKE(gnuradio,3.1svn)
 
@@ -244,9 +239,10 @@ AC_ARG_ENABLE(
 
 build_dirs="config"
 GRC_OMNITHREAD                 dnl must come before gnuradio-core and mblock
-GRC_GNURADIO_CORE
 GRC_PMT
 GRC_MBLOCK                     dnl this must come after GRC_PMT
+GRC_GCELL
+GRC_GNURADIO_CORE
 GRC_USRP
 GRC_GR_USRP                    dnl this must come after GRC_USRP
 GRC_GR_MSDD6000
diff --git a/gcell/Makefile.am b/gcell/Makefile.am
new file mode 100644 (file)
index 0000000..959d356
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# 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
+
+SUBDIRS = src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
diff --git a/gcell/gcell.pc.in b/gcell/gcell.pc.in
new file mode 100644 (file)
index 0000000..2b6101d
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: gcell
+Description: The GNU Radio SPE scheduler and RPC mechanism
+Requires: gnuradio-omnithread mblock
+Version: @VERSION@
+Libs: -L${libdir} -lgcell
+Cflags: -I${includedir} @DEFINES@
diff --git a/gcell/src/Makefile.am b/gcell/src/Makefile.am
new file mode 100644 (file)
index 0000000..af76eb6
--- /dev/null
@@ -0,0 +1,23 @@
+#
+# 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 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
+
+SUBDIRS = include lib apps ibm
diff --git a/gcell/src/apps/Makefile.am b/gcell/src/apps/Makefile.am
new file mode 100644 (file)
index 0000000..e8cbf3c
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# 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 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
+
+SUBDIRS = spu .
+
+AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(MBLOCK_INCLUDES) \
+       $(GCELL_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES)
+
+
+GCELL_QA_LA = $(top_builddir)/gcell/src/lib/libgcell-qa.la
+
+TESTS = test_all
+
+
+bin_PROGRAMS = \
+       test_all \
+       benchmark_dma \
+       benchmark_nop
+
+
+test_all_SOURCES = test_all.cc
+test_all_LDADD = $(GCELL_QA_LA) $(GCELL_LA)
+
+benchmark_dma_SOURCES = benchmark_dma.cc
+benchmark_dma_LDADD = spu/benchmark_procs $(GCELL_LA) $(MBLOCK_LA)
+
+benchmark_nop_SOURCES = benchmark_nop.cc
+benchmark_nop_LDADD = spu/benchmark_procs $(GCELL_LA) $(MBLOCK_LA)
diff --git a/gcell/src/apps/benchmark_dma.cc b/gcell/src/apps/benchmark_dma.cc
new file mode 100644 (file)
index 0000000..c3df3a9
--- /dev/null
@@ -0,0 +1,265 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_job_manager.h"
+#include "mb_time.h"
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <boost/scoped_array.hpp>
+#include <assert.h>
+
+// handle to embedded SPU executable that contains benchmark routines
+// (The name of the variable (benchmark_procs) is the name of the spu executable.)
+extern spe_program_handle_t benchmark_procs;
+
+static gc_proc_id_t gcp_benchmark_udelay = GCP_UNKNOWN_PROC;
+
+#define        BENCHMARK_PUT           0x1
+#define        BENCHMARK_GET           0x2
+#define        BENCHMARK_GET_PUT       (BENCHMARK_PUT|BENCHMARK_GET)
+
+
+#if 0
+static bool
+power_of_2_p(unsigned long x)
+{
+  int nbits = sizeof(x) * 8;
+  for (int i = 0; i < nbits; i++)
+    if (x == (1UL << i))
+      return true;
+
+  return false;
+}
+#endif
+
+static void
+init_jd(gc_job_desc *jd, unsigned int usecs,
+       unsigned char *getbuf, unsigned char *putbuf, size_t buflen,
+       int getput_mask)
+{
+  jd->proc_id = gcp_benchmark_udelay;
+  jd->input.nargs = 1;
+  jd->input.arg[0].u32 = usecs;
+  jd->output.nargs = 0;
+
+  switch(getput_mask & BENCHMARK_GET_PUT){
+
+  case BENCHMARK_GET:
+    jd->eaa.nargs = 1;
+    jd->eaa.arg[0].direction = GCJD_DMA_GET;
+    jd->eaa.arg[0].ea_addr = ptr_to_ea(getbuf);
+    jd->eaa.arg[0].get_size = buflen;
+    break;
+
+  case BENCHMARK_PUT:
+    jd->eaa.nargs = 1;
+    jd->eaa.arg[0].direction = GCJD_DMA_PUT;
+    jd->eaa.arg[0].ea_addr = ptr_to_ea(putbuf);
+    jd->eaa.arg[0].put_size = buflen;
+    break;
+    
+  case BENCHMARK_GET_PUT:
+    jd->eaa.nargs = 2;
+    jd->eaa.arg[0].direction = GCJD_DMA_GET;
+    jd->eaa.arg[0].ea_addr = ptr_to_ea(getbuf);
+    jd->eaa.arg[0].get_size = buflen;
+    jd->eaa.arg[1].direction = GCJD_DMA_PUT;
+    jd->eaa.arg[1].ea_addr = ptr_to_ea(putbuf);
+    jd->eaa.arg[1].put_size = buflen;
+    break;
+  }
+}
+
+static void
+run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size, int getput_mask)
+{
+  static const int64_t TOTAL_SIZE_DMA = 5LL << 30;
+  static const int NJDS = 64;
+  unsigned int njobs = (unsigned int)(TOTAL_SIZE_DMA / dma_size);
+  //unsigned int njobs = NJDS * 16;
+  unsigned int nsubmitted = 0;
+  unsigned int ncompleted = 0;
+  gc_job_desc *all_jds[NJDS];
+  gc_job_desc *jds[2][NJDS];
+  unsigned int njds[2];
+  unsigned int ci;             // current index
+  bool done[NJDS];
+  
+  static const unsigned int BUFSIZE = (32 << 10) * NJDS;
+  unsigned char *getbuf = new unsigned char[BUFSIZE];
+  boost::scoped_array<unsigned char> _getbuf(getbuf);
+  unsigned char *putbuf = new unsigned char[BUFSIZE];
+  boost::scoped_array<unsigned char> _putbuf(putbuf);
+  int gbi = 0;
+
+  // touch all pages to force allocation now
+  for (unsigned int i = 0; i < BUFSIZE; i += 4096){
+    getbuf[i] = 0;
+    putbuf[i] = 0;
+  }
+
+  gc_jm_options opts;
+  opts.program_handle = &benchmark_procs;
+  opts.nspes = nspes;
+  //opts.enable_logging = true;
+  //opts.log2_nlog_entries = 13;
+  gc_job_manager *mgr = gc_make_job_manager(&opts);
+
+  if ((gcp_benchmark_udelay = mgr->lookup_proc("benchmark_udelay")) == GCP_UNKNOWN_PROC){
+    fprintf(stderr, "lookup_proc: failed to find \"benchmark_udelay\"\n");
+    return;
+  }
+
+  // allocate and init all job descriptors
+  for (int i = 0; i < NJDS; i++){
+    if (gbi + dma_size > BUFSIZE)
+      gbi = 0;
+
+    all_jds[i] = mgr->alloc_job_desc();
+    init_jd(all_jds[i], usecs, &getbuf[gbi], &putbuf[gbi], dma_size, getput_mask);
+    gbi += dma_size;
+  }
+
+  for (int iter = 0; iter < 1; iter++){
+
+    mb_time t_start = mb_time::time();
+
+    nsubmitted = 0;
+    ncompleted = 0;
+
+    ci = 0;
+    njds[0] = 0;
+    njds[1] = 0;
+  
+    // submit the first batch
+    for (int i = 0; i < NJDS; i++){
+      if (mgr->submit_job(all_jds[i])){
+       jds[ci][njds[ci]++] = all_jds[i];
+       nsubmitted++;
+      }
+      else {
+       printf("submit_job(jds[%d]) failed, status = %d\n",
+              i, all_jds[i]->status);
+      }
+    }
+  
+    while (ncompleted < njobs){
+      njds[ci^1] = 0;
+      int n = mgr->wait_jobs(njds[ci], jds[ci], done, GC_WAIT_ANY);
+      // printf("%2d\n", n);
+      if (n < 0){
+       fprintf(stderr, "mgr->wait_jobs failed\n");
+       break;
+      }
+      for (unsigned int i = 0; i < njds[ci]; i++){
+       if (!done[i]){  // remember for next iteration
+         jds[ci^1][njds[ci^1]++] = jds[ci][i];
+       }
+       else {
+         ncompleted++;
+         // printf("ncompleted = %7d\n", ncompleted);
+         if (nsubmitted < njobs){                  // submit another one
+           if (mgr->submit_job(jds[ci][i])){
+             jds[ci^1][njds[ci^1]++] = jds[ci][i];  // remember for next iter
+             nsubmitted++;
+           }
+           else {
+             printf("submit_job(jds[%d]) failed, status = %d\n",
+                    i, jds[ci][i]->status);
+           }
+         }
+       }
+      }
+      ci ^= 1; // toggle current
+    }
+
+    // stop timing
+    mb_time t_stop = mb_time::time();
+
+    double delta = (t_stop - t_start).double_time();
+    printf("nspes: %2d  udelay: %4d  elapsed_time: %7.3f  dma_size: %5d  dma_throughput: %7.3e\n",
+          mgr->nspes(), usecs, delta, dma_size,
+          (double) njobs * dma_size / delta * (getput_mask == BENCHMARK_GET_PUT ? 2.0 : 1.0));
+
+  }
+
+  delete mgr;
+}
+
+static void
+usage()
+{
+  fprintf(stderr, "usage: benchmark_dma [-p] [-g] [-n <nspes>] [-u <udelay>] [-s <dma_size>]\n");
+  fprintf(stderr, "  you must specify one or both of -p (put) and -g (get)\n");
+}
+
+
+int
+main(int argc, char **argv)
+{
+  unsigned int nspes = 0;
+  unsigned int usecs = 0;
+  unsigned int dma_size = 32 << 10;
+  int getput_mask = 0;
+  int ch;
+
+  while ((ch = getopt(argc, argv, "n:u:s:pg")) != EOF){
+    switch(ch){
+    case 'n':
+      nspes = strtol(optarg, 0, 0);
+      break;
+
+    case 'u':
+      usecs = strtol(optarg, 0, 0);
+      break;
+
+    case 's':
+      dma_size = strtol(optarg, 0, 0);
+      if (dma_size == 0){
+       fprintf(stderr, "-s <dma_size> must be > 0\n");
+       return 1;
+      }
+      break;
+
+    case 'p':
+      getput_mask |= BENCHMARK_PUT;
+      break;
+
+    case 'g':
+      getput_mask |= BENCHMARK_GET;
+      break;
+      
+    case '?':
+    default:
+      usage();
+      return 1;
+    }
+  }
+
+  if (getput_mask == 0){
+    usage();
+    return 1;
+  }
+
+  run_test(nspes, usecs, dma_size, getput_mask);
+  return 0;
+}
diff --git a/gcell/src/apps/benchmark_nop.cc b/gcell/src/apps/benchmark_nop.cc
new file mode 100644 (file)
index 0000000..7ef3f63
--- /dev/null
@@ -0,0 +1,162 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_job_manager.h"
+#include "mb_time.h"
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+// handle to embedded SPU executable that contains benchmark routines
+// (The name of the variable (benchmark_procs) is the name of the spu executable.)
+extern spe_program_handle_t benchmark_procs;
+
+static gc_proc_id_t gcp_benchmark_udelay = GCP_UNKNOWN_PROC;
+
+static void
+init_jd(gc_job_desc *jd, unsigned int usecs)
+{
+  jd->proc_id = gcp_benchmark_udelay;
+  jd->input.nargs = 1;
+  jd->input.arg[0].u32 = usecs;
+  jd->output.nargs = 0;
+  jd->eaa.nargs = 0;
+}
+
+static void
+run_test(unsigned int nspes, unsigned int usecs, int njobs)
+{
+  static const int NJDS = 64;
+  int nsubmitted = 0;
+  int ncompleted = 0;
+  gc_job_desc *all_jds[NJDS];
+  gc_job_desc *jds[2][NJDS];
+  unsigned int njds[2];
+  unsigned int ci;             // current index
+  bool done[NJDS];
+  
+  gc_jm_options opts;
+  opts.program_handle = &benchmark_procs;
+  opts.nspes = nspes;
+  opts.gang_schedule = true;
+  gc_job_manager *mgr = gc_make_job_manager(&opts);
+
+  if ((gcp_benchmark_udelay = mgr->lookup_proc("benchmark_udelay")) == GCP_UNKNOWN_PROC){
+    fprintf(stderr, "lookup_proc: failed to find \"benchmark_udelay\"\n");
+    return;
+  }
+
+  // allocate and init all job descriptors
+  for (int i = 0; i < NJDS; i++){
+    all_jds[i] = mgr->alloc_job_desc();
+    init_jd(all_jds[i], usecs);
+  }
+
+  mb_time t_start = mb_time::time();
+
+  ci = 0;
+  njds[0] = 0;
+  njds[1] = 0;
+  
+  // submit the first batch
+  for (int i = 0; i < NJDS; i++){
+    if (mgr->submit_job(all_jds[i])){
+      jds[ci][njds[ci]++] = all_jds[i];
+      nsubmitted++;
+    }
+    else {
+      printf("submit_job(jds[%d]) failed, status = %d\n",
+            i, all_jds[i]->status);
+    }
+  }
+  
+  while (ncompleted < njobs){
+    njds[ci^1] = 0;
+    int n = mgr->wait_jobs(njds[ci], jds[ci], done, GC_WAIT_ANY);
+    // printf("%2d\n", n);
+    if (n < 0){
+      fprintf(stderr, "mgr->wait_jobs failed\n");
+      break;
+    }
+    for (unsigned int i = 0; i < njds[ci]; i++){
+      if (!done[i]){   // remember for next iteration
+       jds[ci^1][njds[ci^1]++] = jds[ci][i];
+      }
+      else {
+       ncompleted++;
+       // printf("ncompleted = %7d\n", ncompleted);
+       if (nsubmitted < njobs){                    // submit another one
+         if (mgr->submit_job(jds[ci][i])){
+           jds[ci^1][njds[ci^1]++] = jds[ci][i];  // remember for next iter
+           nsubmitted++;
+         }
+         else {
+           printf("submit_job(jds[%d]) failed, status = %d\n",
+                  i, jds[ci][i]->status);
+         }
+       }
+      }
+    }
+    ci ^= 1;   // toggle current
+  }
+
+  // stop timing
+  mb_time t_stop = mb_time::time();
+  double delta = (t_stop - t_start).double_time();
+  printf("nspes: %2d  udelay: %4d  elapsed_time: %7.3f  njobs: %g  speedup: %6.3f\n",
+        mgr->nspes(), usecs, delta, (double) njobs,
+        njobs * usecs * 1e-6 / delta);
+
+  delete mgr;
+}
+
+int
+main(int argc, char **argv)
+{
+  unsigned int nspes = 0;
+  unsigned int usecs = 0;
+  int njobs = 500000;
+  int ch;
+
+  while ((ch = getopt(argc, argv, "n:u:N:")) != EOF){
+    switch(ch){
+    case 'n':
+      nspes = strtol(optarg, 0, 0);
+      break;
+
+    case 'u':
+      usecs = strtol(optarg, 0, 0);
+      break;
+
+    case 'N':
+      njobs = strtol(optarg, 0, 0);
+      break;
+
+    case '?':
+    default:
+      fprintf(stderr, "usage: benchmark_nop [-n <nspes>] [-u <udelay>] [-N <njobs>]\n");
+      return 1;
+    }
+  }
+
+  run_test(nspes, usecs, njobs);
+  return 0;
+}
diff --git a/gcell/src/apps/gen_script.py b/gcell/src/apps/gen_script.py
new file mode 100755 (executable)
index 0000000..e4bbc74
--- /dev/null
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+import sys
+import time
+import os
+
+from optparse import OptionParser
+
+
+def get_svn_rev():
+    try:
+        f = os.popen("svn info", "r")
+        lines = f.readlines()
+        f.close()
+    except:
+        return "unk"
+
+    svn_rev = "unk"
+    for l in lines:
+        if l.startswith('Revision:'):
+            t = l.rstrip()
+            svn_rev = t.split()[-1]
+    return svn_rev
+    
+def is_ps3():
+    try:
+        f = open("/proc/cpuinfo")
+        s = f.read()
+    except:
+        return False
+
+    return s.find('PS3') != -1
+
+
+def main():
+
+    def make_fname(suffix):
+        return basename + '.' + suffix
+
+    max_spes_default = 16
+    if is_ps3():
+        max_spes_default = 6
+        
+    parser = OptionParser()
+    parser.add_option("-m", "--max-spes", type="int", default=max_spes_default,
+                      metavar="NSPES",
+                      help="maximum number of SPEs to use [default=%default]")
+    parser.add_option("", "--min-spes", type="int", default=1,
+                      metavar="NSPES",
+                      help="minimum number of SPEs to use [default=%default]")
+    parser.add_option("-p", "--oprofile", action="store_true", default=False,
+                      help="emit oprofile commands")
+    parser.add_option("-t", "--tag", default=None,
+                      help="additional goodie in generated filenames")
+    (options, args) = parser.parse_args()
+    if len(args) != 0:
+        parser.print_help()
+        sys.exit(1)
+
+    svn_rev = get_svn_rev()
+
+    os.environ['TZ'] = 'PST8PDT'        # always pacific
+    time.tzset()
+
+    tag = ''
+    if options.tag:
+        tag = '-' + options.tag
+        
+    basename = 'R-%s%s-%s' % (svn_rev, tag, time.strftime('%Y%m%d-%H%M'))
+
+    base_njobs = int(500e3)
+    njobs = {
+         1 : base_njobs,
+        10 : base_njobs,
+        50 : base_njobs,
+       100 : base_njobs, 
+       200 : int(base_njobs/2),
+       250 : int(base_njobs/2.5),
+       300 : int(base_njobs/3),
+       400 : int(base_njobs/4),
+       500 : int(base_njobs/5)
+        }
+
+    
+    f_results = make_fname('results')
+    f_opreport = make_fname('opreport')
+    f_avg = make_fname('avg')
+    f_png = make_fname('png')
+
+    f = sys.stdout
+    f.write("#!/bin/bash\n")
+
+    if options.oprofile:
+        f.write("opcontrol --stop\n")
+        f.write("opcontrol --reset\n")
+        f.write("opcontrol --start\n")
+
+    f.write("(\n")
+
+    for udelay in (10, 50, 100, 200, 300):
+        for nspes in range(options.min_spes, options.max_spes+1):
+            cmd = "./benchmark_nop -n %d -u %d -N %d\n" % (nspes, udelay, njobs[udelay])
+            f.write(cmd)
+            f.write(cmd)
+
+    f.write(") | tee %s\n" % (f_results,))
+
+    if options.oprofile:
+        f.write("opcontrol --dump\n")
+        f.write("opcontrol --stop\n")
+        f.write("opreport -l | head -100 > %s\n" % (f_opreport,))
+
+    f.write("./split_and_avg_results.py %s > %s\n" % (f_results, f_avg))
+    f.write("./plot_speedup.py %s -o %s\n" % (f_avg, f_png))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/gcell/src/apps/plot_speedup.py b/gcell/src/apps/plot_speedup.py
new file mode 100755 (executable)
index 0000000..96277f8
--- /dev/null
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+from optparse import OptionParser
+from pylab import *
+from pprint import pprint
+import os.path
+
+
+def add_entry(d, nspes, speedup, work_incr):
+    if d.has_key(work_incr):
+        d[work_incr].append((nspes, speedup))
+    else:
+        d[work_incr] = [(nspes, speedup)]
+    
+def parse_file(f):
+    d = {}
+    for line in f:
+        items = [float(x) for x in line.split()]
+        # print "items =", items
+        nspes = items[0]
+        work_incr = int(1e6 * items[1])
+        speedup = items[4]
+        add_entry(d, nspes, speedup, work_incr)
+    return d
+
+
+class plot_data(object):
+    def __init__(self, filenames, output_filename):
+        self.fig = figure(1, figsize=(8, 6), facecolor='w')
+        self.sp = self.fig.add_subplot(1,1,1)
+        self.sp.set_xlabel("nspes", fontweight="bold")
+        self.sp.set_ylabel("speedup", fontweight="bold")
+        self.sp.grid(True)
+        # print 'rcParams["legend.fontsize"] =', rcParams["legend.fontsize"]
+        rcParams["legend.fontsize"] = 10
+
+
+        self.markers = {
+             10 : 'o',
+             50 : 's',
+            100 : '^',
+            200 : 'D',
+            300 : 'v',
+            400 : '>',
+            500 : 'h'
+            }
+        
+        if len(filenames) == 1:
+            f = filenames[0]
+            d = parse_file(open(f))
+            self.make_single_plot(d, f)
+            
+        else:
+            for f in filenames:
+                d = parse_file(open(f))
+                self.make_plot(d, f, f == filenames[0])
+
+        if output_filename:
+            savefig(output_filename)
+        else:
+            show()
+
+
+    def make_single_plot(self, d, filename):
+        def style(k):
+            return self.markers[k]
+
+        tag, ext = os.path.splitext(os.path.basename(filename))
+        title(tag)
+        keys = d.keys()
+        keys.sort()
+        keys.reverse()
+        for k in keys:
+            vlist = d[k]         # list of 2-tuples
+            xs = [v[0] for v in vlist]
+            ys = [v[1] for v in vlist]
+            plot(xs, ys, style(k), label="%d us" % (k,))
+
+        x = legend(loc=2)
+
+    def make_plot(self, d, filename, first):
+        def style(k):
+            if first:
+                return self.markers[k]
+            else:
+                return 'k' + self.markers[k]
+
+        tag, ext = os.path.splitext(os.path.basename(filename))
+        keys = d.keys()
+        keys.sort()
+        keys.reverse()
+        for k in keys:
+            vlist = d[k]         # list of 2-tuples
+            xs = [v[0] for v in vlist]
+            ys = [v[1] for v in vlist]
+            plot(xs, ys, style(k), label="%s %d us" % (tag, k))
+
+        x = legend(loc=2)
+
+def main():
+    usage="%prog: [options] input_filename..."
+    description = "Plot R*.avg files from benchmark_nop.py"
+    parser = OptionParser(usage=usage, description=description)
+    parser.add_option('-o', '--output', default=None,  metavar="FILE",
+                      help="generate .png file")
+    (options, args) = parser.parse_args()
+    if len(args) < 1:
+        parser.print_help()
+        raise SystemExit, 1
+
+    filenames = args
+    dc = plot_data(filenames, options.output)
+
+
+        
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
+
diff --git a/gcell/src/apps/results-071223 b/gcell/src/apps/results-071223
new file mode 100644 (file)
index 0000000..2716171
--- /dev/null
@@ -0,0 +1,126 @@
+nspes:  1  udelay:    1  elapsed_time:  26.117  njobs: 1e+06  us/job:  26.117
+nspes:  1  udelay:    1  elapsed_time:  26.058  njobs: 1e+06  us/job:  26.058
+nspes:  1  udelay:    1  elapsed_time:  26.737  njobs: 1e+06  us/job:  26.737
+nspes:  2  udelay:    1  elapsed_time:  23.585  njobs: 1e+06  us/job:  23.585
+nspes:  2  udelay:    1  elapsed_time:  21.958  njobs: 1e+06  us/job:  21.958
+nspes:  2  udelay:    1  elapsed_time:  21.034  njobs: 1e+06  us/job:  21.034
+nspes:  3  udelay:    1  elapsed_time:  25.819  njobs: 1e+06  us/job:  25.819
+nspes:  3  udelay:    1  elapsed_time:  23.719  njobs: 1e+06  us/job:  23.719
+nspes:  3  udelay:    1  elapsed_time:  21.711  njobs: 1e+06  us/job:  21.711
+nspes:  4  udelay:    1  elapsed_time:  20.210  njobs: 1e+06  us/job:  20.210
+nspes:  4  udelay:    1  elapsed_time:  20.558  njobs: 1e+06  us/job:  20.558
+nspes:  4  udelay:    1  elapsed_time:  20.957  njobs: 1e+06  us/job:  20.957
+nspes:  5  udelay:    1  elapsed_time:  24.571  njobs: 1e+06  us/job:  24.571
+nspes:  5  udelay:    1  elapsed_time:  20.207  njobs: 1e+06  us/job:  20.207
+nspes:  5  udelay:    1  elapsed_time:  21.976  njobs: 1e+06  us/job:  21.976
+nspes:  6  udelay:    1  elapsed_time:  22.601  njobs: 1e+06  us/job:  22.601
+nspes:  6  udelay:    1  elapsed_time:  18.794  njobs: 1e+06  us/job:  18.794
+nspes:  6  udelay:    1  elapsed_time:  19.755  njobs: 1e+06  us/job:  19.755
+nspes:  1  udelay:    5  elapsed_time:  28.047  njobs: 1e+06  us/job:  28.047
+nspes:  1  udelay:    5  elapsed_time:  27.265  njobs: 1e+06  us/job:  27.265
+nspes:  1  udelay:    5  elapsed_time:  27.555  njobs: 1e+06  us/job:  27.555
+nspes:  2  udelay:    5  elapsed_time:  21.130  njobs: 1e+06  us/job:  21.130
+nspes:  2  udelay:    5  elapsed_time:  21.067  njobs: 1e+06  us/job:  21.067
+nspes:  2  udelay:    5  elapsed_time:  21.607  njobs: 1e+06  us/job:  21.607
+nspes:  3  udelay:    5  elapsed_time:  23.712  njobs: 1e+06  us/job:  23.712
+nspes:  3  udelay:    5  elapsed_time:  23.658  njobs: 1e+06  us/job:  23.658
+nspes:  3  udelay:    5  elapsed_time:  25.277  njobs: 1e+06  us/job:  25.277
+nspes:  4  udelay:    5  elapsed_time:  22.264  njobs: 1e+06  us/job:  22.264
+nspes:  4  udelay:    5  elapsed_time:  20.970  njobs: 1e+06  us/job:  20.970
+nspes:  4  udelay:    5  elapsed_time:  21.533  njobs: 1e+06  us/job:  21.533
+nspes:  5  udelay:    5  elapsed_time:  21.504  njobs: 1e+06  us/job:  21.504
+nspes:  5  udelay:    5  elapsed_time:  21.956  njobs: 1e+06  us/job:  21.956
+nspes:  5  udelay:    5  elapsed_time:  21.333  njobs: 1e+06  us/job:  21.333
+nspes:  6  udelay:    5  elapsed_time:  20.639  njobs: 1e+06  us/job:  20.639
+nspes:  6  udelay:    5  elapsed_time:  23.022  njobs: 1e+06  us/job:  23.022
+nspes:  6  udelay:    5  elapsed_time:  22.453  njobs: 1e+06  us/job:  22.453
+nspes:  1  udelay:   10  elapsed_time:  27.780  njobs: 1e+06  us/job:  27.780
+nspes:  1  udelay:   10  elapsed_time:  27.683  njobs: 1e+06  us/job:  27.683
+nspes:  1  udelay:   10  elapsed_time:  26.803  njobs: 1e+06  us/job:  26.803
+nspes:  2  udelay:   10  elapsed_time:  20.878  njobs: 1e+06  us/job:  20.878
+nspes:  2  udelay:   10  elapsed_time:  22.430  njobs: 1e+06  us/job:  22.430
+nspes:  2  udelay:   10  elapsed_time:  20.952  njobs: 1e+06  us/job:  20.952
+nspes:  3  udelay:   10  elapsed_time:  22.752  njobs: 1e+06  us/job:  22.752
+nspes:  3  udelay:   10  elapsed_time:  24.294  njobs: 1e+06  us/job:  24.294
+nspes:  3  udelay:   10  elapsed_time:  23.935  njobs: 1e+06  us/job:  23.935
+nspes:  4  udelay:   10  elapsed_time:  20.437  njobs: 1e+06  us/job:  20.437
+nspes:  4  udelay:   10  elapsed_time:  21.498  njobs: 1e+06  us/job:  21.498
+nspes:  4  udelay:   10  elapsed_time:  20.521  njobs: 1e+06  us/job:  20.521
+nspes:  5  udelay:   10  elapsed_time:  22.704  njobs: 1e+06  us/job:  22.704
+nspes:  5  udelay:   10  elapsed_time:  21.106  njobs: 1e+06  us/job:  21.106
+nspes:  5  udelay:   10  elapsed_time:  22.800  njobs: 1e+06  us/job:  22.800
+nspes:  6  udelay:   10  elapsed_time:  21.098  njobs: 1e+06  us/job:  21.098
+nspes:  6  udelay:   10  elapsed_time:  22.749  njobs: 1e+06  us/job:  22.749
+nspes:  6  udelay:   10  elapsed_time:  19.651  njobs: 1e+06  us/job:  19.651
+nspes:  1  udelay:   50  elapsed_time:  54.621  njobs: 1e+06  us/job:  54.621
+nspes:  1  udelay:   50  elapsed_time:  54.548  njobs: 1e+06  us/job:  54.548
+nspes:  1  udelay:   50  elapsed_time:  54.641  njobs: 1e+06  us/job:  54.641
+nspes:  2  udelay:   50  elapsed_time:  30.837  njobs: 1e+06  us/job:  30.837
+nspes:  2  udelay:   50  elapsed_time:  30.933  njobs: 1e+06  us/job:  30.933
+nspes:  2  udelay:   50  elapsed_time:  30.044  njobs: 1e+06  us/job:  30.044
+nspes:  3  udelay:   50  elapsed_time:  24.170  njobs: 1e+06  us/job:  24.170
+nspes:  3  udelay:   50  elapsed_time:  23.798  njobs: 1e+06  us/job:  23.798
+nspes:  3  udelay:   50  elapsed_time:  23.515  njobs: 1e+06  us/job:  23.515
+nspes:  4  udelay:   50  elapsed_time:  23.011  njobs: 1e+06  us/job:  23.011
+nspes:  4  udelay:   50  elapsed_time:  21.382  njobs: 1e+06  us/job:  21.382
+nspes:  4  udelay:   50  elapsed_time:  20.531  njobs: 1e+06  us/job:  20.531
+nspes:  5  udelay:   50  elapsed_time:  24.157  njobs: 1e+06  us/job:  24.157
+nspes:  5  udelay:   50  elapsed_time:  21.119  njobs: 1e+06  us/job:  21.119
+nspes:  5  udelay:   50  elapsed_time:  22.055  njobs: 1e+06  us/job:  22.055
+nspes:  6  udelay:   50  elapsed_time:  19.136  njobs: 1e+06  us/job:  19.136
+nspes:  6  udelay:   50  elapsed_time:  20.607  njobs: 1e+06  us/job:  20.607
+nspes:  6  udelay:   50  elapsed_time:  20.527  njobs: 1e+06  us/job:  20.527
+nspes:  1  udelay:  100  elapsed_time: 107.531  njobs: 1e+06  us/job: 107.531
+nspes:  1  udelay:  100  elapsed_time: 107.607  njobs: 1e+06  us/job: 107.607
+nspes:  1  udelay:  100  elapsed_time: 107.532  njobs: 1e+06  us/job: 107.532
+nspes:  2  udelay:  100  elapsed_time:  53.950  njobs: 1e+06  us/job:  53.950
+nspes:  2  udelay:  100  elapsed_time:  53.920  njobs: 1e+06  us/job:  53.920
+nspes:  2  udelay:  100  elapsed_time:  54.232  njobs: 1e+06  us/job:  54.232
+nspes:  3  udelay:  100  elapsed_time:  37.987  njobs: 1e+06  us/job:  37.987
+nspes:  3  udelay:  100  elapsed_time:  38.778  njobs: 1e+06  us/job:  38.778
+nspes:  3  udelay:  100  elapsed_time:  39.042  njobs: 1e+06  us/job:  39.042
+nspes:  4  udelay:  100  elapsed_time:  31.192  njobs: 1e+06  us/job:  31.192
+nspes:  4  udelay:  100  elapsed_time:  31.090  njobs: 1e+06  us/job:  31.090
+nspes:  4  udelay:  100  elapsed_time:  31.472  njobs: 1e+06  us/job:  31.472
+nspes:  5  udelay:  100  elapsed_time:  28.490  njobs: 1e+06  us/job:  28.490
+nspes:  5  udelay:  100  elapsed_time:  27.574  njobs: 1e+06  us/job:  27.574
+nspes:  5  udelay:  100  elapsed_time:  27.013  njobs: 1e+06  us/job:  27.013
+nspes:  6  udelay:  100  elapsed_time:  26.635  njobs: 1e+06  us/job:  26.635
+nspes:  6  udelay:  100  elapsed_time:  24.036  njobs: 1e+06  us/job:  24.036
+nspes:  6  udelay:  100  elapsed_time:  26.174  njobs: 1e+06  us/job:  26.174
+nspes:  1  udelay:  300  elapsed_time: 320.618  njobs: 1e+06  us/job: 320.618
+nspes:  1  udelay:  300  elapsed_time: 320.635  njobs: 1e+06  us/job: 320.635
+nspes:  1  udelay:  300  elapsed_time: 320.699  njobs: 1e+06  us/job: 320.699
+nspes:  2  udelay:  300  elapsed_time: 160.314  njobs: 1e+06  us/job: 160.314
+nspes:  2  udelay:  300  elapsed_time: 160.340  njobs: 1e+06  us/job: 160.340
+nspes:  2  udelay:  300  elapsed_time: 160.312  njobs: 1e+06  us/job: 160.312
+nspes:  3  udelay:  300  elapsed_time: 106.878  njobs: 1e+06  us/job: 106.878
+nspes:  3  udelay:  300  elapsed_time: 106.875  njobs: 1e+06  us/job: 106.875
+nspes:  3  udelay:  300  elapsed_time: 106.871  njobs: 1e+06  us/job: 106.871
+nspes:  4  udelay:  300  elapsed_time:  80.158  njobs: 1e+06  us/job:  80.158
+nspes:  4  udelay:  300  elapsed_time:  80.163  njobs: 1e+06  us/job:  80.163
+nspes:  4  udelay:  300  elapsed_time:  80.154  njobs: 1e+06  us/job:  80.154
+nspes:  5  udelay:  300  elapsed_time:  64.156  njobs: 1e+06  us/job:  64.156
+nspes:  5  udelay:  300  elapsed_time:  64.250  njobs: 1e+06  us/job:  64.250
+nspes:  5  udelay:  300  elapsed_time:  64.158  njobs: 1e+06  us/job:  64.158
+nspes:  6  udelay:  300  elapsed_time:  53.633  njobs: 1e+06  us/job:  53.633
+nspes:  6  udelay:  300  elapsed_time:  53.541  njobs: 1e+06  us/job:  53.541
+nspes:  6  udelay:  300  elapsed_time:  53.617  njobs: 1e+06  us/job:  53.617
+nspes:  1  udelay:  500  elapsed_time: 533.638  njobs: 1e+06  us/job: 533.638
+nspes:  1  udelay:  500  elapsed_time: 533.649  njobs: 1e+06  us/job: 533.649
+nspes:  1  udelay:  500  elapsed_time: 533.618  njobs: 1e+06  us/job: 533.618
+nspes:  2  udelay:  500  elapsed_time: 266.810  njobs: 1e+06  us/job: 266.810
+nspes:  2  udelay:  500  elapsed_time: 266.814  njobs: 1e+06  us/job: 266.814
+nspes:  2  udelay:  500  elapsed_time: 266.893  njobs: 1e+06  us/job: 266.893
+nspes:  3  udelay:  500  elapsed_time: 177.875  njobs: 1e+06  us/job: 177.875
+nspes:  3  udelay:  500  elapsed_time: 177.878  njobs: 1e+06  us/job: 177.878
+nspes:  3  udelay:  500  elapsed_time: 177.875  njobs: 1e+06  us/job: 177.875
+nspes:  4  udelay:  500  elapsed_time: 133.417  njobs: 1e+06  us/job: 133.417
+nspes:  4  udelay:  500  elapsed_time: 133.483  njobs: 1e+06  us/job: 133.483
+nspes:  4  udelay:  500  elapsed_time: 133.407  njobs: 1e+06  us/job: 133.407
+nspes:  5  udelay:  500  elapsed_time: 106.723  njobs: 1e+06  us/job: 106.723
+nspes:  5  udelay:  500  elapsed_time: 106.728  njobs: 1e+06  us/job: 106.728
+nspes:  5  udelay:  500  elapsed_time: 106.722  njobs: 1e+06  us/job: 106.722
+nspes:  6  udelay:  500  elapsed_time:  88.943  njobs: 1e+06  us/job:  88.943
+nspes:  6  udelay:  500  elapsed_time:  88.941  njobs: 1e+06  us/job:  88.941
+nspes:  6  udelay:  500  elapsed_time:  88.944  njobs: 1e+06  us/job:  88.944
diff --git a/gcell/src/apps/split_and_avg_results.py b/gcell/src/apps/split_and_avg_results.py
new file mode 100755 (executable)
index 0000000..8a750fa
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+#
+# 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 this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+"""
+input file looks like this:
+
+nspes:  1  udelay:   10  elapsed_time:   6.842  njobs: 500000  speedup:  0.731
+nspes:  2  udelay:   10  elapsed_time:   4.093  njobs: 500000  speedup:  1.221
+"""
+
+import sys
+from optparse import OptionParser
+from pprint import pprint
+
+class data(object):
+    def __init__(self, nspes, work_per_job, elapsed_time, njobs):
+        self.nspes = nspes
+        self.work_per_job = work_per_job  # seconds
+        self.elapsed_time = elapsed_time  # seconds
+        self.njobs = njobs
+        self.speedup = work_per_job * njobs / elapsed_time
+
+    def __repr__(self):
+        return "<data nspes=%d work_per_job=%s elapsed_time=%s njobs=%s speedup=%s>" % (
+            self.nspes, (self.work_per_job),
+            (self.elapsed_time),
+            (self.njobs),
+            (self.speedup))
+
+def cmp_data(x, y):
+    t = x.nspes - y.nspes
+    if t == 0:
+        t = x.work_per_job - y.work_per_job
+        if t < 0:
+            return -1
+        elif t > 0:
+            return +1
+        else:
+            return 0
+    return t
+
+def main():
+    usage = "usage: %prog [options] input_filename"
+    parser = OptionParser(usage=usage)
+    (options, args) = parser.parse_args()
+    if len(args) != 1:
+        parser.print_help()
+        raise SystemExit, 1
+    input_filename = args[0]
+
+    
+    m = {}
+    for line in open(input_filename, "r"):
+        s = line.split()
+        nspes = int(s[1])
+        work_per_job = int(s[3]) * 1e-6
+        elapsed_time = float(s[5])
+        njobs = float(s[7])
+        d = data(nspes, work_per_job, elapsed_time, njobs)
+
+        # collect lists that have the same values for nspes and work_per_job
+        # so we can generate an average elapsed_time from all observations
+        key = (nspes, work_per_job)
+        v = m.get(key, [])
+        v.append(d)
+        m[key] = v
+
+    r = []
+    for k, v in m.iteritems():
+        total_elapsed_time = sum([x.elapsed_time for x in v])
+        r.append(data(v[0].nspes,
+                      v[0].work_per_job,
+                      total_elapsed_time/len(v),
+                      v[0].njobs))
+
+    r.sort(cmp_data)
+
+    #pprint(r)
+    for t in r:
+        print t.nspes, t.work_per_job, t.elapsed_time, t.njobs, t.speedup
+
+if __name__ == '__main__':
+    main()
diff --git a/gcell/src/apps/spu/Makefile.am b/gcell/src/apps/spu/Makefile.am
new file mode 100644 (file)
index 0000000..c94fe18
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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.spu
+
+AM_CPPFLAGS = $(GCELL_SPU_INCLUDES)
+
+# SPU executables
+
+noinst_PROGRAMS = \
+       benchmark_procs
+
+benchmark_procs_SOURCES = benchmark_procs.c
+benchmark_procs_LDADD = $(GCELL_SPU_LA)
diff --git a/gcell/src/apps/spu/benchmark_procs.c b/gcell/src/apps/spu/benchmark_procs.c
new file mode 100644 (file)
index 0000000..8d5b406
--- /dev/null
@@ -0,0 +1,75 @@
+/* -*- 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 <gc_delay.h>
+#include <gc_declare_proc.h>
+#include <string.h>
+
+#define _UNUSED __attribute__((unused))
+
+
+static void
+benchmark_udelay(const gc_job_direct_args_t *input,
+                gc_job_direct_args_t *output _UNUSED,
+                const gc_job_ea_args_t *eaa _UNUSED)
+{
+  gc_udelay(input->arg[0].u32);
+}
+
+GC_DECLARE_PROC(benchmark_udelay, "benchmark_udelay");
+
+
+
+static void
+benchmark_put_zeros(const gc_job_direct_args_t *input _UNUSED,
+                   gc_job_direct_args_t *output _UNUSED,
+                   const gc_job_ea_args_t *eaa)
+{
+  for (unsigned int i = 0; i < eaa->nargs; i++){
+    if (eaa->arg[i].direction == GCJD_DMA_PUT)
+      memset(eaa->arg[i].ls_addr, 0, eaa->arg[i].put_size);
+  }
+}
+
+GC_DECLARE_PROC(benchmark_put_zeros, "benchmark_put_zeros");
+
+
+static void
+benchmark_copy(const gc_job_direct_args_t *input _UNUSED,
+              gc_job_direct_args_t *output,
+              const gc_job_ea_args_t *eaa)
+{
+  if (eaa->nargs != 2
+      || eaa->arg[0].direction != GCJD_DMA_PUT
+      || eaa->arg[1].direction != GCJD_DMA_GET){
+    output->arg[0].s32 = -1;
+    return;
+  }
+
+  output->arg[0].s32 = 0;
+  unsigned n = eaa->arg[0].put_size;
+  if (eaa->arg[1].get_size < n)
+    n = eaa->arg[1].get_size;
+  
+  memcpy(eaa->arg[0].ls_addr, eaa->arg[1].ls_addr, n);
+}
+
+GC_DECLARE_PROC(benchmark_copy, "benchmark_copy");
diff --git a/gcell/src/apps/test_all.cc b/gcell/src/apps/test_all.cc
new file mode 100644 (file)
index 0000000..e652de2
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <cppunit/TextTestRunner.h>
+
+#include <qa_lib.h>
+
+
+int 
+main(int argc, char **argv)
+{
+  
+  CppUnit::TextTestRunner      runner;
+
+  runner.addTest(qa_lib::suite());
+  
+  bool was_successful = runner.run("", false);
+
+  return was_successful ? 0 : 1;
+}
diff --git a/gcell/src/ibm/Makefile.am b/gcell/src/ibm/Makefile.am
new file mode 100644 (file)
index 0000000..8013e6a
--- /dev/null
@@ -0,0 +1,98 @@
+#
+# 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 = \
+       ./README \
+       ./sync/ppu_source/atomic_add.h \
+       ./sync/ppu_source/atomic_add_return.h \
+       ./sync/ppu_source/atomic_dec_and_test.h \
+       ./sync/ppu_source/atomic_dec.h \
+       ./sync/ppu_source/atomic_dec_if_positive.h \
+       ./sync/ppu_source/atomic_dec_return.h \
+       ./sync/ppu_source/atomic.h \
+       ./sync/ppu_source/atomic_inc.h \
+       ./sync/ppu_source/atomic_inc_return.h \
+       ./sync/ppu_source/atomic_read.h \
+       ./sync/ppu_source/atomic_set.h \
+       ./sync/ppu_source/atomic_sub_and_test.h \
+       ./sync/ppu_source/atomic_sub.h \
+       ./sync/ppu_source/atomic_sub_return.h \
+       ./sync/ppu_source/complete_all.h \
+       ./sync/ppu_source/complete.h \
+       ./sync/ppu_source/completion.h \
+       ./sync/ppu_source/cond_broadcast.h \
+       ./sync/ppu_source/cond.h \
+       ./sync/ppu_source/cond_init.h \
+       ./sync/ppu_source/cond_signal.h \
+       ./sync/ppu_source/cond_wait.h \
+       ./sync/ppu_source/init_completion.h \
+       ./sync/ppu_source/libsync.h \
+       ./sync/ppu_source/mutex.h \
+       ./sync/ppu_source/mutex_init.h \
+       ./sync/ppu_source/mutex_lock.h \
+       ./sync/ppu_source/mutex_trylock.h \
+       ./sync/ppu_source/mutex_unlock.h \
+       ./sync/ppu_source/pdt_libsync_config.xml \
+       ./sync/ppu_source/pdt_libsync.xml \
+       ./sync/ppu_source/sync_utils.h \
+       ./sync/ppu_source/trace_libsync.h \
+       ./sync/ppu_source/wait_for_completion.h \
+       ./sync/spu_source/atomic_add.h \
+       ./sync/spu_source/atomic_add_return.h \
+       ./sync/spu_source/atomic_dec_and_test.h \
+       ./sync/spu_source/atomic_dec.h \
+       ./sync/spu_source/atomic_dec_if_positive.h \
+       ./sync/spu_source/atomic_dec_return.h \
+       ./sync/spu_source/atomic.h \
+       ./sync/spu_source/atomic_inc.h \
+       ./sync/spu_source/atomic_inc_return.h \
+       ./sync/spu_source/atomic_read.h \
+       ./sync/spu_source/atomic_set.h \
+       ./sync/spu_source/atomic_sub_and_test.h \
+       ./sync/spu_source/atomic_sub.h \
+       ./sync/spu_source/atomic_sub_return.h \
+       ./sync/spu_source/complete_all.h \
+       ./sync/spu_source/complete.h \
+       ./sync/spu_source/completion.h \
+       ./sync/spu_source/cond_broadcast.h \
+       ./sync/spu_source/cond.h \
+       ./sync/spu_source/cond_init.h \
+       ./sync/spu_source/cond_signal.h \
+       ./sync/spu_source/cond_wait.h \
+       ./sync/spu_source/init_completion.h \
+       ./sync/spu_source/libsync.h \
+       ./sync/spu_source/mutex.h \
+       ./sync/spu_source/mutex_init.h \
+       ./sync/spu_source/mutex_lock.h \
+       ./sync/spu_source/mutex_trylock.h \
+       ./sync/spu_source/mutex_unlock.h \
+       ./sync/spu_source/read_lock.h \
+       ./sync/spu_source/read_trylock.h \
+       ./sync/spu_source/read_unlock.h \
+       ./sync/spu_source/rwlock_init.h \
+       ./sync/spu_source/sync_irq.h \
+       ./sync/spu_source/sync_utils.h \
+       ./sync/spu_source/trace_libsync.h \
+       ./sync/spu_source/wait_for_completion.h \
+       ./sync/spu_source/write_lock.h \
+       ./sync/spu_source/write_trylock.h \
+       ./sync/spu_source/write_unlock.h
diff --git a/gcell/src/ibm/README b/gcell/src/ibm/README
new file mode 100644 (file)
index 0000000..9420fcc
--- /dev/null
@@ -0,0 +1,10 @@
+This directory and below contains code from IBM licensed under the
+"Modified BSD license."  It was extracted unmodified from the IBM Cell
+SDK 3.0 library source tarball, lib_source.tar, typically found in
+/opt/cell/sdk/src/lib_source.tar.
+
+We've done this because this code doesn't come unpacked in the native
+(cell) installation of the SDK 3.0, and thus we can't just add a
+-I/path/to/this/stuff in our Makefiles.  If this changes, we'll delete
+this code from here, and fix our Makefiles.  In the meanwhile, this
+reduces the probability of build problems.
diff --git a/gcell/src/ibm/sync/ppu_source/atomic.h b/gcell/src/ibm/sync/ppu_source/atomic.h
new file mode 100644 (file)
index 0000000..105f7bf
--- /dev/null
@@ -0,0 +1,112 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+/*
+ * atomic.h - PPE atomic SHM counter operations.
+ *
+ * Interfaces patterned after, and hopefully compatible
+ * with PowerPC64-Linux atomic counter operations.  Uses
+ * 32b values for various counters.
+ */
+#ifndef _PPU_ATOMIC_H_
+#define _PPU_ATOMIC_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+
+typedef unsigned int atomic_t __attribute__ ((aligned (128))); 
+
+
+/* atomic_ea_t is a 64bit effective address  that points to 
+ * an atomic_t variable 
+ */
+typedef unsigned long long atomic_ea_t;
+
+/**
+ * ASSUMPTIONS:
+ * On the PPE, the size of a reservation granule is 128 bytes
+ * (a cache-line), so when a programmer puts a reservation on an
+ * address, that whole cacheline is reserved. Therefore both
+ * the PPE and SPE can participate in an atomic operation as long as
+ * lwarx and getllar operate on the same cacheline. 
+ */ 
+
+
+/*
+ * atomically loads and replaces the value v with val. 
+ * Returns the old value at v
+ */ 
+static __inline int _atomic_replace(atomic_ea_t v, int val)
+{
+  int old;
+  void *p;
+
+  SYNC_ULL_TO_PTR(v, p);
+
+  do {
+    old = (int)__lwarx(p);
+  } while (__stwcx(p, (unsigned int)val) == 0);
+
+  return old;
+}
+
+
+/*
+ * atomically loads the value at v, adds val, replaces the
+ * value at v with the sum. Returns the old value at v
+ */ 
+static __inline int _atomic_modify(atomic_ea_t v, int val)
+{
+  int oldval, newval;
+  void *p;
+
+  SYNC_ULL_TO_PTR(v, p);
+
+  do {
+    oldval = (int)__lwarx(p);
+    newval = oldval + val;
+  } while (__stwcx(p, (unsigned int)newval) == 0);
+
+  return oldval;
+}
+
+
+#endif /* _PPU_ATOMIC_H_ */
+
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_add.h b/gcell/src/ibm/sync/ppu_source/atomic_add.h
new file mode 100644 (file)
index 0000000..dd7a5b2
--- /dev/null
@@ -0,0 +1,62 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_ADD_H_
+#define _PPU_ATOMIC_ADD_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_add - atomically add to a counter.
+ * @v: handle to effective address of counter.
+ * @a: value to be added.
+ * 
+ * Atomically add a value to a counter in system memory. 
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_add(int a, atomic_ea_t v)
+{
+  _atomic_modify (v, a);
+}
+
+
+
+#endif /* _PPU_ATOMIC_ADD_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_add_return.h b/gcell/src/ibm/sync/ppu_source/atomic_add_return.h
new file mode 100644 (file)
index 0000000..0fe1275
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_ADD_RETURN_H_
+#define _PPU_ATOMIC_ADD_RETURN_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_add_return - atomically add to a counter and return previous value.
+ * @v: handle to effective address of counter.
+ * @a: value to be added.
+ *
+ * Atomically add a value to a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and add" primitive
+ * that is described in "Book I PowerPC User Instruction
+ * Set Architecture" 
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_add_return(int a, atomic_ea_t v)
+{
+  return _atomic_modify (v, a);
+}
+
+
+#endif /* _PPU_ATOMIC_ADD_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec.h b/gcell/src/ibm/sync/ppu_source/atomic_dec.h
new file mode 100644 (file)
index 0000000..4f82f04
--- /dev/null
@@ -0,0 +1,60 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_DEC_H_
+#define _PPU_ATOMIC_DEC_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_dec - atomically decrement a counter.
+ * @v: handle to effective address of location to be modified.
+ *
+ * Atomically decrement a counter in system memory. The only
+ * restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_dec(atomic_ea_t v)
+{
+  _atomic_modify (v, -1);
+}
+
+
+#endif /* _PPU_ATOMIC_DEC_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h
new file mode 100644 (file)
index 0000000..5093d40
--- /dev/null
@@ -0,0 +1,63 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_DEC_AND_TEST_H_
+#define _PPU_ATOMIC_DEC_AND_TEST_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_dec_and_test - atomically decrement and test if previous==0.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically decrement a counter in system memory and test 
+ * if previous==0.  The only restriction is that @v must be 
+ * word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_dec_and_test(atomic_ea_t v)
+{
+  return (_atomic_modify(v, -1) == 0) ? 1 : 0;
+}
+
+
+#endif /* _PPU_ATOMIC_DEC_AND_TEST_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h
new file mode 100644 (file)
index 0000000..c4d113b
--- /dev/null
@@ -0,0 +1,76 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_DEC_IF_POSITIVE_H_
+#define _PPU_ATOMIC_DEC_IF_POSITIVE_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "atomic.h"
+
+/*
+ * atomic_dec_if_positive - atomically decrement if counter is positive.
+ *
+ *  v: handle to effective address of counter.
+ * 
+ * Atomically decrement a counter if its value is positive.
+ * The only restriction is that v must be word aligned.
+ *
+ *
+ * Returns the old value of the counter, minus 1.
+ */
+static __inline int _atomic_dec_if_positive(atomic_ea_t v)
+{
+  int ret;
+  int tmp;
+  void *p;
+
+  SYNC_ULL_TO_PTR(v, p);
+
+  do {
+    tmp = (int)__lwarx(p);
+    ret = tmp - 1;
+    tmp = (tmp > 0) ? ret : tmp; 
+  } while (__stwcx(p, (unsigned)tmp) == 0);
+
+  return ret;
+}
+
+#endif /* _PPU_ATOMIC_DEC_IF_POSITIVE_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_return.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_return.h
new file mode 100644 (file)
index 0000000..cd87893
--- /dev/null
@@ -0,0 +1,68 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_DEC_RETURN_H_
+#define _PPU_ATOMIC_DEC_RETURN_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_dec_return - atomically decrement a counter and return previous value.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically decrement a counter in system memory and return its
+ * previous value. The only restriction is that @v must be word 
+ * aligned.
+ *
+ * This routine implements the "fetch and decrement"
+ * primitive that is described in "Book I PowerPC User
+ * Instruction Set Architecture".
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_dec_return(atomic_ea_t v)
+{
+  return _atomic_modify (v, -1);
+}
+
+
+
+#endif /* _PPU_ATOMIC_DEC_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_inc.h b/gcell/src/ibm/sync/ppu_source/atomic_inc.h
new file mode 100644 (file)
index 0000000..714aecb
--- /dev/null
@@ -0,0 +1,59 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_INC_H_
+#define _PPU_ATOMIC_INC_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_inc - atomically increment a counter in system memory.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically increment a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_inc(atomic_ea_t v)
+{
+  _atomic_modify (v, 1); 
+}
+
+#endif /* _PPU_ATOMIC_INC_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_inc_return.h b/gcell/src/ibm/sync/ppu_source/atomic_inc_return.h
new file mode 100644 (file)
index 0000000..95178f5
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_INC_RETURN_H_
+#define _PPU_ATOMIC_INC_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+
+/**
+ * atomic_inc_return - atomically increment a counter and return previous.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically increment a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and increment"
+ * primitive that is described in "Book I PowerPC User
+ * Instruction Set Architecture" 
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_inc_return(atomic_ea_t v)
+{
+  return _atomic_modify (v, 1);
+}
+
+#endif /* _PPU_ATOMIC_INC_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_read.h b/gcell/src/ibm/sync/ppu_source/atomic_read.h
new file mode 100644 (file)
index 0000000..258fd51
--- /dev/null
@@ -0,0 +1,62 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_READ_H_
+#define _PPU_ATOMIC_READ_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/*
+ * On PowerPC architecture, if v is a word_aligned address, then
+ * a load of that address is guaranteed to be atomic.  An atomic
+ * read operation is simply a load.
+ */ 
+static __inline int _atomic_read(atomic_ea_t v)
+{
+  volatile int *p;
+
+  SYNC_ULL_TO_PTR(v, p);
+
+  return (*p);
+}
+
+
+#endif /* _PPU_ATOMIC_READ_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_set.h b/gcell/src/ibm/sync/ppu_source/atomic_set.h
new file mode 100644 (file)
index 0000000..e624af4
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_SET_H_
+#define _PPU_ATOMIC_SET_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_set - atomically set a counter in system memory.
+ * @v: this is a 64bit address that points to an atomic_t 
+ * 
+ * Atomically set a counter to a given value. The only 
+ * restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and store" 
+ * primitive that is described in "Book I PowerPC User 
+ * Instruction Set Architecture"
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline void _atomic_set(atomic_ea_t v, int val)
+{
+  _atomic_replace (v, val);
+}
+
+
+#endif /* _PPU_ATOMIC_SET_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub.h b/gcell/src/ibm/sync/ppu_source/atomic_sub.h
new file mode 100644 (file)
index 0000000..b8d3597
--- /dev/null
@@ -0,0 +1,61 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_SUB_H_
+#define _PPU_ATOMIC_SUB_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_sub - atomically subtract from a counter.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_sub(int a, atomic_ea_t v)
+{
+  _atomic_modify (v, -a);
+}
+
+
+#endif /* _PPU_ATOMIC_SUB_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h b/gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h
new file mode 100644 (file)
index 0000000..37ba588
--- /dev/null
@@ -0,0 +1,63 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_SUB_AND_TEST_H_
+#define _PPU_ATOMIC_SUB_AND_TEST_H_
+
+#include "sync_utils.h"
+#include "atomic.h"
+
+/**
+ * atomic_sub_and_test - atomically subtract and test if previous==0.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory
+ * and test if previous==0.  The only restriction is that @v 
+ * must be word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_sub_and_test(int a, atomic_ea_t v)
+{
+  return (_atomic_modify(v, -a) == 0) ? 1 : 0;
+}
+
+#endif /* _PPU_ATOMIC_SUB_AND_TEST_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub_return.h b/gcell/src/ibm/sync/ppu_source/atomic_sub_return.h
new file mode 100644 (file)
index 0000000..084bfa6
--- /dev/null
@@ -0,0 +1,65 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_ATOMIC_SUB_RETURN_H_
+#define _PPU_ATOMIC_SUB_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+
+/**
+ * atomic_sub_return - atomically subtract from a counter & return previous.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+
+
+static __inline int _atomic_sub_return(int a, atomic_ea_t v)
+{
+  return _atomic_modify (v, -a);
+}
+
+#endif /* _PPU_ATOMIC_SUB_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/complete.h b/gcell/src/ibm/sync/ppu_source/complete.h
new file mode 100644 (file)
index 0000000..8633463
--- /dev/null
@@ -0,0 +1,61 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COMPLETE_H_
+#define _PPU_COMPLETE_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "completion.h"
+
+
+static __inline void _complete (completion_ea_t comp)
+{
+  unsigned int old;
+  void *p;
+
+  SYNC_ULL_TO_PTR(comp, p);
+
+  do {
+    old = __lwarx(p);
+  } while (__stwcx(p, (unsigned int)1) == 0);
+}
+
+#endif /* _PPU_COMPLETE_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/complete_all.h b/gcell/src/ibm/sync/ppu_source/complete_all.h
new file mode 100644 (file)
index 0000000..c12eb7f
--- /dev/null
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COMPLETE_ALL_H_
+#define _PPU_COMPLETE_ALL_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "completion.h"
+
+/**
+ * complete_all - indicate that a completion is true.
+ * @completion: handle to effective address of completion variable.
+ *
+ * Indicate that all are completed is true by storing 
+ * MAX_THREADS_WAITING to the completionition variable.
+ */
+
+static __inline void _complete_all(completion_ea_t comp)
+{
+  unsigned int old;
+  unsigned int val = MAX_THREADS_WAITING;
+
+  void *p;
+
+  SYNC_ULL_TO_PTR(comp, p);
+
+  do {
+    old = __lwarx(p);
+  } while (__stwcx(p, val) == 0);
+}
+
+#endif /* _PPU_COMPLETE_ALL_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/completion.h b/gcell/src/ibm/sync/ppu_source/completion.h
new file mode 100644 (file)
index 0000000..b74bdaa
--- /dev/null
@@ -0,0 +1,50 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+
+#ifndef _PPU_COMPLETION_H_
+#define _PPU_COMPLETION_H_
+
+
+#define MAX_THREADS_WAITING   32000 
+
+typedef unsigned long long completion_ea_t;
+
+#endif /* _PPU_COMPLETION_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/cond.h b/gcell/src/ibm/sync/ppu_source/cond.h
new file mode 100644 (file)
index 0000000..9a38f71
--- /dev/null
@@ -0,0 +1,65 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COND_VAR_H_
+#define _PPU_COND_VAR_H_
+
+#include <mutex.h>
+#include <sync_utils.h>
+
+
+typedef struct
+{
+  short num_threads_signal;       /* the number of threads that are going to be waken up.
+                                 There are 3 values possible for this parameter, 0, 1, 
+                                 or num_threads_waiting*/
+  short num_threads_waiting;      /* the number of threads that are waiting to be awaken */ 
+} condition_variable_t __attribute__ ((aligned (16)));  
+
+typedef unsigned long long cond_ea_t;         /* a system memory 64 bit address that points to
+                                 * a valid condition_variable_t */
+
+typedef union {
+    unsigned long long ull;  
+    unsigned int ui[2];
+} val64;
+
+
+#endif /* _PPU_COND_VAR_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/cond_broadcast.h b/gcell/src/ibm/sync/ppu_source/cond_broadcast.h
new file mode 100644 (file)
index 0000000..b93bf7b
--- /dev/null
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COND_BROADCAST_H_
+#define _PPU_COND_BROADCAST_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "cond.h"
+
+/**
+ * cond_broadcast - indicate that a condition is true.
+ * @cond: handle to effective address of condition variable.
+ */
+static __inline void _cond_broadcast (cond_ea_t cond)
+{
+  unsigned int val;
+  void *p;
+
+  SYNC_ULL_TO_PTR(cond, p);
+  
+  do {
+    val = __lwarx(p);
+
+    /* Copy the waiting count (low halfword) to
+     * the signaled count (high halfword)
+     */
+    val = (val & 0xFFFF) | ((val+1) << 16);
+    
+  } while (__stwcx(p, val) == 0);
+}
+
+#endif /* _PPU_COND_BROADCAST_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/cond_init.h b/gcell/src/ibm/sync/ppu_source/cond_init.h
new file mode 100644 (file)
index 0000000..0dfbd63
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COND_INIT_H_
+#define _PPU_COND_INIT_H_
+
+#include "sync_utils.h"
+#include "cond.h"
+
+/**
+ * cond_init - initialize condition variable.
+ * @cond: handle to effective address of condition variable.
+ *
+ * Only one thread initializes a condition variable. Usually, the 
+ * PPE thread initializes a condidtion variable 
+ *
+ * Description: Initialize a cond variable to false.
+ */
+static __inline void _cond_init (cond_ea_t  cond)
+{
+  volatile unsigned int *p;
+
+  SYNC_ULL_TO_PTR(cond, p);
+
+  *p = 0;
+}
+
+
+#endif /* _PPU_COND_INIT_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/cond_signal.h b/gcell/src/ibm/sync/ppu_source/cond_signal.h
new file mode 100644 (file)
index 0000000..dd48748
--- /dev/null
@@ -0,0 +1,74 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COND_SIGNAL_H_
+#define _PPU_COND_SIGNAL_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "cond.h"
+
+/*
+ * _cond_signal: signaling any of the waiting threads to wake up.
+ */ 
+static __inline void _cond_signal (cond_ea_t cond)
+{
+  unsigned int val, waiting, signaled;
+  void *p;
+
+  SYNC_ULL_TO_PTR(cond, p);
+  
+  do {
+    val = __lwarx(p);
+
+    waiting = val & 0xFFFF;
+    signaled = val >> 16;
+    
+    /* If no other party is waiting. Don't send a signal.
+     * Otherwise, increment the signaled halfword.
+     */
+    if (waiting == signaled) break;
+    val = ((val+1) << 16) | waiting;
+
+  } while (__stwcx(p, val) == 0);
+}
+
+
+#endif /* _PPU_COND_SIGNAL_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/cond_wait.h b/gcell/src/ibm/sync/ppu_source/cond_wait.h
new file mode 100644 (file)
index 0000000..ed5fbec
--- /dev/null
@@ -0,0 +1,96 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_COND_WAIT_H_
+#define _PPU_COND_WAIT_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "mutex_lock.h"
+#include "mutex_unlock.h"
+#include "cond.h"
+
+static __inline void _cond_wait (cond_ea_t cond, mutex_ea_t  mutex)
+{
+  int delta, cur_delta;
+  unsigned int val, cond_val, signaled_cnt;
+  void *p;
+
+
+  SYNC_ULL_TO_PTR(cond, p);
+
+  /* Atomically signal we have entered the condition wait by incrementing
+   * the waiting count.
+   */
+  do {
+    val = __lwarx(p);
+    val = (val & ~0xFFFF) | ((val+1) & 0xFFFF);
+  } while (__stwcx(p, val) == 0);
+
+
+  /* Release the lock
+   */
+  _mutex_unlock (mutex);
+
+  /* Determine the signal count needed for this 
+   * participant to be signaled.
+   */
+
+  signaled_cnt = val >> 16;
+  delta = (int)(val & 0xFFFF) - (int)signaled_cnt;
+  if (delta < 0) delta = -delta;
+
+  /* Wait until the signaled count reaches the count
+   * previously determined.
+   */
+  do {
+    cond_val = __lwarx(p);
+
+    cur_delta = (int)(cond_val >> 16) - signaled_cnt;
+    if (cur_delta < 0) cur_delta = -cur_delta;
+   
+  } while (cur_delta < delta);
+
+  /* Relock the mutex 
+   */
+  _mutex_lock (mutex);
+}
+
+#endif /* _PPU_COND_WAIT_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/init_completion.h b/gcell/src/ibm/sync/ppu_source/init_completion.h
new file mode 100644 (file)
index 0000000..8e70811
--- /dev/null
@@ -0,0 +1,63 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_INIT_COMPLETION_H_
+#define _PPU_INIT_COMPLETION_H_
+
+#include "sync_utils.h"
+#include "completion.h"
+
+/**
+ * completion_init - initialize completion variable.
+ * @completion: handle to effective address of completion variable.
+ *
+ * Description: Initialize a completion variable to 0.
+ */
+static __inline void _init_completion(completion_ea_t comp)
+{
+  volatile unsigned int *p;
+
+  SYNC_ULL_TO_PTR(comp, p);
+
+  *p = 0;
+}
+
+
+#endif /* _PPU_INIT_COMPLETION_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/libsync.h b/gcell/src/ibm/sync/ppu_source/libsync.h
new file mode 100644 (file)
index 0000000..bd2e043
--- /dev/null
@@ -0,0 +1,114 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_LIBSYNC_H_
+#define _PPU_LIBSYNC_H_
+
+#include "sync_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long long atomic_ea_t;
+
+extern void atomic_set(atomic_ea_t v, int val);
+extern void atomic_add(int a, atomic_ea_t v);
+extern void atomic_sub(int a, atomic_ea_t v);
+extern void atomic_inc(atomic_ea_t v);
+extern void atomic_dec(atomic_ea_t v);
+
+extern int atomic_read(atomic_ea_t v);
+extern int atomic_add_return(int a, atomic_ea_t v);
+extern int atomic_sub_return(int a, atomic_ea_t v);
+extern int atomic_inc_return(atomic_ea_t v);
+extern int atomic_dec_return(atomic_ea_t v);
+extern int atomic_sub_and_test(int a, atomic_ea_t v);
+extern int atomic_dec_and_test(atomic_ea_t v);
+extern int atomic_dec_if_positive(atomic_ea_t v);
+
+typedef unsigned long long mutex_ea_t;
+void mutex_init(mutex_ea_t lock);
+
+void mutex_lock(mutex_ea_t lock);
+int mutex_trylock(mutex_ea_t ea);
+void mutex_unlock(mutex_ea_t lock);
+
+typedef struct
+{
+  int num_threads_signal;       /* the number of threads that are going to be waken up.
+                                 There are 3 values possible for this parameter, 0, 1, 
+                                 or num_threads_waiting*/
+  int num_threads_waiting;      /* the number of threads that are waiting to be awaken */ 
+} condition_variable_t __attribute__ ((aligned (16)));  
+
+typedef unsigned long long cond_ea_t;         /* a system memory 64 bit address that points to
+                                 * a valid condition_variable_t */
+
+typedef union {
+    unsigned long long ull;  
+    unsigned int ui[2];
+} val64;
+
+
+void cond_init (cond_ea_t  cond);
+void cond_signal (cond_ea_t cond);
+void cond_broadcast (cond_ea_t cond);
+void cond_wait (cond_ea_t cond, mutex_ea_t  mutex);
+
+
+#define MAX_THREADS_WAITING   32000 
+
+typedef unsigned long long completion_ea_t;
+
+extern void init_completion(completion_ea_t comp);
+extern void wait_for_completion(completion_ea_t comp);
+/*
+extern void wait_for_completion_irq(completion_ea_t comp);
+extern void wait_for_completion_irqsave(completion_ea_t comp);
+*/
+extern void complete_all(completion_ea_t comp);
+extern void complete (completion_ea_t comp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PPU_LIBSYNC_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/mutex.h b/gcell/src/ibm/sync/ppu_source/mutex.h
new file mode 100644 (file)
index 0000000..364bb22
--- /dev/null
@@ -0,0 +1,46 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_MUTEX_H_
+#define _PPU_MUTEX_H_           1
+
+typedef unsigned long long mutex_ea_t;
+
+#endif /* _PPU_MUTEX_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/mutex_init.h b/gcell/src/ibm/sync/ppu_source/mutex_init.h
new file mode 100644 (file)
index 0000000..105dc2c
--- /dev/null
@@ -0,0 +1,67 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_MUTEX_INIT_H_
+#define _PPU_MUTEX_INIT_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+/***************************************************************************/
+/**
+ * mutex_init - initialize the mutex by setting the value 
+ * to 0.
+ * @lock: handle to effective address of lock variable.
+ *
+ * Description: Initialize a mutex.
+ */
+static __inline void _mutex_init(mutex_ea_t lock)
+{
+  volatile unsigned int *p;
+
+  SYNC_ULL_TO_PTR(lock, p);
+
+  *p = 0;
+
+  TRACE_MUTEX_INIT(lock);
+}
+
+#endif /* _PPU_MUTEX_INIT_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/mutex_lock.h b/gcell/src/ibm/sync/ppu_source/mutex_lock.h
new file mode 100644 (file)
index 0000000..75240a1
--- /dev/null
@@ -0,0 +1,78 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_MUTEX_LOCK_H_
+#define _PPU_MUTEX_LOCK_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+/* function:   _mutex_lock
+ *
+ * Aquire a lock at a location in system memory by waiting for the
+ * value to become zero, then atomically storing 1. 
+ */
+static __inline void _mutex_lock (mutex_ea_t lock)
+{
+  unsigned int done = 0;
+  void *p;
+#ifdef LIBSYNC_TRACE
+  unsigned int miss = 0;
+#endif /* LIBSYNC_TRACE */
+
+  TRACE_MUTEX_LOCK_ENTRY(interval);
+
+  SYNC_ULL_TO_PTR(lock, p);
+
+  do {
+    if (__lwarx(p) == 0) done = __stwcx(p, (unsigned int) 1);
+#ifdef LIBSYNC_TRACE
+    /* if we missed the lock, note it.. */
+    if (done == 0) miss = 1;
+#endif
+  } while (done == 0);
+  __isync();
+
+  TRACE_MUTEX_LOCK_EXIT(interval, lock, miss);
+}
+
+#endif /* _PPU_MUTEX_LOCK_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/mutex_trylock.h b/gcell/src/ibm/sync/ppu_source/mutex_trylock.h
new file mode 100644 (file)
index 0000000..445196c
--- /dev/null
@@ -0,0 +1,81 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_MUTEX_TRYLOCK_H_
+#define _PPU_MUTEX_TRYLOCK_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+/**
+ * mutex_trylock - acquire a lock, or return immediately.
+ * @lock: handle to effective address of lock variable.
+ *
+ * Description: Acquire a lock, or return immediately 
+ * without polling for availability.
+ *
+ * Context: The application should not call this interface 
+ * from a tight loop!!  Use spin_lock() instead.
+ *
+ * Attempt to immediately aquire a lock at a location in system memory,
+ * and return 1 if the lock was aquired or 0 otherwise.
+ */
+static __inline int _mutex_trylock (mutex_ea_t lock)
+{
+  int val;
+  int ret = 0;
+  void *p;
+
+  SYNC_ULL_TO_PTR(lock, p);
+
+  do {
+    val = (int)__lwarx(p);
+    if (val) break;
+  } while ((ret = __stwcx(p, (unsigned int)1)) == 0);
+  __isync();
+
+  TRACE_MUTEX_TRYLOCK(lock,ret);
+
+  return (ret);
+}
+
+#endif /* _PPU_MUTEX_TRYLOCK_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/mutex_unlock.h b/gcell/src/ibm/sync/ppu_source/mutex_unlock.h
new file mode 100644 (file)
index 0000000..e5255be
--- /dev/null
@@ -0,0 +1,64 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_MUTEX_UNLOCK_H_
+#define _PPU_MUTEX_UNLOCK_H_
+
+#include "mutex.h"
+#include "atomic.h"
+#include "trace_libsync.h"
+
+/* function:   _mutex_unlock
+ *
+ * Release a lock held at address 'lock' in system memory.
+ * For the PU, this routine is the same _unlock, and is 
+ * provided here as a simple convenience for programmers 
+ * (to match the interfaces that are supported on the SPU).
+ * All I need to do is a store since store is an atomic operation by itself 
+ */
+static __inline void _mutex_unlock (mutex_ea_t lock)
+{
+  _atomic_replace ((atomic_ea_t)lock, 0);
+
+  TRACE_MUTEX_UNLOCK(lock); 
+}
+
+
+#endif /* _PPU_MUTEX_UNLOCK_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/pdt_libsync.xml b/gcell/src/ibm/sync/ppu_source/pdt_libsync.xml
new file mode 100644 (file)
index 0000000..d9ea2ce
--- /dev/null
@@ -0,0 +1,184 @@
+<pdtGroup name="LIBSYNC" id="0x03" version="3.0">
+       <!-- PPE events -->
+       <subGroup  name="PPE_MUTEX" id="0xFE03">
+               <recordType name="PPE_MUTEX_INIT" description="PPE: mutex lock init" id="0x0003" type="event">
+                       <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/>
+                       <physicalField name="lock"  description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="empty3"   description="empty slot 3" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>   
+               <recordType name="PPE_MUTEX_LOCK" description="PPE: acquire a mutex lock" id="0x0103"  type="interval">
+                       <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/>
+                       <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="miss"   description="Missed" type="int" toString="0x%x" visible="true"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>
+               <recordType name="PPE_MUTEX_TRYLOCK" description="PPE: try to acquire a lock" id="0x0203"  type="event">
+                       <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/>
+                       <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField  name="ret" description="Try lock return code" type="int" toString="0x%x" visible="true"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>   
+               <recordType name="PPE_MUTEX_UNLOCK" description="PPE: unlock a mutex lock" id="0x0303"  type="event">
+                       <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/>
+                       <physicalField  name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="empty3"   description="empty slot 3" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>
+       </subGroup>
+       <!-- SPE events -->
+       <subGroup  name="SPE_MUTEX" id="0xFD03">
+               <recordType name="SPE_MUTEX_INIT" description="SPE: mutex lock init" id="0x0403"  type="event">
+                       <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/>
+                       <physicalField  name="lock"  description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="empty3"   description="empty slot 3" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>   
+               <recordType name="SPE_MUTEX_LOCK" description="SPE: acquire a mutex lock" id="0x0503"  type="interval">
+                       <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/>
+                       <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="miss"   description="Missed" type="int" toString="0x%x" visible="true"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>
+               <recordType name="SPE_MUTEX_TRYLOCK" description="SPE: try to acquire a mutex lock" id="0x0603"  type="event">
+                       <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/>
+                       <physicalField  name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField  name="ret_val" description="Try lock return code" type="int" toString="0x%x" visible="true"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>   
+               <recordType name="SPE_MUTEX_UNLOCK" description="SPE: unlock a mutex lock" id="0x0703"  type="event">
+                       <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/>
+                       <physicalField  name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/>
+                       <physicalField name="empty3"   description="empty slot 3" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty4"   description="empty slot 4" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty5"   description="empty slot 5" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty6"   description="empty slot 6" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty7"   description="empty slot 7" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty8"   description="empty slot 8" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty9"   description="empty slot 9" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty10"   description="empty slot 10" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty11"   description="empty slot 11" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty12"   description="empty slot 12" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty13"   description="empty slot 13" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty14"   description="empty slot 14" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty15"   description="empty slot 15" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty16"   description="empty slot 16" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty17"   description="empty slot 17" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty18"   description="empty slot 18" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty19"   description="empty slot 19" type="int" toString="0x%x" visible="false"/>
+                       <physicalField name="empty20"   description="empty slot 20" type="int" toString="0x%x" visible="false"/>
+               </recordType>   
+       </subGroup>
+</pdtGroup>
diff --git a/gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml b/gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml
new file mode 100644 (file)
index 0000000..a0b848d
--- /dev/null
@@ -0,0 +1,61 @@
+<pdt_configuration application_name="libsync" output_dir="." version="3.0">
+       <groups>
+               <group name="GENERAL" description="General event types" id="0x00">
+                       <view yStart="0.0" yEnd="0.2" color="0x0000FF"/>
+                       <include href="/usr/share/pdt/config/pdt_general.xml"/>
+               </group>
+               <group name="LIBSPE2" description="CBE libspe 2.0 event types" id="0x01">
+                       <view yStart="0.2" yEnd="0.4" color="0x00FFFF"/>
+                       <include href="/usr/share/pdt/config/pdt_libspe2.xml"/>
+               </group>
+               <group name="MFCIO" description="SPE MFCIO event types" id="0x02">
+                       <view yStart="0.4" yEnd="0.6" color="0x00FF80"/>
+                       <include href="/usr/share/pdt/config/pdt_mfcio.xml"/>
+               </group>
+               <group name="LIBSYNC" description="General event types" id="0x03">
+                       <view yStart="0.6" yEnd="0.8" color="0xFFFF00"/>                        
+                       <include href="/usr/share/pdt/config/pdt_libsync.xml"/>
+               </group>
+       </groups>
+<configuration name="CBE">
+<host name="none"/>
+<groupsControl>
+       <group name="GENERAL" active="true">            
+               <profile active="false"/>
+               <!--  The GENERAL group of events are always active-->
+       </group> 
+       <group name="LIBSPE2" active="true">
+       </group>
+       <group name="LIBSYNC" active="true">                    
+               <sub_group name="PPE_MUTEX" active="true">
+                       <event name="PPE_MUTEX_INIT" active="true"/>
+                       <event name="PPE_MUTEX_LOCK" active="true"/>
+                       <event name="PPE_MUTEX_TRYLOCK" active="true"/>
+                       <event name="PPE_MUTEX_UNLOCK" active="true"/>
+               </sub_group>
+       </group>
+</groupsControl>
+</configuration>
+<!-- -->
+<!-- SPEs configuration - this section is read with the CBE configuration -->
+<!-- -->
+<configuration name="SPE">
+<host name="CBE"/>
+<groupsControl>
+       <group name="GENERAL" active="true">                    
+               <profile active="false"/>
+               <!--  The GENERAL group of events are always active-->
+       </group>
+       <group name="MFCIO" active="true">
+       </group>
+       <group name="LIBSYNC" active="true">                    
+               <sub_group name="SPE_MUTEX" active="true">
+                       <event name="SPE_MUTEX_INIT" active="true"/>
+                       <event name="SPE_MUTEX_LOCK" active="true"/>
+                       <event name="SPE_MUTEX_TRYLOCK" active="true"/>
+                       <event name="SPE_MUTEX_UNLOCK" active="true"/>
+               </sub_group>
+       </group>                        
+</groupsControl>
+</configuration>
+</pdt_configuration>
diff --git a/gcell/src/ibm/sync/ppu_source/sync_utils.h b/gcell/src/ibm/sync/ppu_source/sync_utils.h
new file mode 100644 (file)
index 0000000..c7120a3
--- /dev/null
@@ -0,0 +1,73 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _PPU_SYNC_UTILS_H_
+#define _PPU_SYNC_UTILS_H_      1
+
+/* SYNC_ULL_TO_PTR - convert a 64-bit unsigned long long to a void 
+ *                   pointer.
+ */
+#ifdef __powerpc64__
+
+#define SYNC_ULL_TO_PTR(_ull, _ptr) {          \
+  union {                                      \
+    void *ptr;                                 \
+    unsigned long long ull;                    \
+  } _x;                                                \
+                                               \
+  _x.ull = _ull;                               \
+  _ptr = _x.ptr;                               \
+}
+
+#else
+
+#define SYNC_ULL_TO_PTR(_ull, _ptr) {          \
+  union {                                      \
+    void *ptr[2];                              \
+    unsigned long long ull;                    \
+  } _x;                                                \
+                                               \
+  _x.ull = _ull;                               \
+  _ptr = _x.ptr[1];                            \
+}
+
+#endif
+
+#endif /* _PPU_SYNC_UTILS_H_ */
diff --git a/gcell/src/ibm/sync/ppu_source/trace_libsync.h b/gcell/src/ibm/sync/ppu_source/trace_libsync.h
new file mode 100644 (file)
index 0000000..6d6f036
--- /dev/null
@@ -0,0 +1,117 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2007                                               */
+/* International Business Machines Corporation                     */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef __LIBSYNC_PPU_TRACEHOOKS_H__
+#define __LIBSYNC_PPU_TRACEHOOKS_H__
+
+#ifdef LIBSYNC_TRACE
+
+#include <trace_events.h>
+
+/*
+ *  last parameter in the trace_even and trace_interval_entry call is
+ *   the stack level to report the PC in the trace record. so 0 means
+ *   the PC of the current frame, 1 means the PC of the caller, etc.
+ *   there's a dilemma here - these macros are included in the inline
+ *   _mutex calls which get called from the (created during build)
+ *   mutex functions in the mutex .c files. in that case, the level
+ *   should be 1 - we don't want the PC of where in the mutex function
+ *   the trace call is happening, we want the PC of whomever is calling
+ *   the mutex function.
+ *
+ *   but.. an app can call the inline functions - it can #include the
+ *   appropriate libsync mutex .h files, and call the inlined _mutex
+ *   function in their code. in that case, the appropriate level for the
+ *   trace calls would be 0 - the user would want to know where in their
+ *   code the call to the _mutex function is.
+ *
+ *   so, we'll assume _LEVEL of 0 which is what the inline funtions need.
+ *   when we build the files for libsync, we'll do a -D_LEVEL=1 
+ */
+#ifndef _LEVEL
+#define _LEVEL 0
+#endif
+
+
+#define TRACE_EVENT_MUTEX_INIT 0x0003
+
+#define TRACE_MUTEX_INIT(lock) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(uint64_t)lock; \
+  trace_event(TRACE_EVENT_MUTEX_INIT, 1, &payload, "Event=%d, lock=0x%x",_LEVEL); \
+}
+
+#define TRACE_EVENT_MUTEX_LOCK 0x0103
+
+#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) \
+trace_interval_p _INTERVAL = trace_interval_entry(TRACE_EVENT_MUTEX_LOCK, _LEVEL)
+
+#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(uint64_t)lock; \
+  payload.word[2]=(uint32_t)miss; \
+  trace_interval_exit(_INTERVAL, 2,  &payload, "Event=%d, lock=0x%x, miss=0x%x"); \
+}
+
+#define TRACE_EVENT_MUTEX_TRYLOCK 0x0203
+
+#define TRACE_MUTEX_TRYLOCK(lock,ret) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(uint64_t)lock; \
+  payload.word[2]=(uint32_t)ret; \
+  trace_event(TRACE_EVENT_MUTEX_TRYLOCK, 2, &payload, "Event=%d, lock=0x%x, ret=0x%x", _LEVEL); \
+}
+
+#define TRACE_EVENT_MUTEX_UNLOCK 0x0303
+
+#define TRACE_MUTEX_UNLOCK(lock) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(uint64_t)lock; \
+  trace_event(TRACE_EVENT_MUTEX_UNLOCK, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \
+}
+
+#else /* LIBSYNC_TRACE */
+
+#define TRACE_MUTEX_INIT(lock)
+#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL)
+#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss)
+#define TRACE_MUTEX_TRYLOCK(lock,ret_val)
+#define TRACE_MUTEX_UNLOCK(lock)
+
+#endif /* LIBSYNC_TRACE */
+
+#endif  /* __LIBSYNC_PPU_TRACEHOOKS_H__ */
diff --git a/gcell/src/ibm/sync/ppu_source/wait_for_completion.h b/gcell/src/ibm/sync/ppu_source/wait_for_completion.h
new file mode 100644 (file)
index 0000000..f2b0427
--- /dev/null
@@ -0,0 +1,75 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+
+#ifndef _PPU_WAIT_FOR_COMPLETION_H_
+#define _PPU_WAIT_FOR_COMPLETION_H_
+
+#include <ppu_intrinsics.h>
+#include "sync_utils.h"
+#include "completion.h"
+
+
+/**
+ * completion_wait - wait until a completion is broadcast.
+ * @comp: handle to effective address of completion variable.
+ *
+ * Description: Wait until another processor or device signals
+ * that a completionition is 'true'.  The only restriction here is 
+ * that @comp must be a word aligned address.
+ *
+ * Beware: This function hot polls waiting for completion.
+ */
+static __inline void _wait_for_completion(completion_ea_t comp)
+{
+  int val;
+  void *p;
+
+  SYNC_ULL_TO_PTR(comp, p);
+
+  do {
+    val = (int)__lwarx(p);
+    if (val != 1) val = (int)__stwcx(p, (unsigned int)0);
+  } while (val == 0);
+  __isync();
+}
+
+
+#endif /* _PPU_WAIT_FOR_COMPLETION_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic.h b/gcell/src/ibm/sync/spu_source/atomic.h
new file mode 100644 (file)
index 0000000..951c26e
--- /dev/null
@@ -0,0 +1,101 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+/*
+ * atomic.h - SPU atomic SHM counter operations.
+ *
+ * Interfaces patterned after, and hopefully compatible
+ * with PowerPC64-Linux atomic counter operations.  Uses
+ * 32b values for various counters.
+ */
+#ifndef _SPU_ATOMIC_H_
+#define _SPU_ATOMIC_H_
+
+#include <sync_utils.h>
+#include <spu_mfcio.h>
+
+
+/* atomic_eaddr_t is a 64bit effective address 
+ * that points to an atomic_t variable */
+typedef unsigned long long atomic_ea_t;
+
+#define DECL_ATOMIC_VARS()                              \
+    char _tmp[256];                                    \
+    char *tmp = (char *) ALIGN(_tmp, 128);             \
+    volatile s32 *buf = (volatile s32 *) &tmp[0];       \
+    u32 size = 128, tagid = 0;                          \
+    s32 ret_val;                                       \
+    u32 offset;                                         \
+    addr64 ea64
+
+/* __atomic_op                                              
+*    Internal routine to acquire lock line reservation
+*    then conditionally modify the counter variable 
+*    pointed to by 'v'.  The 'replace' flag indicates 
+*    whether or not this is to be an arithmetic R-M-W
+*    or a simple replace operation.
+*/
+#define ATOMIC_OP(__v, __val, __replace, __final_val)           \
+{                                                               \
+    char __tmp[256];                                            \
+    char *_tmp = (char *) ALIGN(__tmp, 128);                   \
+    volatile s32 *_buf = (volatile s32 *) &_tmp[0];             \
+    u32 _size = 128, _tagid = 0;                                \
+    s32 _status, _ret_val;                                      \
+    u32 _offset;                                                \
+    addr64 _ea64;                                               \
+                                                                \
+    _ea64.ull = ALIGN128_EA(__v);                               \
+    _offset = OFFSET128_EA_U32(__v);                            \
+    do {                                                        \
+       MFC_DMA(_buf, _ea64, _size, _tagid, MFC_GETLLAR_CMD);   \
+        spu_readch (MFC_RdAtomicStat);                          \
+                                                                \
+       _ret_val = _buf[_offset];                                \
+       _buf[_offset] = (__replace) ? __val : _ret_val + __val;    \
+       MFC_DMA(_buf, _ea64, _size, _tagid, MFC_PUTLLC_CMD);    \
+       _status = spu_readch(MFC_RdAtomicStat);                  \
+    } while (_status != 0);                                     \
+                                                                \
+    __final_val = _ret_val;                                     \
+}                                                               
+
+#endif /* _SPU_ATOMIC_H_ */
+
diff --git a/gcell/src/ibm/sync/spu_source/atomic_add.h b/gcell/src/ibm/sync/spu_source/atomic_add.h
new file mode 100644 (file)
index 0000000..7606ae0
--- /dev/null
@@ -0,0 +1,62 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_ADD_H_
+#define _SPU_ATOMIC_ADD_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_add - atomically add to a counter.
+ * @v: handle to effective address of counter.
+ * @a: value to be added.
+ * 
+ * Atomically add a value to a counter in system memory. 
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_add(int a, atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP (v, a, 0, ret_val);
+}
+
+
+#endif /* _SPU_ATOMIC_ADD_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_add_return.h b/gcell/src/ibm/sync/spu_source/atomic_add_return.h
new file mode 100644 (file)
index 0000000..35f07ad
--- /dev/null
@@ -0,0 +1,69 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_ADD_RETURN_H_
+#define _SPU_ATOMIC_ADD_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+/**
+ * atomic_add_return - atomically add to a counter and return previous value.
+ * @v: handle to effective address of counter.
+ * @a: value to be added.
+ *
+ * Atomically add a value to a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and add" primitive
+ * that is described in "Book I PowerPC User Instruction
+ * Set Architecture", but uses MFC lock line reservation
+ * operations instead of lwarx/stwcx.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_add_return(int a, atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, a, 0, ret_val);
+    return ret_val;
+}
+
+
+#endif /* _SPU_ATOMIC_ADD_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec.h b/gcell/src/ibm/sync/spu_source/atomic_dec.h
new file mode 100644 (file)
index 0000000..30ca7c5
--- /dev/null
@@ -0,0 +1,61 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_DEC_H_
+#define _SPU_ATOMIC_DEC_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_dec - atomically decrement a counter.
+ * @v: handle to effective address of location to be modified.
+ *
+ * Atomically decrement a counter in system memory. The only
+ * restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_dec(atomic_ea_t v)
+{    
+    int ret_val;
+    ATOMIC_OP (v, -1, 0, ret_val);
+}
+
+
+#endif /* _SPU_ATOMIC_DEC_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h b/gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h
new file mode 100644 (file)
index 0000000..b3c8298
--- /dev/null
@@ -0,0 +1,64 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_DEC_AND_TEST_H_
+#define _SPU_ATOMIC_DEC_AND_TEST_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_dec_and_test - atomically decrement and test if previous==0.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically decrement a counter in system memory and test 
+ * if previous==0.  The only restriction is that @v must be 
+ * word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_dec_and_test(atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, -1, 0, ret_val);
+    return (ret_val == 0) ? 1 : 0;
+}
+
+#endif /* _SPU_ATOMIC_DEC_AND_TEST_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h b/gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h
new file mode 100644 (file)
index 0000000..2a01ec3
--- /dev/null
@@ -0,0 +1,86 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_DEC_IF_POSITIVE_H_
+#define _SPU_ATOMIC_DEC_IF_POSITIVE_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_dec_if_positive - atomically decrement if counter is positive.
+ * @v: handle to effective address of counter.
+ * 
+ * Atomically decrement a counter if its value is positive.
+ * The only restriction is that @v must be word aligned.
+ *
+*
+ * Returns the old value of the counter, minus 1.
+ */
+static __inline int _atomic_dec_if_positive(atomic_ea_t v)
+{
+    DECL_ATOMIC_VARS();
+    s32 status;
+
+    ea64.ull = ALIGN128_EA(v);
+    offset = OFFSET128_EA_U32(v);
+    do {
+       MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+       spu_readch(MFC_RdAtomicStat);
+
+       ret_val = buf[offset] - 1;
+       if (likely(ret_val >= 0)) {
+           buf[offset] = ret_val;
+           MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+           status = spu_readch(MFC_RdAtomicStat);
+       } else {
+           MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+           spu_readch(MFC_RdAtomicStat);
+           status = 0;
+           break;
+       }
+    } while (status != 0);
+
+    return ret_val;
+}
+
+
+
+#endif /* _SPU_ATOMIC_DEC_IF_POSITIVE_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_return.h b/gcell/src/ibm/sync/spu_source/atomic_dec_return.h
new file mode 100644 (file)
index 0000000..45effb6
--- /dev/null
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_DEC_RETURN_H_
+#define _SPU_ATOMIC_DEC_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_dec_return - atomically decrement a counter and return previous value.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically decrement a counter in system memory and return its
+ * previous value. The only restriction is that @v must be word 
+ * aligned.
+ *
+ * This routine implements the "fetch and decrement"
+ * primitive that is described in "Book I PowerPC User
+ * Instruction Set Architecture", but uses MFC lock line
+ * reservation operations instead of lwarx/stwcx.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_dec_return(atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, -1, 0, ret_val);
+    return ret_val;
+}
+
+
+#endif /* _SPU_ATOMIC_DEC_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_inc.h b/gcell/src/ibm/sync/spu_source/atomic_inc.h
new file mode 100644 (file)
index 0000000..6800efe
--- /dev/null
@@ -0,0 +1,61 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_INC_H_
+#define _SPU_ATOMIC_INC_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_inc - atomically increment a counter in system memory.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically increment a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_inc(atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP (v, 1, 0, ret_val);
+}
+
+
+#endif /* _SPU_ATOMIC_INC_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_inc_return.h b/gcell/src/ibm/sync/spu_source/atomic_inc_return.h
new file mode 100644 (file)
index 0000000..89361a0
--- /dev/null
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_INC_RETURN_H_
+#define _SPU_ATOMIC_INC_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+
+/**
+ * atomic_inc_return - atomically increment a counter and return previous.
+ * @v: handle to effective address of counter.
+ *
+ * Atomically increment a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and increment"
+ * primitive that is described in "Book I PowerPC User
+ * Instruction Set Architecture", but uses MFC lock line
+ * reservation operations instead of lwarx/stwcx.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_inc_return(atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, 1, 0, ret_val);
+    return ret_val;
+}
+
+
+#endif /* _SPU_ATOMIC_INC_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_read.h b/gcell/src/ibm/sync/spu_source/atomic_read.h
new file mode 100644 (file)
index 0000000..711a0ad
--- /dev/null
@@ -0,0 +1,78 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_READ_H_
+#define _SPU_ATOMIC_READ_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_read - read an atomic counter.
+ * @v: handle to effective address of counter.
+ *
+ * Read the current value of an atomic counter.
+ */
+static __inline int _atomic_read(atomic_ea_t v)
+{
+    DECL_ATOMIC_VARS();
+
+    /* reserve a tag for use */
+    tagid = mfc_tag_reserve();
+
+    u32 oldtmask, tagmask = 1 << (tagid & 31);
+
+    ea64.ull = ALIGN128_EA(v);
+    offset = OFFSET128_EA_U32(v);
+
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD);
+    oldtmask = spu_readch(MFC_RdTagMask);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+    spu_writech(MFC_WrTagMask, oldtmask);
+
+    mfc_tag_release (tagid);
+    ret_val =  buf[offset];
+    return ret_val;
+}
+
+
+#endif /* _SPU_ATOMIC_READ_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_set.h b/gcell/src/ibm/sync/spu_source/atomic_set.h
new file mode 100644 (file)
index 0000000..261d28a
--- /dev/null
@@ -0,0 +1,68 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_SET_H_
+#define _SPU_ATOMIC_SET_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_set - atomically set a counter in system memory.
+ * @v: handle to effective address of counter.
+ * 
+ * Atomically set a counter to a given value. The only 
+ * restriction is that @v must be word aligned.
+ *
+ * This routine implements the "fetch and store" 
+ * primitive that is described in "Book I PowerPC User 
+ * Instruction Set Architecture", but uses MFC lock line
+ * reservation operations instead of lwarx/stwcx. 
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline void _atomic_set(atomic_ea_t v, int val)
+{
+    int ret_val;
+    ATOMIC_OP(v, val, 1, ret_val);
+}
+
+
+#endif /* _SPU_ATOMIC_SET_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub.h b/gcell/src/ibm/sync/spu_source/atomic_sub.h
new file mode 100644 (file)
index 0000000..f366e1d
--- /dev/null
@@ -0,0 +1,64 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_SUB_H_
+#define _SPU_ATOMIC_SUB_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_sub - atomically subtract from a counter.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ */
+static __inline void _atomic_sub(int a, atomic_ea_t v)
+{
+    int ret_val;
+
+    ATOMIC_OP (v, -a, 0, ret_val);
+}
+
+
+
+#endif /* _SPU_ATOMIC_SUB_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h b/gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h
new file mode 100644 (file)
index 0000000..fe5824a
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_SUB_AND_TEST_H_
+#define _SPU_ATOMIC_SUB_AND_TEST_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+/**
+ * atomic_sub_and_test - atomically subtract and test if previous==0.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory
+ * and test if previous==0.  The only restriction is that @v 
+ * must be word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_sub_and_test(int a, atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, -a, 0, ret_val);
+    return (ret_val == 0) ? 1 : 0;
+}
+
+
+#endif /* _SPU_ATOMIC_SUB_AND_TEST_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub_return.h b/gcell/src/ibm/sync/spu_source/atomic_sub_return.h
new file mode 100644 (file)
index 0000000..5dbed5b
--- /dev/null
@@ -0,0 +1,69 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_ATOMIC_SUB_RETURN_H_
+#define _SPU_ATOMIC_SUB_RETURN_H_
+
+#include <sync_utils.h>
+#include <atomic.h>
+
+
+/**
+ * atomic_sub_return - atomically subtract from a counter & return previous.
+ * @v: handle to effective address of counter.
+ * @a: value to be subtracted.
+ *
+ * Atomically subtract a value from a counter in system memory.
+ * The only restriction is that @v must be word aligned.
+ *
+ * Returns the previous value from system memory.
+ */
+static __inline int _atomic_sub_return(int a, atomic_ea_t v)
+{
+    int ret_val;
+    ATOMIC_OP(v, -a, 0, ret_val);
+    return ret_val;
+    //return __atomic_op(v, -a, 0);
+}
+
+
+
+
+#endif /* _SPU_ATOMIC_SUB_RETURN_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/complete.h b/gcell/src/ibm/sync/spu_source/complete.h
new file mode 100644 (file)
index 0000000..6a78086
--- /dev/null
@@ -0,0 +1,67 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COMPLETE_H_
+#define _SPU_COMPLETE_H_
+
+#include "sync_utils.h"
+#include <spu_mfcio.h>
+#include "completion.h"
+
+static __inline void _complete(completion_ea_t completion)
+{
+    DECL_COMPLETION_VARS();
+
+    ea64.ull = ALIGN128_EA(completion);
+    offset = OFFSET128_EA_U32(completion);
+    MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+    spu_readch(MFC_RdAtomicStat);
+
+    /* set the completionition variable to exactly one so
+     * only one thread can be awaken */
+    buf[offset] = 1;
+    MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD);
+    spu_readch(MFC_RdAtomicStat);
+}
+
+
+
+
+#endif /* _SPU_COMPLETE_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/complete_all.h b/gcell/src/ibm/sync/spu_source/complete_all.h
new file mode 100644 (file)
index 0000000..5f9c3dc
--- /dev/null
@@ -0,0 +1,74 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COMPLETE_ALL_H_
+#define _SPU_COMPLETE_ALL_H_
+
+#include "sync_utils.h"
+#include <spu_mfcio.h>
+#include "completion.h"
+
+/**
+ * completion_broadcast - indicate that a completion is true.
+ * @completion: handle to effective address of completion variable.
+ *
+ * Indicate that a completionition is true by storing '1' to the
+ * completionition variable.
+ */
+static __inline void _complete_all(completion_ea_t completion)
+{
+    DECL_COMPLETION_VARS();
+
+    ea64.ull = ALIGN128_EA(completion);
+    offset = OFFSET128_EA_U32(completion);
+    MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+    spu_readch(MFC_RdAtomicStat);
+
+    /* set the completionition variable to the count. So that
+     * all the threads  */
+    buf[offset] = MAX_THREADS_WAITING;
+    MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD);
+    spu_readch(MFC_RdAtomicStat);
+}
+
+
+
+
+#endif /* _SPU_COMPLETE_ALL_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/completion.h b/gcell/src/ibm/sync/spu_source/completion.h
new file mode 100644 (file)
index 0000000..4a302d2
--- /dev/null
@@ -0,0 +1,68 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+/*
+ * cond.h - simple condition wait & broadcast operations.
+ *
+ * Interrupt aware versions of the routines are supported.
+ * Applications should call either '_irq' or '_irqsave'
+ * forms of the functions when interrupts are enabled.
+ */
+
+#ifndef __SPU_COMPLETION_H__
+#define __SPU_COMPLETION_H__
+
+#include "sync_utils.h"
+
+#define MAX_THREADS_WAITING   32000 
+typedef unsigned long long completion_ea_t;
+
+
+#define DECL_COMPLETION_VARS()                                \
+    char _tmp[256];                                     \
+    char *tmp = (char *) ALIGN(_tmp, 128);              \
+    volatile s32 *buf = (volatile s32 *) &tmp[0];       \
+    u32 size = 128, tagid = 0;                          \
+    u32 offset;                                         \
+    addr64 ea64
+
+
+
+#endif /* __SPU_COMPLETION_H__ */
diff --git a/gcell/src/ibm/sync/spu_source/cond.h b/gcell/src/ibm/sync/spu_source/cond.h
new file mode 100644 (file)
index 0000000..ceb3285
--- /dev/null
@@ -0,0 +1,69 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COND_VAR_H_
+#define _SPU_COND_VAR_H_
+
+#include "sync_utils.h"
+typedef struct
+{
+  int num_threads_signal;       /* the number of threads that are going to be waken up.
+                                 There are 3 values possible for this parameter, 0, 1, 
+                                 or num_threads_waiting*/
+  int num_threads_waiting;      /* the number of threads that are waiting to be awaken */ 
+} condition_variable_t __attribute__ ((aligned (128)));  
+
+typedef eaddr_t cond_ea_t;         /* a system memory 64 bit address that points to
+                                 * a valid condition_variable_t */
+
+
+
+
+#define DECL_COND_VARS()                                \
+    char _tmp[256];                                     \
+    char *tmp = (char *) ALIGN(_tmp, 128);              \
+    volatile s32 *buf = (volatile s32 *) &tmp[0];       \
+    u32 size = 128, tagid = 0;                          \
+    s32 status, ret_val;                                \
+    u32 offset;                                         \
+    addr64 ea64;                                        \
+    condition_variable_t cond_var
+
+#endif /* _SPU_COND_VAR_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/cond_broadcast.h b/gcell/src/ibm/sync/spu_source/cond_broadcast.h
new file mode 100644 (file)
index 0000000..15a1da3
--- /dev/null
@@ -0,0 +1,73 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COND_BROADCAST_H_
+#define _SPU_COND_BROADCAST_H_
+
+#include "sync_utils.h"
+#include "cond.h"
+#include <spu_mfcio.h>
+
+/**
+ * cond_broadcast - indicate that a condition is true.
+ * @cond: handle to effective address of condition variable.
+ */
+static __inline void _cond_broadcast(cond_ea_t cond)
+{
+    char _tmp[256];                                     
+    char *tmp = (char *) ALIGN(_tmp, 128);              
+    volatile unsigned short *buf = (volatile unsigned short *) &tmp[0];       
+    unsigned int size = 128, tagid = 0;                          
+    u32 offset;                                         
+    addr64 ea64;          
+
+    ea64.ull = ALIGN128_EA(cond);
+    offset = OFFSET128_EA_U16(cond);
+    MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+    spu_readch(MFC_RdAtomicStat);
+
+    /* set the condition variable to the count. So that
+     * all the threads  */
+    buf[offset] = buf[offset + 1];
+    MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD);
+    spu_readch(MFC_RdAtomicStat);
+}
+
+#endif /* _SPU_COND_BROADCAST_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/cond_init.h b/gcell/src/ibm/sync/spu_source/cond_init.h
new file mode 100644 (file)
index 0000000..7202e53
--- /dev/null
@@ -0,0 +1,127 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COND_INIT_H_
+#define _SPU_COND_INIT_H_
+
+#include "sync_utils.h"
+#include "cond.h"
+#include <spu_mfcio.h>
+
+
+/**
+ * cond_init - initialize condition variable.
+ * @cond: handle to effective address of condition variable.
+ *
+ *
+ * Conditional Variable - is a synchronization device that allows 
+ * SPE and PPE threads to suspend execution and relinquish the 
+ * processors until some predicate on shared data is satisfied. 
+ * The basic operations on conditions are: signal the condition
+ * (when the predicate becomes true), and wait for the condition,
+ * suspending the thread execution until anoter thread signals the
+ * condition
+ *
+ * A condition variable must always be associated with a mutex, to
+ * avoid the race condition where a thread prepares to wait on a 
+ * condition variable and another thread signals the condition just
+ * before the first thread actually waits on it.
+ *
+ * cond_init initializes the condition variable cond. 
+ *
+ * cond_signal restarts one of the threads that are waiting on the
+ * condition variable cond. If no threads are waiting on cond, nothing
+ * happens. If several threads are waiting on cond, exactly one
+ * is restarted, but it is not specified which
+ *
+ * cond_broadcast restarts all the threads that are waiting on the 
+ * condition variable cond. Nothing happens if no threads are waiting
+ * on cond
+ *
+ * cond_wait atomically unlocks the mutex and waits for the condition
+ * variable cond to be signaled. The mutex must be lock locked by 
+ * the calling thread on the entrance to cond_wait. Before returning
+ * to the calling thread, cond_wait re-acquires mutex. 
+ *
+ * Only one thread initializes a condition variable. Usually, the 
+ * PPE thread initializes a condidtion variable, however, a cond_init
+ * function is provided here for completeness
+ *
+ * Description: Initialize a cond variable to false.
+ */
+static __inline void _cond_init(cond_ea_t cond )
+{
+    char _tmp[256];                                     
+    char *tmp = (char *) ALIGN(_tmp, 128);              
+    volatile unsigned short *buf = (volatile unsigned short *) &tmp[0];       
+    unsigned int size = 128, tagid;                          
+    unsigned int offset;           
+    addr64 ea64;
+    unsigned int oldtmask;
+    unsigned int tagmask;    
+
+    tagid = mfc_tag_reserve(); 
+
+    tagmask = 1 << (tagid & 31);
+
+    ea64.ull = ALIGN128_EA(cond);
+    offset = OFFSET128_EA_U16(cond);
+
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD);
+    oldtmask = spu_readch(MFC_RdTagMask);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+
+    /* this is still just one word. since buf is of type
+     * short, we fit both counts into one word. */
+    buf[offset] = 0;
+    buf[offset+1] = 0;
+    MFC_DMA(buf, ea64, size, (tagid & 31), MFC_PUT_CMD);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+    spu_writech(MFC_WrTagMask, oldtmask);
+    mfc_tag_release (tagid);
+}
+
+
+
+#endif /* _SPU_COND_INIT_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/cond_signal.h b/gcell/src/ibm/sync/spu_source/cond_signal.h
new file mode 100644 (file)
index 0000000..a035d28
--- /dev/null
@@ -0,0 +1,88 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COND_SIGNAL_H_
+#define _SPU_COND_SIGNAL_H_
+#include <stdio.h>
+#include "sync_utils.h"
+#include "cond.h"
+#include "atomic.h"
+#include <spu_mfcio.h>
+
+/*
+ * _cond_signal: signalling any of the waiting threads to wake up.
+ */ 
+static __inline void _cond_signal(cond_ea_t cond)
+{
+    char _tmp[256];                                     
+    char *tmp = (char *) ALIGN(_tmp, 128);              
+    volatile unsigned short *buf = (volatile unsigned short *) &tmp[0];       
+    unsigned int size = 128, tagid = 0;                          
+    u32 offset;                                         
+    addr64 ea64;                                      
+    int status;
+
+    ea64.ull = ALIGN128_EA(cond);
+    offset = OFFSET128_EA_U16(cond);
+
+    do {
+      MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+      (void)spu_readch(MFC_RdAtomicStat);
+
+      /* Check for waiting threads.
+       */
+      if (buf[offset] != buf[offset+1]) {
+       /* Increment the signaled count to release the next waiting
+        * thread.
+        */
+       buf[offset]++;
+
+       MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+       status = spu_readch(MFC_RdAtomicStat);
+      } else {
+       /* Nobody is waiting, do nothing.
+        */
+       status = 0;
+      }
+    } while (status);
+}
+
+
+#endif /* _SPU_COND_SIGNAL_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/cond_wait.h b/gcell/src/ibm/sync/spu_source/cond_wait.h
new file mode 100644 (file)
index 0000000..cf4b880
--- /dev/null
@@ -0,0 +1,103 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_COND_WAIT_H_
+#define _SPU_COND_WAIT_H_
+#include <stdio.h>
+#include "sync_irq.h"
+#include "sync_utils.h"
+#include "mutex_lock.h"
+#include "mutex_unlock.h"
+#include "cond.h"
+#include <spu_mfcio.h>
+
+static __inline void _cond_wait (cond_ea_t cond, mutex_ea_t  mutex)
+{
+    char _tmp[256];                                     
+    char *tmp = (char *) ALIGN(_tmp, 128);              
+    volatile signed short *buf = (volatile signed short *) &tmp[0];       
+    unsigned int size = 128, tagid = 0;                          
+    int status;                                
+    unsigned int offset;                                         
+    addr64 ea64;  
+    signed short delta, cur_delta, signaled_cnt;
+
+    ea64.ull = ALIGN128_EA(cond);
+    offset = OFFSET128_EA_U16(cond);
+
+    /* increment the waiting halfword of the condition variable.
+     */
+    do {
+      MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+      (void)spu_readch(MFC_RdAtomicStat);
+
+      buf[offset+1]++;
+      
+      MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+      status = spu_readch(MFC_RdAtomicStat); 
+    } while (status);
+
+    _mutex_unlock(mutex);
+
+    /* keep track of the change in count needed to be signaled. This 
+     * is delta.
+     */
+    signaled_cnt = buf[offset];
+    delta = buf[offset+1] - signaled_cnt;
+    if (delta < 0) delta = -delta;
+
+    while (1) {
+      MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+      (void)spu_readch(MFC_RdAtomicStat);
+
+      cur_delta = buf[offset] - signaled_cnt;
+      if (cur_delta < 0) cur_delta = -cur_delta;
+
+
+      if (cur_delta >= delta) {
+       /* the counts indicate that this thread has been signaled.
+        */
+       break;
+      } 
+    } 
+    _mutex_lock (mutex);
+}
+
+#endif /* _SPU_COND_WAIT_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/init_completion.h b/gcell/src/ibm/sync/spu_source/init_completion.h
new file mode 100644 (file)
index 0000000..bf93e72
--- /dev/null
@@ -0,0 +1,82 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_INIT_COMPLETION_H_
+#define _SPU_INIT_COMPLETION_H_
+
+#include "sync_utils.h"
+#include <spu_mfcio.h>
+#include "completion.h"
+
+/**
+ * completion_init - initialize completion variable.
+ * @completion: handle to effective address of completion variable.
+ *
+ * Description: Initialize a completion variable to false.
+ */
+static __inline void _init_completion(completion_ea_t completion)
+{
+    DECL_COMPLETION_VARS();
+    u32 oldtmask, tagmask;
+   
+    tagid = mfc_tag_reserve();
+    tagmask = 1 << (tagid & 31);
+
+    ea64.ull = ALIGN128_EA(completion);
+    offset = OFFSET128_EA_U32(completion);
+
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD);
+    oldtmask = spu_readch(MFC_RdTagMask);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+
+    buf[offset] = 0;
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_PUT_CMD);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+    spu_writech(MFC_WrTagMask, oldtmask);
+    mfc_tag_release(tagid);
+}
+
+
+
+#endif /* _SPU_INIT_COMPLETION_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/libsync.h b/gcell/src/ibm/sync/spu_source/libsync.h
new file mode 100644 (file)
index 0000000..48cc722
--- /dev/null
@@ -0,0 +1,116 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_LIB_SYNC_H_
+#define _SPU_LIB_SYNC_H_
+#include "sync_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned long long atomic_ea_t;
+
+extern void atomic_set(atomic_ea_t v, int val);
+extern void atomic_add(int a, atomic_ea_t v);
+extern void atomic_sub(int a, atomic_ea_t v);
+extern void atomic_inc(atomic_ea_t v);
+extern void atomic_dec(atomic_ea_t v);
+
+extern int atomic_read(atomic_ea_t v);
+extern int atomic_add_return(int a, atomic_ea_t v);
+extern int atomic_sub_return(int a, atomic_ea_t v);
+extern int atomic_inc_return(atomic_ea_t v);
+extern int atomic_dec_return(atomic_ea_t v);
+extern int atomic_sub_and_test(int a, atomic_ea_t v);
+extern int atomic_dec_and_test(atomic_ea_t v);
+extern int atomic_dec_if_positive(atomic_ea_t v);
+
+typedef unsigned long long mutex_ea_t;
+
+extern void mutex_init(mutex_ea_t lock);
+extern void mutex_lock(mutex_ea_t lock);
+extern int mutex_trylock(mutex_ea_t ea);
+extern void mutex_unlock(mutex_ea_t lock);
+
+
+typedef struct
+{
+  int num_threads_signal;       /* the number of threads that are going to be waken up.
+                                * There are 3 values possible for this parameter, 0, 1, 
+                                 * or num_threads_waiting
+                                */
+  int num_threads_waiting;      /* the number of threads that are waiting to be awaken 
+                                */ 
+} condition_variable_t __attribute__ ((aligned (128)));  
+
+typedef eaddr_t cond_ea_t;     /* a system memory 64 bit address that points to
+                                * a valid condition_variable_t 
+                                */
+
+
+extern void cond_init (cond_ea_t  cond);
+extern void cond_signal (cond_ea_t cond);
+extern void cond_broadcast (cond_ea_t cond);
+extern void cond_wait (cond_ea_t cond, mutex_ea_t  mutex);
+
+typedef unsigned long long completion_ea_t;
+
+extern void init_completion(completion_ea_t completion);
+extern void wait_for_completion(completion_ea_t completion);
+extern void complete(completion_ea_t completion);
+extern void complete_all(completion_ea_t completion);
+
+#ifdef __SPU__
+  /* Function only implemented for the SPU
+   */
+  extern void read_lock(eaddr_t ea);
+  extern void read_unlock(eaddr_t ea);
+  extern int  read_trylock(eaddr_t ea);
+  extern void write_lock(eaddr_t ea);
+  extern void write_unlock(eaddr_t ea);
+  extern int  write_trylock(eaddr_t ea);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SPU_LIB_SYNC_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/mutex.h b/gcell/src/ibm/sync/spu_source/mutex.h
new file mode 100644 (file)
index 0000000..37f2b4d
--- /dev/null
@@ -0,0 +1,178 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_MUTEX_H_
+#define _SPU_MUTEX_H_           1
+
+#include "sync_utils.h"
+#include "sync_irq.h"
+#include <spu_mfcio.h>
+
+typedef eaddr_t mutex_ea_t;
+
+#define DECL_MUTEX_VARS()                               \
+    char _tmp[256];                                     \
+    char *tmp = (char *) ALIGN(_tmp, 128);              \
+    volatile s32 *buf = (volatile s32 *) &tmp[0];       \
+    u32 size = 128, tagid = 0;                          \
+    u32 offset;                                         \
+    addr64 ea64
+
+/* RAW_TEST_AND_SET
+ *    Macro implementing the test and set primitive.
+ *
+ *    RAW_TEST_AND_SET(==, 1)  used by spin_try_lock()
+ *    RAW_TEST_AND_SET(>=, 1)  used by read_try_lock()
+ *    RAW_TEST_AND_SET(==, -1) used by write_try_lock()
+ */
+#define RAW_TEST_AND_SET(_RELOP_, _val)                                \
+    ea64.ull = ALIGN128_EA(ea);                                        \
+    offset = OFFSET128_EA_U32(ea);                             \
+    do {                                                       \
+        MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);      \
+        spu_readch(MFC_RdAtomicStat);                          \
+        SET_HIT;                                               \
+        if (likely(buf[offset] _RELOP_ 0)) {                   \
+            buf[offset] += _val;                               \
+           MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);    \
+            status = spu_readch(MFC_RdAtomicStat);             \
+            ret_val = 1;                                       \
+        } else {                                               \
+           MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);    \
+            spu_readch(MFC_RdAtomicStat);                      \
+            status = ret_val = 0;                              \
+            break;                                             \
+        }                                                      \
+    } while (status != 0)
+
+/* RAW_SPINLOCK
+ *    Macro implementing the spinlock primitive.
+ *
+ *    RAW_SPINLOCK(==, 1)      used by spin_lock()
+ *    RAW_SPINLOCK(>=, 1)      used by read_lock()
+ *    RAW_SPINLOCK(==, -1)     used by write_lock()
+ */
+
+
+#define RAW_SPINLOCK(_RELOP_, _val)                            \
+    ea64.ull = ALIGN128_EA(ea);                                        \
+    offset = OFFSET128_EA_U32(ea);                             \
+    do {                                                       \
+        MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);      \
+        spu_readch(MFC_RdAtomicStat);                          \
+        SET_HIT;                                               \
+        status = 1;                                            \
+        if (likely(buf[offset] _RELOP_ 0)) {                   \
+            buf[offset] += _val;                               \
+           MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);    \
+            status = spu_readch(MFC_RdAtomicStat);             \
+        }                                                      \
+    } while (status != 0);
+
+
+static inline void _lock_init(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    u32 oldtmask, tagmask;
+  
+    tagid = mfc_tag_reserve(); 
+   
+    tagmask = 1 << (tagid & 31);
+
+    /* __lock_init
+     *    Internal routine to initialize a spinlock or
+     *    reader/writer lock.
+     */
+    ea64.ull = ALIGN128_EA(ea);
+    offset = OFFSET128_EA_U32(ea);
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD);
+    oldtmask = spu_readch(MFC_RdTagMask);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+
+    buf[offset] = 0;
+    MFC_DMA(buf, ea64, size, tagid & 31, MFC_PUT_CMD);
+    spu_writech(MFC_WrTagMask, tagmask);
+    spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY);
+    spu_readch(MFC_RdTagStat);
+    spu_writech(MFC_WrTagMask, oldtmask);
+    mfc_tag_release(tagid);
+}
+
+static inline void _spin_lock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status;
+
+    /* _spin_lock
+     *    Internal routine to acquire spinlock.
+     */
+/* non trace - no hit/miss indicator */
+#define SET_HIT
+    RAW_SPINLOCK(==, 1);
+}
+
+#ifdef LIBSYNC_TRACE
+static inline s32 _spin_lock_trace(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status = 0;
+/* trace - need hit/miss indicator */
+#undef SET_HIT
+#define SET_HIT        if (status == 0) hit = buf[offset]
+    s32 hit;
+
+    hit = 0;
+    /* _spin_lock_trace for trace
+     *    Internal routine to acquire spinlock.
+     */
+    RAW_SPINLOCK(==, 1);
+
+    return hit;
+
+#undef SET_HIT
+#define SET_HIT
+}
+
+#endif /* LIBSYNC_TRACE */
+
+
+#endif /* SPU_MUTEX_H */
diff --git a/gcell/src/ibm/sync/spu_source/mutex_init.h b/gcell/src/ibm/sync/spu_source/mutex_init.h
new file mode 100644 (file)
index 0000000..9bddb14
--- /dev/null
@@ -0,0 +1,64 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_MUTEX_INIT_H_
+#define _SPU_MUTEX_INIT_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+/***************************************************************************/
+/**
+ * mutex_init - initialize the mutex by setting the value 
+ * to 0.
+ * @lock: handle to effective address of lock variable.
+ *
+ * Description: Initialize a mutex.
+ */
+static __inline void _mutex_init(mutex_ea_t lock)
+{
+   _lock_init(lock);
+
+   TRACE_MUTEX_INIT(lock);
+}
+
+
+#endif /* _SPU_MUTEX_INIT_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/mutex_lock.h b/gcell/src/ibm/sync/spu_source/mutex_lock.h
new file mode 100644 (file)
index 0000000..63bdbc3
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_MUTEX_LOCK_H_
+#define _SPU_MUTEX_LOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+static __inline void _mutex_lock(mutex_ea_t ea)
+{
+
+#ifdef LIBSYNC_TRACE
+   s32 miss = 0;
+
+   TRACE_MUTEX_LOCK_ENTRY(interval);
+   miss = _spin_lock_trace(ea);
+   TRACE_MUTEX_LOCK_EXIT(interval, ea, miss);
+
+#else /* LIBSYNC_TRACE */
+
+   _spin_lock(ea);
+
+#endif /* LIBSYNC_TRACE */
+
+}
+
+#endif /* _SPU_MUTEX_LOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/mutex_trylock.h b/gcell/src/ibm/sync/spu_source/mutex_trylock.h
new file mode 100644 (file)
index 0000000..3c8df46
--- /dev/null
@@ -0,0 +1,70 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_MUTEX_TRYLOCK_H_
+#define _SPU_MUTEX_TRYLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include "trace_libsync.h"
+
+/**
+ * mutex_trylock - acquire a lock, or return immediately.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Description: Acquire a lock, or return immediately 
+ * without polling for availability.
+ *
+ * Context: The application should not call this interface 
+ * from a tight loop!!  Use spin_lock() instead.
+ */
+static __inline int _mutex_trylock(mutex_ea_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status, ret_val;
+
+    RAW_TEST_AND_SET(==, 1);
+
+    TRACE_MUTEX_TRYLOCK(ea, ret_val);
+
+    return ret_val;
+}
+
+#endif /* _SPU_MUTEX_TRYLOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/mutex_unlock.h b/gcell/src/ibm/sync/spu_source/mutex_unlock.h
new file mode 100644 (file)
index 0000000..87d6bba
--- /dev/null
@@ -0,0 +1,59 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_MUTEX_UNLOCK_H_
+#define _SPU_MUTEX_UNLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include "atomic.h"
+#include "trace_libsync.h"
+
+static __inline void _mutex_unlock(mutex_ea_t ea)
+{
+    int ret_val;
+
+    ATOMIC_OP((atomic_ea_t)ea, 0, 1, ret_val);
+
+    TRACE_MUTEX_UNLOCK(ea);
+}
+
+
+#endif /* _SPU_MUTEX_UNLOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/read_lock.h b/gcell/src/ibm/sync/spu_source/read_lock.h
new file mode 100644 (file)
index 0000000..0e1d971
--- /dev/null
@@ -0,0 +1,66 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_READ_LOCK_H_
+#define _SPU_READ_LOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+
+/**
+ * read_lock - acquire reader lock, or spin until available.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Description: Acquire a non-exclusive reader lock, or spin 
+ * until available.  The only restriction here is that @ea
+ * must be word aligned.
+ *
+ * Context: This routine should not be called if SPU 
+ * asynchronous interrupts are enabled.
+ */
+static __inline void _read_lock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status;
+
+    RAW_SPINLOCK(>=, 1);
+}
+
+#endif /* _SPU_READ_LOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/read_trylock.h b/gcell/src/ibm/sync/spu_source/read_trylock.h
new file mode 100644 (file)
index 0000000..d032783
--- /dev/null
@@ -0,0 +1,71 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_READ_TRYLOCK_H_
+#define _SPU_READ_TRYLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+
+/**
+ * read_trylock - acquire a reader lock, or return immediately.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Acquire a non-exclusive reader lock, or return
+ * immediately.  The only restriction here is that
+ * @ea must be word aligned.
+ *
+ * Returns 1 on success, or 0 on failure.
+ *
+ * Context: The application should not call this interface 
+ * from a tight loop!!  Use read_lock() instead.
+ */
+static __inline int _read_trylock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status, ret_val;
+
+    RAW_TEST_AND_SET(>=, 1);
+
+    return ret_val;
+}
+
+
+#endif /* _SPU_READ_TRYLOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/read_unlock.h b/gcell/src/ibm/sync/spu_source/read_unlock.h
new file mode 100644 (file)
index 0000000..f011550
--- /dev/null
@@ -0,0 +1,88 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_READ_UNLOCK_H_
+#define _SPU_READ_UNLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include <spu_mfcio.h>
+
+
+/**
+ * read_unlock - release reader lock.
+ * @ea: handle to effective address of lock variable.
+ * 
+ * Description: Release a reader lock.  The only restriction 
+ * here is that @ea must be word aligned.
+ *
+ * Context: This routine should be used when interrupts
+ * do not need to be re-enabled --either because interrupts
+ * are not being used, or because the application will take
+ * steps to re-enable them later.
+ */
+static __inline void _read_unlock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status;
+
+    /* _read_unlock
+     *
+     *    Reader locks must use PUTLLC when releasing, instead of
+     *    the more traditional PUTLLUC because of the non-exclusive
+     *    nature of the lock.  The reason for this is that other
+     *    readers may have incremented the counter, and we don't
+     *    want to corrupt it by blindly issuing PUTLLUC!!
+     */
+    ea64.ull = ALIGN128_EA(ea);
+    offset = OFFSET128_EA_U32(ea);
+    do {
+        MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+        spu_readch(MFC_RdAtomicStat);
+
+        buf[offset] -= 1;
+        MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+        status = spu_readch(MFC_RdAtomicStat);
+    } while (status != 0);
+
+}
+
+
+#endif /* _SPU_READ_UNLOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/rwlock_init.h b/gcell/src/ibm/sync/spu_source/rwlock_init.h
new file mode 100644 (file)
index 0000000..6b05533
--- /dev/null
@@ -0,0 +1,60 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_RWLOCK_INIT_H_
+#define _SPU_RWLOCK_INIT_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+
+/**
+ * rwlock_init - initialize a reader/writer lock.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Description: Initialize a reader/writer lock.
+ */
+static __inline void _rwlock_init(eaddr_t rwlock)
+{
+    _lock_init(rwlock);
+}
+
+
+
+#endif /* _SPU_RWLOCK_INIT_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/sync_irq.h b/gcell/src/ibm/sync/spu_source/sync_irq.h
new file mode 100644 (file)
index 0000000..feae65e
--- /dev/null
@@ -0,0 +1,76 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+/*
+ * irq.h - SPU interrupt management facilities.
+ * 
+ * These utilities help an "interrupt aware" library to manage
+ * state of SPU interrupts.  
+ */
+
+#ifndef __SPU_IRQ_H__
+#define __SPU_IRQ_H__
+
+#include <spu_intrinsics.h>
+#include "sync_utils.h"
+
+static inline u32 irq_mask(u32 newmask)
+{
+    u32 old, tmp = 0;
+
+    /* irq_mask
+     *    Set the interrupt mask to the newmask value,
+     *    and return its previous setting.  Will
+     *    detect and discard potential phantom
+     *    events.
+     */
+
+    old = spu_readch(SPU_RdEventMask);
+    spu_writech(SPU_WrEventMask, tmp);
+    if (spu_readchcnt(SPU_RdEventStat)) {
+        tmp = spu_readch(SPU_RdEventStat);
+        spu_writech(SPU_WrEventAck, tmp);
+    }
+    spu_writech(SPU_WrEventMask, newmask);
+
+    return old;
+}
+
+#endif /* __SPU_IRQ_H__ */
diff --git a/gcell/src/ibm/sync/spu_source/sync_utils.h b/gcell/src/ibm/sync/spu_source/sync_utils.h
new file mode 100644 (file)
index 0000000..516b41f
--- /dev/null
@@ -0,0 +1,103 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+/*
+ * sync_utils.h - SPU sync-library internal utilities.
+ *
+ * These utilities are used internally by the SPU sync library.
+ */
+#ifndef __SPU_SYNC_UTILS_H__
+#define __SPU_SYNC_UTILS_H__
+
+#include <spu_intrinsics.h>
+
+typedef unsigned int u32;
+typedef signed int s32;
+typedef unsigned long long u64;
+typedef unsigned long long eaddr_t;
+
+
+typedef union {
+    u64 ull;  
+    u32 ui[2];
+} addr64;
+
+#ifndef likely
+#define likely(_c)     \
+    __builtin_expect((_c), 1)
+#define unlikely(_c)    \
+    __builtin_expect((_c), 0)
+#endif
+
+#define ALLOCA(_nbytes, _size)    \
+    alloca((_nbytes) + (_size)-1)
+
+#define ALIGN(_ptr, _size)       \
+    ((((u32) _ptr) + (_size)-1) & ~((_size)-1))
+
+#define ALIGN128_EA(_ull)      \
+    ((_ull) & ~(127ULL))
+/*
+#define OFFSET128_EA(_ull, _type) \
+    (((_ull) & 127ULL) / sizeof(_type))
+    */
+
+#define OFFSET128_EA_U32(_ull) \
+    (((_ull) & 127ULL) >> 2)
+
+#define OFFSET128_EA_U16(_ull) \
+    (((_ull) & 127ULL) >> 1)
+
+#define MFC_DMA(_ls, _ea, _sz, _tg, _cmd) \
+    spu_mfcdma64(_ls, _ea.ui[0], _ea.ui[1], _sz, _tg, _cmd)
+
+#define MFC_SYNC() {                           \
+    u32 _tagid = 0;                            \
+    spu_writech(mfc_tag_id, _tagid);           \
+    spu_writech(mfc_cmd_queue, MFC_SYNC_CMD);  \
+}
+
+#define MFC_EIEIO() {                          \
+    u32 _tagid = 0;                            \
+    spu_writech(mfc_tag_id, _tagid);           \
+    spu_writech(mfc_cmd_queue, MFC_EIEIO_CMD); \
+}
+
+#endif /* __SPU_SYNC_UTILS_H__ */
diff --git a/gcell/src/ibm/sync/spu_source/trace_libsync.h b/gcell/src/ibm/sync/spu_source/trace_libsync.h
new file mode 100644 (file)
index 0000000..47887c9
--- /dev/null
@@ -0,0 +1,117 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2007                                               */
+/* International Business Machines Corporation                     */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef __LIBSYNC_SPU_TRACEHOOKS_H__
+#define __LIBSYNC_SPU_TRACEHOOKS_H__
+
+#ifdef LIBSYNC_TRACE
+
+#include <trace_events.h>
+
+/*
+ *  last parameter in the trace_even and trace_interval_entry call is
+ *   the stack level to report the PC in the trace record. so 0 means
+ *   the PC of the current frame, 1 means the PC of the caller, etc.
+ *   there's a dilemma here - these macros are included in the inline
+ *   _mutex calls which get called from the (created during build)
+ *   mutex functions in the mutex .c files. in that case, the level
+ *   should be 1 - we don't want the PC of where in the mutex function
+ *   the trace call is happening, we want the PC of whomever is calling
+ *   the mutex function.
+ *
+ *   but.. an app can call the inline functions - it can #include the
+ *   appropriate libsync mutex .h files, and call the inlined _mutex
+ *   function in their code. in that case, the appropriate level for the
+ *   trace calls would be 0 - the user would want to know where in their
+ *   code the call to the _mutex function is.
+ *
+ *   so, we'll assume _LEVEL of 0 which is what the inline funtions need.
+ *   when we build the files for libsync, we'll do a -D_LEVEL=1 
+ */
+#ifndef _LEVEL
+#define _LEVEL 0
+#endif
+
+
+#define TRACE_EVENT_MUTEX_INIT 0x0403
+
+#define TRACE_MUTEX_INIT(lock) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(unsigned long)lock; \
+  trace_event(TRACE_EVENT_MUTEX_INIT, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \
+}
+
+#define TRACE_EVENT_MUTEX_LOCK 0x0503
+
+#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) \
+trace_interval_p _INTERVAL = trace_interval_entry(TRACE_EVENT_MUTEX_LOCK, _LEVEL)
+
+#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(unsigned long)lock; \
+  payload.word[2]=(unsigned int)miss; \
+  trace_interval_exit(_INTERVAL, 2,  &payload, "Event=%d, lock=0x%x, miss=0x%x"); \
+}
+
+#define TRACE_EVENT_MUTEX_TRYLOCK 0x0603
+
+#define TRACE_MUTEX_TRYLOCK(lock,ret_val) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(unsigned long)lock; \
+  payload.word[2]=(unsigned int)ret_val; \
+  trace_event(TRACE_EVENT_MUTEX_TRYLOCK, 2, &payload, "Event=%d, lock=0x%x, ret_val=0x%x", _LEVEL); \
+}
+
+#define TRACE_EVENT_MUTEX_UNLOCK 0x0703
+
+#define TRACE_MUTEX_UNLOCK(lock) { \
+  trace_payload_t payload; \
+  payload.dword[0]=(unsigned long)lock; \
+  trace_event(TRACE_EVENT_MUTEX_UNLOCK, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \
+}
+
+#else /* LIBSYNC_TRACE */
+
+#define TRACE_MUTEX_INIT(lock) 
+#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) 
+#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss)
+#define TRACE_MUTEX_TRYLOCK(lock,ret_val)
+#define TRACE_MUTEX_UNLOCK(lock) 
+
+#endif /* LIBSYNC_TRACE */
+
+#endif  /* __LIBSYNC_SPU_TRACEHOOKS_H__ */
diff --git a/gcell/src/ibm/sync/spu_source/wait_for_completion.h b/gcell/src/ibm/sync/spu_source/wait_for_completion.h
new file mode 100644 (file)
index 0000000..ea7bdbe
--- /dev/null
@@ -0,0 +1,82 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_WAIT_FOR_COMPLETION_H_
+#define _SPU_WAIT_FOR_COMPLETION_H_
+
+#include "sync_utils.h"
+#include <spu_mfcio.h>
+#include "sync_irq.h"
+#include "completion.h"
+
+/* _wait_for_completion 
+ *    Internal routine to wait for completion to
+ *    become true (!0).  When completion is false,
+ *    uses lock line reservation lost event to 
+ *    sleep until the variable has been changed.
+ */
+static __inline void _wait_for_completion(completion_ea_t completion)
+{
+    DECL_COMPLETION_VARS();
+    s32 status;
+
+    status = 1;
+
+    ea64.ull = ALIGN128_EA(completion);
+    offset = OFFSET128_EA_U32(completion);
+    do {
+        MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+        spu_readch(MFC_RdAtomicStat);
+        /* if the completion variable has been set elsewhere
+         * (a signal or broadcast function has been called 
+         * then we get out of the loop, and reset the variable */
+        if (likely(buf[offset] != 0)) {
+            /* decrement the variable */
+            buf[offset]--;
+            MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD);
+            spu_readch(MFC_RdAtomicStat);
+            status = 0;
+        }
+    } while (status != 0);
+}
+
+
+
+#endif /* _SPU_WAIT_FOR_COMPLETION_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/write_lock.h b/gcell/src/ibm/sync/spu_source/write_lock.h
new file mode 100644 (file)
index 0000000..7af5175
--- /dev/null
@@ -0,0 +1,67 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_WRITE_LOCK_H_
+#define _SPU_WRITE_LOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+
+/**
+ * write_lock - acquire writer lock, or spin until available.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Description: Acquire an exclusive writer lock, 
+ * or spin until available.  The only restriction 
+ * here is that @ea must be word aligned.
+ *
+ * Context: This routine should not be called if SPU 
+ * asynchronous interrupts are enabled.
+ */
+static __inline void _write_lock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status;
+
+    RAW_SPINLOCK(==, -1);
+}
+
+
+#endif /* _SPU_WRITE_LOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/write_trylock.h b/gcell/src/ibm/sync/spu_source/write_trylock.h
new file mode 100644 (file)
index 0000000..b3799b3
--- /dev/null
@@ -0,0 +1,72 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_WRITE_TRYLOCK_H_
+#define _SPU_WRITE_TRYLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+
+/**
+ * write_trylock - acquire a writer lock, or return immediately.
+ * @ea: handle to effective address of lock variable.
+ *
+ * Try to acquire an exclusive writer lock, or return
+ * immediately.  The only restriction here is that @ea
+ * must be word aligned.
+ *
+ * Returns 1 on success, or 0 on failure.
+ *
+ * Caution:
+ * The application should not call this interface from a tight
+ * loop!!  Use write_lock() instead.
+ */
+static __inline int _write_trylock(eaddr_t ea)
+{
+    DECL_MUTEX_VARS();
+    s32 status, ret_val;
+
+    RAW_TEST_AND_SET(==, -1);
+
+    return ret_val;
+}
+
+
+#endif /* _SPU_WRITE_TRYLOCK_H_ */
diff --git a/gcell/src/ibm/sync/spu_source/write_unlock.h b/gcell/src/ibm/sync/spu_source/write_unlock.h
new file mode 100644 (file)
index 0000000..25b24e1
--- /dev/null
@@ -0,0 +1,69 @@
+/* --------------------------------------------------------------  */
+/* (C)Copyright 2001,2007,                                         */
+/* International Business Machines Corporation,                    */
+/* Sony Computer Entertainment, Incorporated,                      */
+/* Toshiba Corporation,                                            */
+/*                                                                 */
+/* All Rights Reserved.                                            */
+/*                                                                 */
+/* Redistribution and use in source and binary forms, with or      */
+/* without modification, are permitted provided that the           */
+/* following conditions are met:                                   */
+/*                                                                 */
+/* - Redistributions of source code must retain the above copyright*/
+/*   notice, this list of conditions and the following disclaimer. */
+/*                                                                 */
+/* - Redistributions in binary form must reproduce the above       */
+/*   copyright notice, this list of conditions and the following   */
+/*   disclaimer in the documentation and/or other materials        */
+/*   provided with the distribution.                               */
+/*                                                                 */
+/* - Neither the name of IBM Corporation nor the names of its      */
+/*   contributors may be used to endorse or promote products       */
+/*   derived from this software without specific prior written     */
+/*   permission.                                                   */
+/*                                                                 */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND          */
+/* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,     */
+/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF        */
+/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE        */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            */
+/* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT    */
+/* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)        */
+/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN       */
+/* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    */
+/* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  */
+/* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              */
+/* --------------------------------------------------------------  */
+/* PROLOG END TAG zYx                                              */
+#ifndef _SPU_WRITE_UNLOCK_H_
+#define _SPU_WRITE_UNLOCK_H_
+
+#include "sync_utils.h"
+#include "mutex.h"
+#include <spu_mfcio.h>
+
+/**
+ * write_unlock - release writer lock.
+ * @rwlock: handle to effective address of lock variable.
+ *
+ * Release a single writer lock.
+ */
+static __inline void _write_unlock(eaddr_t rwlock)
+{
+    DECL_MUTEX_VARS();
+
+    ea64.ull = ALIGN128_EA(rwlock);
+    offset = OFFSET128_EA_U32(rwlock);
+    MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD);
+    spu_readch(MFC_RdAtomicStat);
+
+    buf[offset] = 0;
+    MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD);
+    spu_readch(MFC_RdAtomicStat);
+}
+
+
+#endif /* _SPU_WRITE_UNLOCK_H_ */
diff --git a/gcell/src/include/Makefile.am b/gcell/src/include/Makefile.am
new file mode 100644 (file)
index 0000000..1e65282
--- /dev/null
@@ -0,0 +1,39 @@
+#
+# 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 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
+
+SUBDIRS = spu
+
+gcellinclude_HEADERS = \
+       compiler.h \
+       gc_atomic.h \
+       gc_cdefs.h \
+       gc_declare_proc.h \
+       gc_jd_queue_data.h \
+       gc_jd_queue.h \
+       gc_jd_stack.h \
+       gc_job_desc.h \
+       gc_job_desc_private.h \
+       gc_logging.h \
+       gc_mbox.h \
+       gc_spu_args.h \
+       gc_types.h \
+       memory_barrier.h
diff --git a/gcell/src/include/compiler.h b/gcell/src/include/compiler.h
new file mode 100644 (file)
index 0000000..74a9739
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_COMPILER_H
+#define INCLUDED_COMPILER_H
+
+/*!
+ * \brief Compiler specific hackery.  These are for GCC.
+ */
+
+#define _AL8   __attribute__((aligned (8)))
+#define _AL16  __attribute__((aligned (16)))
+#define _AL128 __attribute__((aligned (128)))
+
+#ifndef likely
+#define likely(x)       __builtin_expect(!!(x), 1)
+#define unlikely(x)     __builtin_expect(!!(x), 0)
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+
+#endif /* INCLUDED_COMPILER_H */
diff --git a/gcell/src/include/gc_atomic.h b/gcell/src/include/gc_atomic.h
new file mode 100644 (file)
index 0000000..01737cd
--- /dev/null
@@ -0,0 +1,29 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_ATOMIC_H
+#define INCLUDED_GC_ATOMIC_H
+
+#include <stdint.h>
+
+typedef uint32_t       gc_atomic_t;
+
+
+#endif /* INCLUDED_GC_ATOMIC_H */
diff --git a/gcell/src/include/gc_cdefs.h b/gcell/src/include/gc_cdefs.h
new file mode 100644 (file)
index 0000000..93084ba
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_CDEFS_H
+#define INCLUDED_GC_CDEFS_H
+
+/* C++ needs to know that types and declarations are C, not C++.  */
+#ifdef __cplusplus
+# define __GC_BEGIN_DECLS      extern "C" {
+# define __GC_END_DECLS        }
+#else
+# define __GC_BEGIN_DECLS
+# define __GC_END_DECLS
+#endif
+
+#endif /* INCLUDED_GC_CDEFS_H */
diff --git a/gcell/src/include/gc_declare_proc.h b/gcell/src/include/gc_declare_proc.h
new file mode 100644 (file)
index 0000000..37af5ba
--- /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_GC_DECLARE_PROC_H
+#define INCLUDED_GC_DECLARE_PROC_H
+
+#include <stdint.h>
+#include <gc_job_desc.h>
+
+/*
+ * This is C, not C++ code...
+ *
+ * ...and is used by both PPE and SPE code
+ */
+__GC_BEGIN_DECLS
+
+#define GC_PROC_DEF_SECTION ".gcell.proc_def"
+
+typedef struct gc_proc_def {
+#if defined(__SPU__)
+  gc_spu_proc_t        proc;
+#else
+  uint32_t     proc;
+#endif
+  char         name[28];
+} _AL16 gc_proc_def_t;
+
+
+#if defined(__SPU__)
+/*!
+ * \brief Tell gcell about a SPU procedure
+ *
+ * \param _proc_   pointer to function (gc_spu_proc_t)
+ * \param _name_   the name of the procedure ("quoted string")
+ *
+ * This macro registers the given procedure with the gcell runtime.
+ * From the PPE, use gc_job_manager::lookup_proc to map \p _name_ to a gc_proc_id_t
+ */
+#define GC_DECLARE_PROC(_proc_, _name_) \
+static struct gc_proc_def \
+  _GCPD_ ## _proc_ __attribute__((section(GC_PROC_DEF_SECTION), used)) = \
+  { _proc_, _name_ }
+#endif
+
+__GC_END_DECLS
+
+#endif /* INCLUDED_GC_DECLARE_PROC_H */
diff --git a/gcell/src/include/gc_jd_queue.h b/gcell/src/include/gc_jd_queue.h
new file mode 100644 (file)
index 0000000..f5f8a1a
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JD_QUEUE_H
+#define INCLUDED_GC_JD_QUEUE_H
+
+#include "gc_jd_queue_data.h"
+
+__GC_BEGIN_DECLS
+
+/*!
+ * \brief Initialize the queue to empty.
+ */
+void 
+gc_jd_queue_init(gc_jd_queue_t *q);
+  
+
+/*!
+ * \brief Add \p item to the tail of \p q.
+ */
+void 
+gc_jd_queue_enqueue(gc_jd_queue_t *q, gc_job_desc_t *item);
+
+
+/*!
+ * \brief Remove and return item at head of queue, or 0 if queue is empty
+ */
+gc_job_desc_t *
+gc_jd_queue_dequeue(gc_jd_queue_t *q);
+
+__GC_END_DECLS
+
+
+#endif /* INCLUDED_GC_JD_QUEUE_H */
diff --git a/gcell/src/include/gc_jd_queue_data.h b/gcell/src/include/gc_jd_queue_data.h
new file mode 100644 (file)
index 0000000..d48591b
--- /dev/null
@@ -0,0 +1,51 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JD_QUEUE_DATA_H
+#define INCLUDED_GC_JD_QUEUE_DATA_H
+
+#include "gc_types.h"
+#include "gc_job_desc.h"
+
+__GC_BEGIN_DECLS
+
+/*!
+ * \brief (Lock free someday...) queue for job descriptors
+ *
+ * This is the main data structure shared between PPEs and SPEs.
+ * It is used to enqueue work for SPEs.  SPEs or PPEs may enqueue
+ * work.  SPE's dequeue from here.
+ *
+ * FIXME make it lock free ;)  For now, use a spin lock.
+ */
+typedef struct gc_jd_queue
+{
+  gc_eaddr_t   head _AL16;
+  gc_eaddr_t   tail _AL16;
+  uint32_t     mutex;          // libsync mutex (spin lock)
+} gc_jd_queue_t;
+
+
+__GC_END_DECLS
+
+#endif /* INCLUDED_GC_JD_QUEUE_DATA_H */
+
+
diff --git a/gcell/src/include/gc_jd_stack.h b/gcell/src/include/gc_jd_stack.h
new file mode 100644 (file)
index 0000000..72e9435
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JD_STACK_H
+#define INCLUDED_GC_JD_STACK_H
+
+#include "gc_types.h"
+#include "gc_job_desc.h"
+
+__GC_BEGIN_DECLS
+
+/*!
+ * \brief Lock free stack for job descriptors (used for free list)
+ *
+ * This is aligned to a cache line, and fills the cache line,
+ * to avoid inadvertently losing reservations created with
+ * the load-and-reserve instructions.
+ */
+
+typedef struct gc_jd_stack
+{
+  gc_eaddr_t   top;
+
+  // pad out to a full cache line
+  uint8_t      _pad[128 - sizeof(gc_eaddr_t)];
+} _AL128 gc_jd_stack_t;
+
+
+/*!
+ * \brief Initialize the stack to empty.
+ */
+void 
+gc_jd_stack_init(gc_jd_stack_t *stack);
+  
+
+/*!
+ * \brief Add \p item to the top of \p stack.
+ */
+void 
+gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item);
+
+
+/*!
+ * \brief pop and return top item on stack, or 0 if stack is empty
+ */
+gc_job_desc_t *
+gc_jd_stack_pop(gc_jd_stack_t *stack);
+
+__GC_END_DECLS
+
+
+#endif /* INCLUDED_GC_JD_STACK_H */
diff --git a/gcell/src/include/gc_job_desc.h b/gcell/src/include/gc_job_desc.h
new file mode 100644 (file)
index 0000000..b791506
--- /dev/null
@@ -0,0 +1,213 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JOB_DESC_H
+#define INCLUDED_GC_JOB_DESC_H
+
+/*!
+ * This file contains the structures that are used to describe how to
+ * call "jobs" that execute on the SPEs.  A "job" is a task, or piece of
+ * work that you want to run on an SPE.
+ *
+ * There is code running in the SPE that knows how to interpret
+ * these job descriptions. Thus, in most cases, the overhead
+ * of invoking these is very low.
+ *
+ * The whole "job idea" is SPE centric.  At first pass,
+ * the PPE will be constructing jobs and enqueing them.
+ * However, there is nothing in the implementation that
+ * prohibits SPEs from creating their own jobs in the
+ * future.  Also, there is nothing prohibiting SPE-to-SPE
+ * DMA's.
+ *
+ * SPE's dequeue and "pull" jobs to themselves, do the work, then
+ * notify the entity that submitted the job.
+ */
+
+#include "gc_types.h"
+#include "gc_job_desc_private.h"
+
+/*
+ * This is C, not C++ code...
+ *
+ * ...and is used by both PPE and SPE code
+ */
+__GC_BEGIN_DECLS
+
+
+//! opaque ID that specifies which code to invoke on the SPE
+typedef uint32_t gc_proc_id_t;
+#define GCP_UNKNOWN_PROC ((gc_proc_id_t) -1)
+
+
+//! final job status
+typedef enum {
+  JS_OK,
+  JS_SHUTTING_DOWN,        // job mananger is shutting down
+  JS_TOO_MANY_CLIENTS,     // too many client threads
+  JS_UNKNOWN_PROC,         // didn't recognize the procedure ID
+  JS_BAD_DIRECTION,        // EA arg has invalid direction
+  JS_BAD_EAH,              // not all EA args have the same high 32 address bits
+  JS_BAD_N_DIRECT,         // too many direct args
+  JS_BAD_N_EA,             // too many EA args
+  JS_ARGS_TOO_LONG,        // total length of EA args exceeds limit
+  JS_BAD_JUJU,             // misc problem: you're having a bad day
+  JS_BAD_JOB_DESC,         // gc_job_desc was not allocated using mgr->alloc_job_desc()
+
+} gc_job_status_t;
+
+#define MAX_ARGS_DIRECT  8  // maximum number of args passed using "direct" method
+#define MAX_ARGS_EA     8  // maximum number of args passed via EA memory (dma)
+
+/*
+ * We support two classes of arguments,
+ *   "direct", which are contained in the gc_job_desc_args and
+ *   "EA", which are copied in/out according to info in gc_job_desc_args
+ */
+
+/*!
+ * \brief Tag type of "direct" argument
+ */
+typedef enum {
+  GCT_S32,
+  GCT_U32,
+  GCT_S64,
+  GCT_U64,
+  GCT_FLOAT,
+  GCT_DOUBLE,
+  GCT_FLT_CMPLX,
+  GCT_DBL_CMPLX,
+  GCT_EADDR,
+
+} gc_tag_t;
+
+
+/*!
+ * \brief union for passing "direct" argument
+ */
+typedef union gc_arg_union
+{
+  int32_t       s32;
+  uint32_t      u32;
+  int64_t       s64;
+  uint64_t      u64;
+  float                 f;
+  double        d;
+  //float complex  cf; //  64-bits (C99)
+  //double complex cd;  // 128-bits (C99)
+  gc_eaddr_t    ea;    //  64-bits
+} _AL8 gc_arg_union_t;
+
+
+/*!
+ * \brief "direct" input or output arguments
+ */
+typedef struct gc_job_direct_args
+{
+  uint32_t       nargs;                        // # of "direct" args
+  gc_tag_t       tag[MAX_ARGS_DIRECT] _AL16;   // type of direct arg[i]
+  gc_arg_union_t  arg[MAX_ARGS_DIRECT] _AL16;   // direct argument values
+
+} _AL16 gc_job_direct_args_t;
+
+
+// specifies direction for args passed in EA memory
+
+#define GCJD_DMA_GET           0x01            // in to SPE
+#define        GCJD_DMA_PUT            0x02            // out from SPE
+
+/*!
+ * \brief Description of args passed in EA memory.
+ * These are DMA'd between EA and LS as specified.
+ */
+typedef struct gc_job_ea_arg {
+  //! EA address of buffer
+  gc_eaddr_t     ea_addr;      
+
+  //! GC_JD_DMA_* get arg or put arg
+  uint32_t      direction;
+
+  //! number of bytes to get
+  uint32_t      get_size;         
+
+  //! number of bytes to put
+  uint32_t      put_size;
+
+#if defined(__SPU__)
+  //! local store address (filled in by SPU runtime)
+  void         *ls_addr;
+  uint32_t      _pad[2];
+#else
+  uint32_t       _pad[3];
+#endif
+
+} _AL16 gc_job_ea_arg_t;
+
+
+typedef struct gc_job_ea_args {
+  uint32_t             nargs;
+  gc_job_ea_arg_t      arg[MAX_ARGS_EA];
+
+} _AL16 gc_job_ea_args_t;
+
+
+/*!
+ * \brief "job description" that is DMA'd to/from the SPE.
+ */
+typedef struct gc_job_desc
+{
+  gc_job_desc_private_t sys;     // internals
+  gc_job_status_t      status;   // what happened (output)
+  gc_proc_id_t          proc_id;  // specifies which procedure to run
+  gc_job_direct_args_t input;    // direct args to SPE
+  gc_job_direct_args_t output;   // direct args from SPE
+  gc_job_ea_args_t     eaa;      // args passed via EA memory
+
+} _AL128 gc_job_desc_t;
+
+
+/*!
+ * type of procedure invoked on spu
+ */
+typedef void (*gc_spu_proc_t)(const gc_job_direct_args_t *input,
+                             gc_job_direct_args_t *output,
+                             const gc_job_ea_args_t *eaa);
+
+#if !defined(__SPU__)
+
+static inline gc_job_desc_t *
+ea_to_jdp(gc_eaddr_t ea)
+{
+  return (gc_job_desc_t *) ea_to_ptr(ea);
+}
+
+static inline gc_eaddr_t
+jdp_to_ea(gc_job_desc_t *item)
+{
+  return ptr_to_ea(item);
+}
+
+#endif
+
+
+__GC_END_DECLS
+
+#endif /* INCLUDED_GC_JOB_DESC_H */
diff --git a/gcell/src/include/gc_job_desc_private.h b/gcell/src/include/gc_job_desc_private.h
new file mode 100644 (file)
index 0000000..1f76d86
--- /dev/null
@@ -0,0 +1,39 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JOB_DESC_PRIVATE_H
+#define INCLUDED_GC_JOB_DESC_PRIVATE_H
+
+// #include <libsync.h>
+
+/*!
+ * \brief Implementation details we'd like to hide from the user.
+ */
+typedef struct gc_job_desc_private
+{
+  gc_eaddr_t   next;               // used to implement job queue and free list
+  uint16_t     job_id;
+  uint16_t     client_id;
+  uint32_t     direction_union;    // union of all gc_job_ea_arg.direction fields
+} gc_job_desc_private_t;
+
+#endif /* INCLUDED_GC_JOB_PRIVATE_H */
+
diff --git a/gcell/src/include/gc_logging.h b/gcell/src/include/gc_logging.h
new file mode 100644 (file)
index 0000000..b98c283
--- /dev/null
@@ -0,0 +1,166 @@
+/* -*- 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_GC_LOGGING_H
+#define INCLUDED_GC_LOGGING_H
+
+#include <gc_types.h>
+#include <string.h>
+
+__GC_BEGIN_DECLS
+
+typedef struct gc_log {
+  gc_eaddr_t           base;           // gc_log_entry_t * (16 byte aligned)
+  uint32_t     nentries;       // number of entries (power-of-2)
+} gc_log_t;
+
+typedef struct gc_log_entry {
+  uint32_t     seqno;          // monotonic sequence number
+  uint32_t     timestamp;      // decrementer value (wraps every 53s on PS3)
+  uint16_t     subsystem;      // 0 to 255 reserved for system, user gets 256 and up
+  uint16_t     event;
+  uint32_t     info[5];
+} _AL16 gc_log_entry_t;
+
+#define        GCL_SS_SYS      0       // lowest system reserved subsystem
+#define        GCL_SS_USER   256       // lowest user reserved subsystem
+
+
+/*
+ * The resulting log files can be displayed using using:
+ *
+ *  $ od -t x4 -w32 spu_log.00 | less
+ */
+
+
+#if defined(__SPU__)
+
+/*!
+ * System fills in seqno and timestamp.  User is responsible for the rest.
+ */
+
+void _gc_log_write(gc_log_entry_t entry);
+
+#ifdef ENABLE_GC_LOGGING
+#define gc_log_write(entry) _gc_log_write(entry)
+#else
+#define gc_log_write(entry) do { } while (0)
+#endif
+
+inline static void
+gc_log_write0(int subsystem, int event)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = 0;
+  e.info[1] = 0;
+  e.info[2] = 0;
+  e.info[3] = 0;
+  e.info[4] = 0;
+  gc_log_write(e);
+}
+
+inline static void
+gc_log_write1(int subsystem, int event,
+             uint32_t info0)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = info0;
+  e.info[1] = 0;
+  e.info[2] = 0;
+  e.info[3] = 0;
+  e.info[4] = 0;
+  gc_log_write(e);
+}
+
+inline static void
+gc_log_write2(int subsystem, int event,
+             uint32_t info0, uint32_t info1)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = info0;
+  e.info[1] = info1;
+  e.info[2] = 0;
+  e.info[3] = 0;
+  e.info[4] = 0;
+  gc_log_write(e);
+}
+
+inline static void
+gc_log_write3(int subsystem, int event,
+             uint32_t info0, uint32_t info1, uint32_t info2)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = info0;
+  e.info[1] = info1;
+  e.info[2] = info2;
+  e.info[3] = 0;
+  e.info[4] = 0;
+  gc_log_write(e);
+}
+
+inline static void
+gc_log_write4(int subsystem, int event,
+             uint32_t info0, uint32_t info1, uint32_t info2, uint32_t info3)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = info0;
+  e.info[1] = info1;
+  e.info[2] = info2;
+  e.info[3] = info3;
+  e.info[4] = 0;
+  gc_log_write(e);
+}
+
+inline static void
+gc_log_write5(int subsystem, int event,
+             uint32_t info0, uint32_t info1, uint32_t info2, uint32_t info3, uint32_t info4)
+{
+  gc_log_entry_t e;
+  e.subsystem = subsystem;
+  e.event = event;
+  e.info[0] = info0;
+  e.info[1] = info1;
+  e.info[2] = info2;
+  e.info[3] = info3;
+  e.info[4] = info4;
+  gc_log_write(e);
+}
+
+/*!
+ * One time initialization called by system runtime
+ */
+void
+_gc_log_init(gc_log_t log_info);
+
+#endif
+
+__GC_END_DECLS
+
+#endif /* INCLUDED_GC_LOGGING_H */
diff --git a/gcell/src/include/gc_mbox.h b/gcell/src/include/gc_mbox.h
new file mode 100644 (file)
index 0000000..32b23c6
--- /dev/null
@@ -0,0 +1,52 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_MBOX_H
+#define INCLUDED_GC_MBOX_H
+
+/*
+ * The PPE and SPE exchange a few 32-bit messages via mailboxes.
+ * All have a 4 bit opcode in the high bits.
+ *
+ *      3                   2                   1
+ *    1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *   |  op   |                        arg                            |
+ *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define MK_MBOX_MSG(cmd, args) ((((cmd) & 0xf) << 28) | ((args) & 0x0fffffff))
+#define MBOX_MSG_OP(msg)  (((msg) >> 28) & 0xf)
+#define        MBOX_MSG_ARG(msg) ((msg) & 0x0fffffff)
+
+// PPE to SPE (sent via SPE Read Inbound Mailbox)
+
+#define OP_EXIT                        0x0     // exit now
+#define        OP_GET_SPU_BUFSIZE      0x1 
+
+// SPE to PPE (sent via SPE Write Outbound Interrupt Mailbox)
+
+#define OP_JOBS_DONE           0x2     // arg is 0 or 1, indicating which
+                                       //   gc_completion_info_t contains the info
+#define        OP_SPU_BUFSIZE          0x3     // arg is max number of bytes
+
+
+#endif /* INCLUDED_GC_MBOX_H */
diff --git a/gcell/src/include/gc_spu_args.h b/gcell/src/include/gc_spu_args.h
new file mode 100644 (file)
index 0000000..f5a2122
--- /dev/null
@@ -0,0 +1,60 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_SPU_ARGS_H
+#define INCLUDED_GC_SPU_ARGS_H
+
+#include <gc_types.h>
+#include <gc_logging.h>
+
+// args passed to SPE at initialization time
+
+typedef struct gc_spu_args {
+  gc_eaddr_t   queue;          // address of job queue (gc_jd_queue_t *)
+  gc_eaddr_t   comp_info[2];   // completion info (gc_comp_info_t *)
+  uint32_t     spu_idx;        // which spu we are: [0,nspus-1]
+  uint32_t     nspus;          // number of spus we're using
+  uint32_t     proc_def_ls_addr;  // LS addr of proc_def table
+  uint32_t     nproc_defs;        // number of proc_defs in table
+  gc_log_t     log;               // logging info
+} _AL16 gc_spu_args_t;
+
+
+#define        GC_CI_NJOBS     62      // makes gc_comp_info 1 cache line long
+
+/*!
+ * \brief Used to return info to PPE on which jobs are completed.
+ *
+ * When each SPE is initalized, it is passed EA pointers to two of
+ * these structures.  The SPE uses these to communicate which jobs
+ * that it has worked on are complete.  The SPE notifies the PPE by
+ * sending an OP_JOBS_DONE message (see gc_mbox.h) with an argument of
+ * 0 or 1, indicating which of the two comp_info's to examine.  The
+ * SPE sets the in_use flag to 1 before DMA'ing to the PPE.  When the
+ * PPE is done with the structure, it must clear the in_use field to
+ * let the SPE know it can begin using it again.
+ */
+typedef struct gc_comp_info {
+  uint16_t     in_use;         // set by SPE, cleared by PPE when it's finished
+  uint16_t     ncomplete;      // number of valid job_id's
+  uint16_t     job_id[GC_CI_NJOBS];    // job_id's of completed jobs
+} _AL128 gc_comp_info_t;
+
+#endif /* INCLUDED_GC_SPU_ARGS_H */
diff --git a/gcell/src/include/gc_types.h b/gcell/src/include/gc_types.h
new file mode 100644 (file)
index 0000000..9a4d054
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_TYPES_H
+#define INCLUDED_GC_TYPES_H
+
+#include <stdint.h>
+#include <gc_cdefs.h>
+#include "compiler.h"
+
+__GC_BEGIN_DECLS
+
+#ifndef __cplusplus
+typedef int bool;
+#define true  1
+#define false 0
+#endif
+
+/*!
+ * \brief 64-bit integer type representing an effective address (EA)
+ *
+ * This type is always 64-bits, regardless of whether we're
+ * running in 32 or 64-bit mode.
+ */
+typedef uint64_t       gc_eaddr_t;
+
+#if !defined(__SPU__)
+static inline void *
+ea_to_ptr(gc_eaddr_t ea)
+{
+  // in 32-bit mode we're tossing the top 32-bits.
+  return (void *) (uintptr_t) ea;
+}
+
+static inline gc_eaddr_t
+ptr_to_ea(void *p)
+{
+  // two steps to avoid compiler warning in 32-bit mode.
+  return (gc_eaddr_t) (uintptr_t) p;
+}
+#endif
+
+__GC_END_DECLS
+
+#endif /* INCLUDED_GC_TYPES_H */
diff --git a/gcell/src/include/memory_barrier.h b/gcell/src/include/memory_barrier.h
new file mode 100644 (file)
index 0000000..b373ffd
--- /dev/null
@@ -0,0 +1,66 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_MEMORY_BARRIER_H
+#define INCLUDED_MEMORY_BARRIER_H
+
+/*
+ * powerpc memory barriers
+ *
+ * The sync instruction guarantees that all memory accesses initiated
+ * by this processor have been performed (with respect to all other
+ * mechanisms that access memory).  The eieio instruction is a barrier
+ * providing an ordering (separately) for (a) cacheable stores and (b)
+ * loads and stores to non-cacheable memory (e.g. I/O devices).
+ *
+ * smp_mb() prevents loads and stores being reordered across this point.
+ * smp_rmb() prevents loads being reordered across this point.
+ * smp_wmb() prevents stores being reordered across this point.
+ *
+ * We have to use the sync instructions for smp_mb(), since lwsync
+ * doesn't order loads with respect to previous stores.  Lwsync is
+ * fine for smp_rmb(), though.  For smp_wmb(), we use eieio since it
+ * is only used to order updates to system memory.
+ *
+ * For details, see "PowerPC Virtual Environment Architecture, Book
+ * II".  Especially Chapter 1, "Storage Model" and Chapter 3, "Storage
+ * Control Instructions." (site:ibm.com)
+ */
+
+#include <ppu_intrinsics.h>
+
+static inline void smp_mb(void)
+{
+  __sync();
+}
+
+static inline void smp_rmb(void)
+{
+  __lwsync();
+}
+
+static inline void smp_wmb(void)
+{
+  __eieio();
+}
+
+
+#endif /* INCLUDED_MEMORY_BARRIER_H */
diff --git a/gcell/src/include/spu/Makefile.am b/gcell/src/include/spu/Makefile.am
new file mode 100644 (file)
index 0000000..d202336
--- /dev/null
@@ -0,0 +1,25 @@
+#
+# 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 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
+
+gcellspuinclude_HEADERS = \
+       gc_delay.h \
+       gc_jd_queue.h
diff --git a/gcell/src/include/spu/gc_delay.h b/gcell/src/include/spu/gc_delay.h
new file mode 100644 (file)
index 0000000..78f16fb
--- /dev/null
@@ -0,0 +1,27 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_DELAY_H
+#define INCLUDED_GC_DELAY_H
+
+void gc_udelay(unsigned int usecs);
+void gc_cdelay(unsigned int cpu_cycles);
+
+#endif /* INCLUDED_GC_DELAY_H */
diff --git a/gcell/src/include/spu/gc_jd_queue.h b/gcell/src/include/spu/gc_jd_queue.h
new file mode 100644 (file)
index 0000000..f1ce1b3
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_SPU_GC_JD_QUEUE_H
+#define INCLUDED_SPU_GC_JD_QUEUE_H
+
+#include "gc_jd_queue_data.h"
+
+/*
+ * Declarations for SPU side of job queue interface
+ */
+
+__GC_BEGIN_DECLS
+
+/*!
+ * \brief Remove and return item at head of queue.
+ *
+ * \param[in]  q is EA address of queue structure.
+ * \param[out] item_ea is EA address of item at head of queue.
+ * \param[out] item is local store copy of item at head of queue.
+ * \returns false if the queue is empty, otherwise returns true
+ *   and sets \p item_ea and DMA's job descriptor into \p item
+ */
+bool
+gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item);
+
+
+/*!
+ * \brief Get a line reservation on the queue
+ *
+ * \param[in]  q is EA address of queue structure.
+ */
+void
+gc_jd_queue_getllar(gc_eaddr_t q);
+
+__GC_END_DECLS
+
+
+#endif /* INCLUDED_SPU_GC_JD_QUEUE_H */
diff --git a/gcell/src/lib/Makefile.am b/gcell/src/lib/Makefile.am
new file mode 100644 (file)
index 0000000..2ccedc3
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# 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
+
+SUBDIRS = spu runtime general procs .
+
+# generate libgcell.la from the convenience libraries in subdirs
+
+lib_LTLIBRARIES = libgcell.la libgcell-qa.la
+
+libgcell_la_SOURCES = 
+libgcell_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libgcell_qa_la_SOURCES = 
+libgcell_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0
+
+libgcell_la_LIBADD = \
+       runtime/libruntime.la \
+       -lspe2 \
+       $(OMNITHREAD_LA)
+
+libgcell_qa_la_LIBADD = \
+       runtime/libruntime-qa.la \
+       $(CPPUNIT_LIBS)
+
+
+
+
+
+
diff --git a/gcell/src/lib/general/Makefile.am b/gcell/src/lib/general/Makefile.am
new file mode 100644 (file)
index 0000000..0e32ffc
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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
+
+# SUBDIRS = spu .
+
diff --git a/gcell/src/lib/procs/Makefile.am b/gcell/src/lib/procs/Makefile.am
new file mode 100644 (file)
index 0000000..0e32ffc
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# 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
+
+# SUBDIRS = spu .
+
diff --git a/gcell/src/lib/runtime/Makefile.am b/gcell/src/lib/runtime/Makefile.am
new file mode 100644 (file)
index 0000000..3f2077c
--- /dev/null
@@ -0,0 +1,76 @@
+#
+# 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 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
+
+# SUBDIRS = spu .
+
+IBM_PPU_SYNC_INCLUDES = -I$(top_srcdir)/gcell/src/ibm/sync/ppu_source
+
+
+AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(MBLOCK_INCLUDES) $(CPPUNIT_INCLUDES) \
+       $(GCELL_INCLUDES) $(IBM_PPU_SYNC_INCLUDES) $(WITH_INCLUDES)
+
+
+noinst_LTLIBRARIES = libruntime.la libruntime-qa.la
+
+libruntime_la_SOURCES = \
+       gc_job_manager.cc \
+       gc_job_manager_impl.cc \
+       gc_jd_queue.c \
+       gc_jd_stack.c \
+       gc_proc_def_utils.cc
+
+libruntime_qa_la_SOURCES = \
+       qa_lib.cc \
+       qa_jd_queue.cc \
+       qa_jd_stack.cc \
+       qa_job_manager.cc
+
+
+gcellinclude_HEADERS = \
+       gc_job_manager.h
+
+noinst_HEADERS = \
+       gc_client_thread_info.h \
+       gc_job_manager_impl.h \
+       gc_proc_def_utils.h \
+       qa_jd_queue.h \
+       qa_jd_stack.h \
+       qa_job_manager.h \
+       qa_lib.h
+
+
+# This kruft is required to link the QA SPU executable into the PPE shared lib w/o warnings
+gcell_qa.lo: ../spu/gcell_qa
+       ppu-embedspu -m32 -fpic gcell_qa ../spu/gcell_qa .libs/gcell_qa.o
+       @rm -f gcell_qa.lo
+       @echo "# gcell_qa.lo - a libtool object file" >> gcell_qa.lo
+       @echo "# Generated by ltmain.sh - GNU libtool 1.5.22 (1.1220.2.365 2005/12/18 22:14:06)" >> gcell_qa.lo
+       @echo "#" >> gcell_qa.lo
+       @echo "# Please DO NOT delete this file!" >> gcell_qa.lo
+       @echo "# It is necessary for linking the library." >> gcell_qa.lo
+       @echo "" >> gcell_qa.lo
+       @echo "pic_object='.libs/gcell_qa.o'" >> gcell_qa.lo
+       @echo "non_pic_object=none" >> gcell_qa.lo
+
+libruntime_qa_la_LIBADD = \
+       gcell_qa.lo \
+       libruntime.la
diff --git a/gcell/src/lib/runtime/gc_client_thread_info.h b/gcell/src/lib/runtime/gc_client_thread_info.h
new file mode 100644 (file)
index 0000000..fbb35d9
--- /dev/null
@@ -0,0 +1,81 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_CLIENT_THREAD_INFO_H
+#define INCLUDED_GC_CLIENT_THREAD_INFO_H
+
+#include <omnithread.h>
+#include <boost/utility.hpp>
+
+enum gc_ct_state {
+  CT_NOT_WAITING,
+  CT_WAIT_ALL,
+  CT_WAIT_ANY,
+};
+
+/*
+ * \brief per client-thread data used by gc_job_manager
+ *
+ * "Client threads" are any threads that invoke methods on
+ * gc_job_manager.  We use pthread_set_specific to store a pointer to
+ * one of these for each thread that comes our way.
+ */
+class gc_client_thread_info : boost::noncopyable {
+public:
+  gc_client_thread_info() :
+    d_free(1), d_cond(&d_mutex), d_state(CT_NOT_WAITING),
+    d_jobs_done(0), d_njobs_waiting_for(0),
+    d_jobs_waiting_for(0){ }
+
+  ~gc_client_thread_info() {
+    d_free = 1;
+    d_state = CT_NOT_WAITING;
+    d_jobs_done = 0;
+    d_njobs_waiting_for = 0;
+    d_jobs_waiting_for = 0;
+  }
+
+  //! is this cti free? (1->free, 0->in use)
+  uint32_t       d_free;
+
+  //! which client info are we?
+  uint16_t       d_client_id;
+
+  //! hold this mutex to manipulate anything below here
+  omni_mutex     d_mutex;
+
+  //! signaled by event handler to wake client thread up
+  omni_condition  d_cond;
+
+  //! Is this client waiting?
+  gc_ct_state    d_state;
+  
+  //! Jobs that have finished and not yet been waited for (bitvector)
+  unsigned long         *d_jobs_done;
+
+  //! # of jobs we're waiting for
+  unsigned int    d_njobs_waiting_for;
+
+  //! Jobs that client thread is waiting for
+  gc_job_desc   **d_jobs_waiting_for;
+
+};
+
+#endif /* INCLUDED_GC_CLIENT_THREAD_INFO_H */
diff --git a/gcell/src/lib/runtime/gc_jd_queue.c b/gcell/src/lib/runtime/gc_jd_queue.c
new file mode 100644 (file)
index 0000000..b5cdcac
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_jd_queue.h"
+#include "memory_barrier.h"
+#include <mutex_init.h>
+#include <mutex_lock.h>
+#include <mutex_unlock.h>
+
+void 
+gc_jd_queue_init(gc_jd_queue_t *q)
+{
+  _mutex_init(ptr_to_ea(&q->mutex));
+  q->head = 0;
+  q->tail = 0;
+  smp_wmb();
+}
+  
+void
+gc_jd_queue_enqueue(gc_jd_queue_t *q, gc_job_desc_t *item)
+{
+  item->sys.next = 0;
+  _mutex_lock(ptr_to_ea(&q->mutex));
+  smp_rmb();           // import barrier
+
+  if (q->tail == 0){    // currently empty
+    q->tail = q->head = jdp_to_ea(item);
+  }
+  else {               // not empty, append
+    ea_to_jdp(q->tail)->sys.next = jdp_to_ea(item);
+    q->tail = jdp_to_ea(item);
+  }
+
+  smp_wmb();           // orders stores above before clearing of mutex
+  _mutex_unlock(ptr_to_ea(&q->mutex));
+}
+
+gc_job_desc_t *
+gc_jd_queue_dequeue(gc_jd_queue_t *q)
+{
+  _mutex_lock(ptr_to_ea(&q->mutex));
+  smp_rmb();           // import barrier
+  
+  gc_eaddr_t item_ea = q->head;
+  if (item_ea == 0){   // empty
+    _mutex_unlock(ptr_to_ea(&q->mutex));
+    return 0;
+  }
+
+  q->head = ea_to_jdp(item_ea)->sys.next;
+  if (q->head == 0)    // now emtpy
+    q->tail = 0;
+
+  gc_job_desc_t *item = ea_to_jdp(item_ea);
+  item->sys.next = 0;
+
+  smp_wmb();           // orders stores above before clearing of mutex
+  _mutex_unlock(ptr_to_ea(&q->mutex));
+  return item;
+}
diff --git a/gcell/src/lib/runtime/gc_jd_stack.c b/gcell/src/lib/runtime/gc_jd_stack.c
new file mode 100644 (file)
index 0000000..0fffc0d
--- /dev/null
@@ -0,0 +1,108 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_jd_stack.h"
+#include "memory_barrier.h"
+
+
+void 
+gc_jd_stack_init(gc_jd_stack_t *stack)
+{
+  stack->top = 0;
+}
+  
+
+#ifdef __powerpc64__  // 64-bit mode
+
+void 
+gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item)
+{
+  gc_eaddr_t   top;
+  gc_eaddr_t   item_ea = ptr_to_ea(item);
+  unsigned int done;
+
+  do {
+    top = __ldarx(&stack->top);
+    item->sys.next = top;
+    smp_wmb();       // order store of item->next before store of stack->top
+    done = __stdcx(&stack->top, item_ea);
+  } while (unlikely(done == 0));
+}
+
+gc_job_desc_t *
+gc_jd_stack_pop(gc_jd_stack_t *stack)
+{
+  gc_eaddr_t   s;
+  gc_eaddr_t   t;
+  unsigned int done;
+
+  do {
+    s  = __ldarx(&stack->top);
+    if (s == 0)                        /* stack's empty */
+      return 0;
+    t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next;
+    done = __stdcx(&stack->top, t);
+  } while (unlikely(done == 0));
+
+  return ea_to_ptr(s);
+}
+
+#else  // 32-bit mode
+
+/*
+ * In 32-bit mode, gc_eaddr's will have the top 32-bits zero.
+ * The ldarx/stdcx instructions aren't available in 32-bit mode,
+ * thus we use lwarx/stwcx on the low 32-bits of the 64-bit addresses.
+ * Since we're big-endian, the low 32-bits are at word offset 1.
+ */
+void 
+gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item)
+{
+  gc_eaddr_t   top;
+  unsigned int done;
+
+  do {
+    top = __lwarx((int32_t *)(&stack->top) + 1);
+    item->sys.next = top;
+    smp_wmb();       // order store of item->sys.next before store of stack->top
+    done = __stwcx((int32_t *)(&stack->top) + 1, item);
+  } while (unlikely(done == 0));
+}
+
+gc_job_desc_t *
+gc_jd_stack_pop(gc_jd_stack_t *stack)
+{
+  gc_eaddr_t   s;
+  gc_eaddr_t   t;
+  unsigned int done;
+
+  do {
+    s  = __lwarx((int32_t *)(&stack->top) + 1);
+    if (s == 0)                        /* stack's empty */
+      return 0;
+    t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next;
+    done = __stwcx((int32_t *)(&stack->top) + 1, (uint32_t) t);
+  } while (unlikely(done == 0));
+
+  return ea_to_ptr(s);
+}
+
+#endif
diff --git a/gcell/src/lib/runtime/gc_job_manager.cc b/gcell/src/lib/runtime/gc_job_manager.cc
new file mode 100644 (file)
index 0000000..edb52a5
--- /dev/null
@@ -0,0 +1,54 @@
+/* -*- 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 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 "gc_job_manager.h"
+#include "gc_job_manager_impl.h"
+
+gc_job_manager *
+gc_make_job_manager(const gc_jm_options *options)
+{
+  return new gc_job_manager_impl(options);
+}
+
+gc_job_manager::gc_job_manager(const gc_jm_options *options)
+{
+  // nop
+}
+
+gc_job_manager::~gc_job_manager()
+{
+  // nop
+}
+
+void
+gc_job_manager::set_debug(int debug)
+{
+  // nop
+}
+
+int
+gc_job_manager::debug()
+{
+  return 0;
+}
diff --git a/gcell/src/lib/runtime/gc_job_manager.h b/gcell/src/lib/runtime/gc_job_manager.h
new file mode 100644 (file)
index 0000000..9c8e70b
--- /dev/null
@@ -0,0 +1,171 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JOB_MANAGER_H
+#define INCLUDED_GC_JOB_MANAGER_H
+
+#include <boost/utility.hpp>
+#include <vector>
+#include <string>
+#include <libspe2.h>
+#include "gc_job_desc.h"
+
+class gc_job_manager;
+
+enum gc_wait_mode {
+  GC_WAIT_ANY,
+  GC_WAIT_ALL,
+};
+
+/*
+ * \brief Options that configure the job_manager.
+ * The default values are reasonable.
+ */
+struct gc_jm_options {
+  unsigned int max_jobs;           // max # of job descriptors in system
+  unsigned int max_client_threads;  // max # of client threads of job manager
+  unsigned int nspes;              // how many SPEs shall we use? 0 -> all of them
+  bool gang_schedule;              // shall we gang schedule?
+  bool use_affinity;               // shall we try for affinity (FIXME not implmented)
+  bool enable_logging;             // shall we log SPE events?
+  uint32_t log2_nlog_entries;           // log2 of number of log entries (default is 12 == 4k)
+  spe_program_handle_t *program_handle;  // program to load into SPEs
+
+  gc_jm_options() :
+    max_jobs(0), max_client_threads(0), nspes(0),
+    gang_schedule(true), use_affinity(false),
+    enable_logging(false), log2_nlog_entries(12),
+    program_handle(0)
+  {
+  }
+};
+
+
+/*
+ * \brief Create an instance of the job manager
+ */
+gc_job_manager *
+gc_make_job_manager(const gc_jm_options *options = 0);
+
+
+/*!
+ * \brief Abstract class that manages SPE jobs.
+ *
+ * There is typically a single instance derived from this class.
+ * It is safe to call its methods from any thread.
+ */
+class gc_job_manager : boost::noncopyable
+{
+public:
+  gc_job_manager(const gc_jm_options *options = 0); 
+
+  virtual ~gc_job_manager();
+
+  /*!
+   * Stop accepting new jobs.  Wait for existing jobs to complete.
+   * Return all managed SPE's to the system.
+   */
+  virtual bool shutdown() = 0;
+
+  /*!
+   * \brief Return number of SPE's currently allocated to job manager.
+   */
+  virtual int nspes() const = 0;
+
+  /*!
+   * \brief Return a pointer to a properly aligned job descriptor,
+   * or zero if none are available.
+   */
+  virtual gc_job_desc *alloc_job_desc() = 0;
+
+  /*
+   *! Free a job descriptor previously allocated with alloc_job_desc()
+   *
+   * \param[in] jd pointer to job descriptor to free.
+   */
+  virtual void free_job_desc(gc_job_desc *jd) = 0;
+
+  /*!
+   * \brief Submit a job for asynchronous processing on an SPE.
+   *
+   * \param[in] jd pointer to job description
+   *
+   * The caller must not read or write the job description
+   * or any of the memory associated with any indirect arguments
+   * until after calling wait_job.
+   *
+   * \returns true iff the job was successfully enqueued.
+   * If submit_job returns false, check jd->status for additional info.
+   */
+  virtual bool submit_job(gc_job_desc *jd) = 0;
+
+  /*!
+   * \brief Wait for job to complete.
+   *
+   * A thread may only wait for jobs which it submitted.
+   *
+   * \returns true if sucessful, else false.
+   */
+  virtual bool 
+  wait_job(gc_job_desc *jd) = 0;
+
+  /*!
+   * \brief wait for 1 or more jobs to complete.
+   *
+   * \param[input] njobs is the length of arrays \p jd and \p done.
+   * \param[input] jd are the jobs that are to be waited for.
+   * \param[output] done indicates whether the corresponding job is complete.
+   * \param[input] mode indicates whether to wait for ALL or ANY of the jobs
+   *   in \p jd to complete.
+   *
+   * A thread may only wait for jobs which it submitted.
+   *
+   * \returns number of jobs completed, or -1 if error.
+   */
+  virtual int
+  wait_jobs(unsigned int njobs,
+           gc_job_desc *jd[], bool done[], gc_wait_mode mode) = 0;
+
+  /*!
+   * Return the maximum number of bytes of EA arguments that may be
+   * copied to or from the SPE in a single job.  The limit applies
+   * independently to the "get" and "put" args.  
+   * \sa gc_job_desc_t, gc_job_ea_args_t
+   */
+  virtual int ea_args_maxsize() = 0;
+
+  /*!
+   * Return gc_proc_id_t associated with spu procedure \p proc_name if one
+   * exists, otherwise return GCP_UNKNOWN_PROC.
+   */
+  virtual gc_proc_id_t lookup_proc(const std::string &proc_name) = 0;
+  
+  /*!
+   * Return a vector of all known spu procedure names.
+   */
+  virtual std::vector<std::string> proc_names() = 0;
+
+  virtual void set_debug(int debug);
+  virtual int debug();
+};
+
+
+#endif /* INCLUDED_GC_JOB_MANAGER_H */
diff --git a/gcell/src/lib/runtime/gc_job_manager_impl.cc b/gcell/src/lib/runtime/gc_job_manager_impl.cc
new file mode 100644 (file)
index 0000000..13d8f0d
--- /dev/null
@@ -0,0 +1,1274 @@
+/* -*- 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 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 <gc_job_manager_impl.h>
+#include <gc_mbox.h>
+#include <gc_proc_def_utils.h>
+
+#include <stdio.h>
+#include <stdexcept>
+#include <stdlib.h>
+#include <atomic_dec_if_positive.h>
+#include <memory_barrier.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+static const size_t CACHE_LINE_SIZE = 128;
+
+static const unsigned int DEFAULT_MAX_JOBS = 128;
+static const unsigned int DEFAULT_MAX_CLIENT_THREADS = 64;
+
+// FIXME this really depends on the SPU code...
+static const unsigned int MAX_TOTAL_INDIRECT_LENGTH = 16 * 1024;
+
+
+static bool          s_key_initialized = false;
+static pthread_key_t s_client_key;
+
+static int s_worker_debug = 0;
+
+// custom deleter of gang_contexts for use with boost::shared_ptr
+class gang_deleter {
+public:
+  void operator()(spe_gang_context_ptr_t ctx) {
+    if (ctx){
+      int r = spe_gang_context_destroy(ctx);
+      if (r != 0){
+       perror("spe_gang_context_destroy");
+      }
+    }
+  }
+};
+
+// custom deleter
+class spe_program_handle_deleter {
+public:
+  void operator()(spe_program_handle_t *program) {
+    if (program){
+      int r = spe_image_close(program);
+      if (r != 0){
+       perror("spe_image_close");
+      }
+    }
+  }
+};
+
+
+// custom deleter of anything that can be freed with "free"
+class free_deleter {
+public:
+  void operator()(void *p) {
+    free(p);
+  }
+};
+
+
+/*
+ * Called when client thread is destroyed.
+ * We mark our client info free.
+ */
+static void
+client_key_destructor(void *p)
+{
+  ((gc_client_thread_info *) p)->d_free = 1;
+}
+
+/*
+ * Return pointer to cache-aligned chunk of storage of size size bytes.
+ * Throw if can't allocate memory.  The storage should be freed
+ * with "free" when done.  The memory is initialized to zero.
+ */
+static void *
+aligned_alloc(size_t size, size_t alignment = CACHE_LINE_SIZE)
+{
+  void *p = 0;
+  if (posix_memalign(&p, alignment, size) != 0){
+    perror("posix_memalign");
+    throw std::runtime_error("memory");
+  }
+  memset(p, 0, size);          // zero the memory
+  return p;
+}
+
+static bool
+is_power_of_2(uint32_t x)
+{
+  return (x != 0) && !(x & (x - 1));
+}
+
+////////////////////////////////////////////////////////////////////////
+
+
+gc_job_manager_impl::gc_job_manager_impl(const gc_jm_options *options)
+  : d_debug(0), d_spu_args(0),
+    d_eh_cond(&d_eh_mutex), d_eh_thread(0), d_eh_state(EHS_INIT),
+    d_shutdown_requested(false),
+    d_client_thread(0), d_ea_args_maxsize(0),
+    d_proc_def(0), d_proc_def_ls_addr(0), d_nproc_defs(0)
+{
+  if (!s_key_initialized){
+    int r = pthread_key_create(&s_client_key, client_key_destructor);
+    if (r != 0)
+      throw std::runtime_error("pthread_key_create");
+    s_key_initialized = true;
+  }
+
+  // ensure it's zero
+  pthread_setspecific(s_client_key, 0);
+
+  if (options != 0)
+    d_options = *options;
+
+  // provide the real default for those indicated with a zero
+  if (d_options.max_jobs == 0)
+    d_options.max_jobs = DEFAULT_MAX_JOBS;
+  if (d_options.max_client_threads == 0)
+    d_options.max_client_threads = DEFAULT_MAX_CLIENT_THREADS;
+
+  if (d_options.program_handle == 0){
+    fprintf(stderr, "gc_job_manager: options->program_handle must be non-zero\n");
+    throw std::runtime_error("gc_job_manager: options->program_handle must be non-zero");
+  }
+
+  int ncpu_nodes = spe_cpu_info_get(SPE_COUNT_PHYSICAL_CPU_NODES, -1);
+  int nusable_spes = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, -1);
+
+  if (debug()){
+    printf("cpu_nodes = %d\n", ncpu_nodes);
+    for (int i = 0; i < ncpu_nodes; i++){
+      printf("node[%d].physical_spes = %2d\n", i,
+            spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, i));
+      printf("node[%d].usable_spes   = %2d\n", i,
+            spe_cpu_info_get(SPE_COUNT_USABLE_SPES, i));
+    }
+  }
+
+  // clamp nspes
+  d_options.nspes = std::min(d_options.nspes, (unsigned int) MAX_SPES);
+  nusable_spes = std::min(nusable_spes, (int) MAX_SPES);
+
+  //
+  // sanity check requested number of spes.
+  //
+  if (d_options.nspes == 0)    // use all of them
+    d_options.nspes = nusable_spes;
+  else {
+    if (d_options.nspes > (unsigned int) nusable_spes){
+      fprintf(stderr,
+             "gc_job_manager: warning: caller requested %d spes.  There are only %d available.\n",
+             d_options.nspes, nusable_spes);
+      if (d_options.gang_schedule){
+       // If we're gang scheduling we'll never get scheduled if we
+       // ask for more than are available.
+       throw std::out_of_range("gang_scheduling: not enough spes available");
+      }
+      else {   // FIXME clamp to usable.  problem on PS3 when overcommited
+       fprintf(stderr, "gc_job_manager: clamping nspes to %d\n", nusable_spes);
+       d_options.nspes = nusable_spes;
+      }
+    }
+  }
+
+  if (d_options.use_affinity){
+    printf("gc_job_manager: warning: affinity request was ignored\n");
+  }
+
+  if (d_options.gang_schedule){
+    d_gang = spe_gang_context_sptr(spe_gang_context_create(0), gang_deleter());
+    if (!d_gang){
+      perror("gc_job_manager_impl[spe_gang_context_create]");
+      throw std::runtime_error("spe_gang_context_create");
+    }
+  }
+
+  // ----------------------------------------------------------------
+  // initalize the job queue
+  
+  d_queue = (gc_jd_queue_t *) aligned_alloc(sizeof(gc_jd_queue_t));
+  _d_queue_boost =
+    boost::shared_ptr<void>((void *) d_queue, free_deleter());
+  gc_jd_queue_init(d_queue);
+
+
+  // ----------------------------------------------------------------
+  // create the spe contexts
+
+  // 1 spu_arg struct for each SPE
+  assert(sizeof(gc_spu_args_t) % 16 == 0);
+  d_spu_args =
+    (gc_spu_args_t *) aligned_alloc(MAX_SPES * sizeof(gc_spu_args_t), 16);
+  _d_spu_args_boost =
+    boost::shared_ptr<void>((void *) d_spu_args, free_deleter());
+
+  // 2 completion info structs for each SPE (we double buffer them)
+  assert(sizeof(gc_comp_info_t) % CACHE_LINE_SIZE == 0);
+  d_comp_info =
+    (gc_comp_info_t *) aligned_alloc(2 * MAX_SPES * sizeof(gc_comp_info_t),
+                                    CACHE_LINE_SIZE);
+  _d_comp_info_boost =
+    boost::shared_ptr<void>((void *) d_comp_info, free_deleter());
+
+
+  // get a handle to the spe program
+
+  spe_program_handle_t *spe_image = d_options.program_handle;
+
+  // fish proc_def table out of SPE ELF file
+
+  if (!gcpd_find_table(spe_image, &d_proc_def, &d_nproc_defs, &d_proc_def_ls_addr)){
+    fprintf(stderr, "gc_job_manager_impl: couldn't find gc_proc_defs in SPE ELF file.\n");
+    throw std::runtime_error("no gc_proc_defs");
+  }
+  // fprintf(stderr, "d_proc_def_ls_addr = 0x%0x\n", d_proc_def_ls_addr);
+
+  int spe_flags = (SPE_EVENTS_ENABLE
+                  | SPE_CFG_SIGNOTIFY1_OR
+                  | SPE_CFG_SIGNOTIFY2_OR);
+  
+  for (unsigned int i = 0; i < d_options.nspes; i++){
+    // FIXME affinity stuff goes here
+    d_worker[i].spe_ctx = spe_context_create(spe_flags, d_gang.get());;
+    if (d_worker[i].spe_ctx == 0){
+      perror("spe_context_create");
+      throw std::runtime_error("spe_context_create");
+    }
+    d_worker[i].spe_idx = i;
+    d_worker[i].spu_args = &d_spu_args[i];
+    d_worker[i].spu_args->queue = ptr_to_ea(d_queue);
+    d_worker[i].spu_args->comp_info[0] = ptr_to_ea(&d_comp_info[2*i+0]);
+    d_worker[i].spu_args->comp_info[1] = ptr_to_ea(&d_comp_info[2*i+1]);
+    d_worker[i].spu_args->spu_idx = i;
+    d_worker[i].spu_args->nspus = d_options.nspes;
+    d_worker[i].spu_args->proc_def_ls_addr = d_proc_def_ls_addr;
+    d_worker[i].spu_args->nproc_defs = d_nproc_defs;
+    d_worker[i].spu_args->log.base = 0;
+    d_worker[i].spu_args->log.nentries = 0;
+    d_worker[i].state = WS_INIT;
+
+    int r = spe_program_load(d_worker[i].spe_ctx, spe_image);
+    if (r != 0){
+      perror("spe_program_load");
+      throw std::runtime_error("spe_program_load");
+    }
+  }
+
+  setup_logfiles();
+
+  // ----------------------------------------------------------------
+  // initalize the free list of job descriptors
+  
+  d_free_list = (gc_jd_stack_t *) aligned_alloc(sizeof(gc_jd_stack_t));
+  // This ensures that the memory associated with d_free_list is
+  // automatically freed in the destructor or if an exception occurs
+  // here in the constructor.
+  _d_free_list_boost =
+    boost::shared_ptr<void>((void *) d_free_list, free_deleter());
+  gc_jd_stack_init(d_free_list);
+
+  if (debug()){
+    printf("sizeof(d_jd[0]) = %d (0x%x)\n", sizeof(d_jd[0]), sizeof(d_jd[0]));
+    printf("max_jobs = %u\n", d_options.max_jobs);
+  }
+
+  // Initialize the array of job descriptors.
+  d_jd = (gc_job_desc_t *) aligned_alloc(sizeof(d_jd[0]) * d_options.max_jobs);
+  _d_jd_boost = boost::shared_ptr<void>((void *) d_jd, free_deleter());
+
+
+  // set unique job_id
+  for (int i = 0; i < (int) d_options.max_jobs; i++)
+    d_jd[i].sys.job_id = i;
+
+  // push them onto the free list
+  for (int i = d_options.max_jobs - 1; i >= 0; i--)
+    free_job_desc(&d_jd[i]);
+
+  // ----------------------------------------------------------------
+  // initialize d_client_thread
+
+  {
+    gc_client_thread_info_sa cti(
+         new gc_client_thread_info[d_options.max_client_threads]);
+
+    d_client_thread.swap(cti);
+
+    for (unsigned int i = 0; i < d_options.max_client_threads; i++)
+      d_client_thread[i].d_client_id = i;
+  }
+
+  // ----------------------------------------------------------------
+  // initialize bitvectors
+
+  // initialize d_bvlen, the number of longs in job related bitvectors.
+  int bits_per_long = sizeof(unsigned long) * 8;
+  d_bvlen = (d_options.max_jobs + bits_per_long - 1) / bits_per_long;
+
+  // allocate all bitvectors in a single cache-aligned chunk
+  size_t nlongs = d_bvlen * d_options.max_client_threads;
+  void *p = aligned_alloc(nlongs * sizeof(unsigned long));
+  _d_all_bitvectors = boost::shared_ptr<void>(p, free_deleter());
+
+  // Now point the gc_client_thread_info bitvectors into this storage
+  unsigned long *v = (unsigned long *) p;
+
+  for (unsigned int i = 0; i < d_options.max_client_threads; i++, v += d_bvlen)
+    d_client_thread[i].d_jobs_done = v;
+
+
+  // ----------------------------------------------------------------
+  // create the spe event handler & worker (SPE) threads
+
+  create_event_handler();
+
+}
+
+////////////////////////////////////////////////////////////////////////
+
+gc_job_manager_impl::~gc_job_manager_impl()
+{
+  shutdown();
+
+  d_jd = 0;            // handled via _d_jd_boost
+  d_free_list = 0;     // handled via _d_free_list_boost
+  d_queue = 0;         // handled via _d_queue_boost
+
+  // clear cti, since we've deleted the underlying data
+  pthread_setspecific(s_client_key, 0);
+
+  unmap_logfiles();
+}
+
+bool
+gc_job_manager_impl::shutdown()
+{
+  omni_mutex_lock      l(d_eh_mutex);
+
+  d_shutdown_requested = true;         // set flag for event handler thread
+
+  // should only happens during early QA code
+  if (d_eh_thread == 0 && d_eh_state == EHS_INIT)
+    return false;
+
+  while (d_eh_state != EHS_DEAD)       // wait for it to finish
+    d_eh_cond.wait();
+
+  return true;
+}
+
+int
+gc_job_manager_impl::nspes() const
+{
+  return d_options.nspes;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void
+gc_job_manager_impl::bv_zero(unsigned long *bv)
+{
+  memset(bv, 0, sizeof(unsigned long) * d_bvlen);
+}
+
+inline void
+gc_job_manager_impl::bv_clr(unsigned long *bv, unsigned int bitno)
+{
+  unsigned int wi = bitno / (sizeof (unsigned long) * 8);
+  unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1);
+  bv[wi] &= ~(1UL << bi);
+}
+
+inline void
+gc_job_manager_impl::bv_set(unsigned long *bv, unsigned int bitno)
+{
+  unsigned int wi = bitno / (sizeof (unsigned long) * 8);
+  unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1);
+  bv[wi] |= (1UL << bi);
+}
+
+inline bool
+gc_job_manager_impl::bv_isset(unsigned long *bv, unsigned int bitno)
+{
+  unsigned int wi = bitno / (sizeof (unsigned long) * 8);
+  unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1);
+  return (bv[wi] & (1UL << bi)) != 0;
+}
+
+inline bool
+gc_job_manager_impl::bv_isclr(unsigned long *bv, unsigned int bitno)
+{
+  unsigned int wi = bitno / (sizeof (unsigned long) * 8);
+  unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1);
+  return (bv[wi] & (1UL << bi)) == 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+gc_job_desc *
+gc_job_manager_impl::alloc_job_desc()
+{
+  // stack is lock free, thus safe to call from any thread
+  return gc_jd_stack_pop(d_free_list);
+}
+
+void
+gc_job_manager_impl::free_job_desc(gc_job_desc *jd)
+{
+  // stack is lock free, thus safe to call from any thread
+  if (jd != 0)
+    gc_jd_stack_push(d_free_list, jd);
+}
+
+////////////////////////////////////////////////////////////////////////
+
+/*
+ * We check as much as we can here on the PPE side, so that the SPE
+ * doesn't have to.
+ */
+static bool
+check_direct_args(gc_job_desc *jd, gc_job_direct_args *args)
+{
+  if (args->nargs > MAX_ARGS_DIRECT){
+    jd->status = JS_BAD_N_DIRECT;
+    return false;
+  }
+
+  return true;
+}
+
+static bool
+check_ea_args(gc_job_desc *jd, gc_job_ea_args *p)
+{
+  if (p->nargs > MAX_ARGS_EA){
+    jd->status = JS_BAD_N_EA;
+    return false;
+  }
+
+  uint32_t dir_union = 0;
+
+  for (unsigned int i = 0; i < p->nargs; i++){
+    dir_union |= p->arg[i].direction;
+    switch(p->arg[i].direction){
+    case GCJD_DMA_GET:
+    case GCJD_DMA_PUT:
+      break;
+
+    default:
+      jd->status = JS_BAD_DIRECTION;
+      return false;
+    }
+  }
+
+  if (p->nargs > 1){
+    unsigned int common_eah = (p->arg[0].ea_addr) >> 32;
+    for (unsigned int i = 1; i < p->nargs; i++){
+      if ((p->arg[i].ea_addr >> 32) != common_eah){
+       jd->status = JS_BAD_EAH;
+       return false;
+      }
+    }
+  }
+
+  jd->sys.direction_union = dir_union;
+  return true;
+}
+
+bool
+gc_job_manager_impl::submit_job(gc_job_desc *jd)
+{
+  if (unlikely(d_shutdown_requested)){
+    jd->status = JS_SHUTTING_DOWN;
+    return false;
+  }
+
+  // Ensure it's one of our job descriptors
+
+  if (jd < d_jd || jd >= &d_jd[d_options.max_jobs]){
+    jd->status = JS_BAD_JOB_DESC;
+    return false;
+  }
+
+  // Ensure we've got a client_thread_info assigned to this thread.
+  
+  gc_client_thread_info *cti =
+    (gc_client_thread_info *) pthread_getspecific(s_client_key);
+  if (unlikely(cti == 0)){
+    if ((cti = alloc_cti()) == 0){
+      fprintf(stderr, "gc_job_manager_impl::submit_job: Too many client threads.\n");
+      jd->status = JS_TOO_MANY_CLIENTS;
+      return false;
+    }
+    int r = pthread_setspecific(s_client_key, cti);
+    if (r != 0){
+      jd->status = JS_BAD_JUJU;
+      fprintf(stderr, "pthread_setspecific failed (return = %d)\n", r);
+      return false;
+    }
+  }
+
+  if (jd->proc_id == GCP_UNKNOWN_PROC){
+    jd->status = JS_UNKNOWN_PROC;
+    return false;
+  }
+
+  if (!check_direct_args(jd, &jd->input))
+    return false;
+
+  if (!check_direct_args(jd, &jd->output))
+    return false;
+
+  if (!check_ea_args(jd, &jd->eaa))
+    return false;
+
+  jd->status = JS_OK;
+  jd->sys.client_id = cti->d_client_id;
+
+  // FIXME keep count of jobs in progress?
+  
+  gc_jd_queue_enqueue(d_queue, jd);
+  return true;
+}
+
+bool
+gc_job_manager_impl::wait_job(gc_job_desc *jd)
+{
+  bool done;
+  return wait_jobs(1, &jd, &done, GC_WAIT_ANY) == 1;
+}
+
+int
+gc_job_manager_impl::wait_jobs(unsigned int njobs,
+                              gc_job_desc *jd[],
+                              bool done[],
+                              gc_wait_mode mode)
+{
+  unsigned int i;
+
+  gc_client_thread_info *cti =
+    (gc_client_thread_info *) pthread_getspecific(s_client_key);
+  if (unlikely(cti == 0))
+    return -1;
+
+  for (i = 0; i < njobs; i++){
+    done[i] = false;
+    if (unlikely(jd[i]->sys.client_id != cti->d_client_id)){
+      fprintf(stderr, "gc_job_manager_impl::wait_jobs: can't wait for a job you didn't submit\n");
+      return -1;
+    }
+  }
+
+  {
+    omni_mutex_lock    l(cti->d_mutex);
+
+    // setup info for event handler
+    cti->d_state = (mode == GC_WAIT_ANY) ? CT_WAIT_ANY : CT_WAIT_ALL;
+    cti->d_njobs_waiting_for = njobs;
+    cti->d_jobs_waiting_for = jd;
+    assert(cti->d_jobs_done != 0);
+
+    unsigned int ndone = 0;
+
+    // wait for jobs to complete
+    
+    while (1){
+      ndone = 0;
+      for (i= 0; i < njobs; i++){
+       if (done[i])
+         ndone++;
+       else if (bv_isset(cti->d_jobs_done, jd[i]->sys.job_id)){
+         bv_clr(cti->d_jobs_done, jd[i]->sys.job_id);
+         done[i] = true;
+         ndone++;
+       }
+      }
+
+      if (mode == GC_WAIT_ANY && ndone > 0)
+       break;
+
+      if (mode == GC_WAIT_ALL && ndone == njobs)
+       break;
+
+      // FIXME what happens when somebody calls shutdown?
+
+      cti->d_cond.wait();      // wait for event handler to wake us up
+    }
+
+    cti->d_state = CT_NOT_WAITING;  
+    cti->d_njobs_waiting_for = 0;      // tidy up (not reqd)
+    cti->d_jobs_waiting_for = 0;       // tidy up (not reqd)
+    return ndone;
+  }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+bool
+gc_job_manager_impl::send_all_spes(uint32_t msg)
+{
+  bool ok = true;
+
+  for (unsigned int i = 0; i < d_options.nspes; i++)
+    ok &= send_spe(i, msg);
+
+  return ok;
+}
+
+bool
+gc_job_manager_impl::send_spe(unsigned int spe, uint32_t msg)
+{
+  if (spe >= d_options.nspes)
+    return false;
+
+  int r = spe_in_mbox_write(d_worker[spe].spe_ctx, &msg, 1,
+                           SPE_MBOX_ALL_BLOCKING);
+  if (r < 0){
+    perror("spe_in_mbox_write");
+    return false;
+  }
+
+  return r == 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+static void
+pthread_create_failure_msg(int r, const char *which)
+{
+  char buf[256];
+  char *s = 0;
+
+  switch (r){
+  case EAGAIN: s = "EAGAIN"; break;
+  case EINVAL: s = "EINVAL"; break;
+  case EPERM:  s = "EPERM";  break;
+  default:
+    snprintf(buf, sizeof(buf), "Unknown error %d", r);
+    s = buf;
+    break;
+  }
+  fprintf(stderr, "pthread_create[%s] failed: %s\n", which, s);
+}
+
+
+static bool
+start_thread(pthread_t *thread,
+            void *(*start_routine)(void *),  void *arg,
+            const char *msg)
+{
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+  // FIXME save sigprocmask
+  // FIXME set sigprocmask
+
+  int r = pthread_create(thread, &attr, start_routine, arg);
+    
+  // FIXME restore sigprocmask
+
+  if (r != 0){
+    pthread_create_failure_msg(r, msg);
+    return false;
+  }
+  return true;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+
+static void *start_worker(void *arg);
+
+static void *
+start_event_handler(void *arg)
+{
+  gc_job_manager_impl *p = (gc_job_manager_impl *) arg;
+  p->event_handler_loop();
+  return 0;
+}
+
+void
+gc_job_manager_impl::create_event_handler()
+{
+  // create the SPE event handler and register our interest in events
+
+  d_spe_event_handler.ptr = spe_event_handler_create();
+  if (d_spe_event_handler.ptr == 0){
+    perror("spe_event_handler_create");
+    throw std::runtime_error("spe_event_handler_create");
+  }
+
+  for (unsigned int i = 0; i < d_options.nspes; i++){
+    spe_event_unit_t   eu;
+    memset(&eu, 0, sizeof(eu));
+    eu.events = SPE_EVENT_OUT_INTR_MBOX | SPE_EVENT_SPE_STOPPED;
+    eu.spe = d_worker[i].spe_ctx;
+    eu.data.u32 = i;   // set in events returned by spe_event_wait
+
+    if (spe_event_handler_register(d_spe_event_handler.ptr, &eu) != 0){
+      perror("spe_event_handler_register");
+      throw std::runtime_error("spe_event_handler_register");
+    }
+  }
+
+  // create our event handling thread
+
+  if (!start_thread(&d_eh_thread, start_event_handler, this, "event_handler")){
+    throw std::runtime_error("pthread_create");
+  }
+
+  // create the SPE worker threads
+
+  bool ok = true;
+  for (unsigned int i = 0; ok && i < d_options.nspes; i++){
+    char name[256];
+    snprintf(name, sizeof(name), "worker[%d]", i);
+    ok &= start_thread(&d_worker[i].thread, start_worker,
+                      &d_worker[i], name);
+  }
+
+  if (!ok){
+    //
+    // FIXME Clean up the mess.  Need to terminate event handler and all workers.
+    //
+    // this should cause the workers to exit, unless they're seriously broken
+    send_all_spes(MK_MBOX_MSG(OP_EXIT, 0));
+
+    shutdown();
+
+    throw std::runtime_error("pthread_create");
+  }
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void
+gc_job_manager_impl::set_eh_state(evt_handler_state s)
+{
+  omni_mutex_lock      l(d_eh_mutex);
+  d_eh_state = s;
+  d_eh_cond.broadcast();
+}
+
+void
+gc_job_manager_impl::set_ea_args_maxsize(int maxsize)
+{
+  omni_mutex_lock      l(d_eh_mutex);
+  d_ea_args_maxsize = maxsize;
+  d_eh_cond.broadcast();
+}
+
+void
+gc_job_manager_impl::print_event(spe_event_unit_t *evt)
+{
+  printf("evt: spe = %d events = (0x%x)", evt->data.u32, evt->events);
+
+  if (evt->events & SPE_EVENT_OUT_INTR_MBOX)
+    printf(" OUT_INTR_MBOX");
+  
+  if (evt->events & SPE_EVENT_IN_MBOX)
+    printf(" IN_MBOX");
+  
+  if (evt->events & SPE_EVENT_TAG_GROUP)
+    printf(" TAG_GROUP");
+  
+  if (evt->events & SPE_EVENT_SPE_STOPPED)
+    printf(" SPE_STOPPED");
+
+  printf("\n");
+}
+
+struct job_client_info {
+  uint16_t     job_id;
+  uint16_t     client_id;
+};
+
+static int
+compare_jci_clients(const void *va, const void *vb)
+{
+  const job_client_info *a = (job_client_info *) va;
+  const job_client_info *b = (job_client_info *) vb;
+
+  return a->client_id - b->client_id;
+}
+
+void
+gc_job_manager_impl::notify_clients_jobs_are_done(unsigned int spe_num,
+                                                 unsigned int completion_info_idx)
+{
+  const char *msg = "gc_job_manager_impl::notify_client_job_is_done (INTERNAL ERROR)";
+
+  smp_rmb();  // order reads so we know that data sent from SPE is here
+
+  gc_comp_info_t *ci = &d_comp_info[2 * spe_num + (completion_info_idx & 0x1)];
+
+  if (ci->ncomplete == 0){     // never happens, but ensures code below is correct
+    ci->in_use = 0;
+    return;
+  }
+
+  if (0){
+    static int total_jobs;
+    static int total_msgs;
+    total_msgs++;
+    total_jobs += ci->ncomplete;
+    printf("ppe:     tj = %6d  tm = %6d\n", total_jobs, total_msgs);
+  }
+
+  job_client_info gci[GC_CI_NJOBS];
+
+  /*
+   * Make one pass through and sanity check everything while filling in gci
+   */
+  for (unsigned int i = 0; i < ci->ncomplete; i++){
+    unsigned int job_id = ci->job_id[i];
+
+    if (job_id >= d_options.max_jobs){
+      // internal error, shouldn't happen
+      fprintf(stderr,"%s: invalid job_id = %d\n", msg, job_id);
+      ci->in_use = 0;          // clear flag so SPE knows we're done with it
+      return;
+    }
+    gc_job_desc *jd = &d_jd[job_id];
+
+    if (jd->sys.client_id >= d_options.max_client_threads){
+      // internal error, shouldn't happen
+      fprintf(stderr, "%s: invalid client_id = %d\n", msg, jd->sys.client_id);
+      ci->in_use = 0;          // clear flag so SPE knows we're done with it
+      return;
+    }
+
+    gci[i].job_id = job_id;
+    gci[i].client_id = jd->sys.client_id;
+  }
+
+  // sort by client_id so we only have to lock & signal once / client
+
+  if (ci->ncomplete > 1)
+    qsort(gci, ci->ncomplete, sizeof(gci[0]), compare_jci_clients);
+
+  // "wind-in" 
+
+  gc_client_thread_info *last_cti = &d_client_thread[gci[0].client_id];
+  last_cti->d_mutex.lock();
+  bv_set(last_cti->d_jobs_done, gci[0].job_id);  // mark job done
+
+  for (unsigned int i = 1; i < ci->ncomplete; i++){
+
+    gc_client_thread_info *cti = &d_client_thread[gci[i].client_id];
+
+    if (cti != last_cti){      // new client?
+
+      // yes.  signal old client, unlock old, lock new
+
+      // FIXME we could distinguish between CT_WAIT_ALL & CT_WAIT_ANY
+
+      if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL)
+       last_cti->d_cond.signal();      // wake client thread up
+
+      last_cti->d_mutex.unlock();
+      cti->d_mutex.lock();
+      last_cti = cti;
+    }
+
+    // mark job done
+    bv_set(cti->d_jobs_done, gci[i].job_id);
+  }
+
+  // "wind-out"
+
+  if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL)
+    last_cti->d_cond.signal(); // wake client thread up
+  last_cti->d_mutex.unlock();
+
+  ci->in_use = 0;              // clear flag so SPE knows we're done with it
+}
+
+void
+gc_job_manager_impl::handle_event(spe_event_unit_t *evt)
+{
+  // print_event(evt);
+
+  int spe_num = evt->data.u32;
+
+  // only a single event type can be signaled at a time
+  
+  if (evt->events == SPE_EVENT_OUT_INTR_MBOX) { // SPE sent us 1 or more msgs
+    static const int NMSGS = 32;
+    unsigned int msg[NMSGS];
+    int n = spe_out_intr_mbox_read(evt->spe, msg, NMSGS, SPE_MBOX_ANY_BLOCKING);
+    // printf("spe_out_intr_mbox_read = %d\n", n);
+    if (n < 0){
+      perror("spe_out_intr_mbox_read");
+    }
+    else {
+      for (int i = 0; i < n; i++){
+       switch(MBOX_MSG_OP(msg[i])){
+       case OP_JOBS_DONE:
+         if (debug())
+           printf("eh: job_done (0x%08x) from spu[%d]\n", msg[i], spe_num);
+         notify_clients_jobs_are_done(spe_num, MBOX_MSG_ARG(msg[i]));
+         break;
+
+       case OP_SPU_BUFSIZE:
+         set_ea_args_maxsize(MBOX_MSG_ARG(msg[i]));
+         break;
+
+       case OP_EXIT:
+       default:
+         printf("eh: Unexpected msg (0x%08x) from spu[%d]\n", msg[i], spe_num);
+         break;
+       }
+      }
+    }
+  }
+  else if (evt->events == SPE_EVENT_SPE_STOPPED){ // the SPE stopped
+    spe_stop_info_t si;
+    int r = spe_stop_info_read(evt->spe, &si);
+    if (r < 0){
+      perror("spe_stop_info_read");
+    }
+    else {
+      switch (si.stop_reason){
+      case SPE_EXIT:
+       if (debug()){
+         printf("eh: spu[%d] SPE_EXIT w/ exit_code = %d\n",
+                spe_num, si.result.spe_exit_code);
+       }
+       break;
+      case SPE_STOP_AND_SIGNAL:
+       printf("eh: spu[%d] SPE_STOP_AND_SIGNAL w/ spe_signal_code = 0x%x\n",
+              spe_num, si.result.spe_signal_code);
+       break;
+      case SPE_RUNTIME_ERROR:
+       printf("eh: spu[%d] SPE_RUNTIME_ERROR w/ spe_runtime_error = 0x%x\n",
+              spe_num, si.result.spe_runtime_error);
+       break;
+      case SPE_RUNTIME_EXCEPTION:
+       printf("eh: spu[%d] SPE_RUNTIME_EXCEPTION w/ spe_runtime_exception = 0x%x\n",
+              spe_num, si.result.spe_runtime_exception);
+       break;
+      case SPE_RUNTIME_FATAL:
+       printf("eh: spu[%d] SPE_RUNTIME_FATAL w/ spe_runtime_fatal = 0x%x\n",
+              spe_num, si.result.spe_runtime_fatal);
+       break;
+      case SPE_CALLBACK_ERROR:
+       printf("eh: spu[%d] SPE_CALLBACK_ERROR w/ spe_callback_error = 0x%x\n",
+              spe_num, si.result.spe_callback_error);
+       break;
+      case SPE_ISOLATION_ERROR:
+       printf("eh: spu[%d] SPE_ISOLATION_ERROR w/ spe_isolation_error = 0x%x\n",
+              spe_num, si.result.spe_isolation_error);
+       break;
+      default:
+       printf("eh: spu[%d] UNKNOWN STOP REASON (%d) w/ spu_status = 0x%x\n",
+              spe_num, si.stop_reason, si.spu_status);
+       break;
+      }
+    }
+  }
+#if 0 // not enabled
+  else if (evt->events == SPE_EVENT_IN_MBOX){   // there's room to write to SPE
+    // spe_in_mbox_write (ignore)
+  }
+  else if (evt->events == SPE_EVENT_TAG_GROUP){         // our DMA completed
+    // spe_mfcio_tag_status_read
+  }
+#endif
+  else {
+    fprintf(stderr, "handle_event: unexpected evt->events = 0x%x\n", evt->events);
+    return;
+  }
+}
+
+//
+// This is the "main program" of the event handling thread
+//
+void
+gc_job_manager_impl::event_handler_loop()
+{
+  static const int MAX_EVENTS = 16;
+  static const int TIMEOUT = 20;       // how long to block in milliseconds
+
+  spe_event_unit_t events[MAX_EVENTS];
+
+  if (d_debug)
+    printf("event_handler_loop: starting\n");
+
+  set_eh_state(EHS_RUNNING);
+
+  // ask the first spe for its max bufsize
+  send_spe(0, MK_MBOX_MSG(OP_GET_SPU_BUFSIZE, 0));
+
+  while (1){
+    switch(d_eh_state){
+
+    case EHS_RUNNING:      // normal stuff
+      if (d_shutdown_requested) {
+       set_eh_state(EHS_SHUTTING_DOWN);
+      }
+      break;
+
+    case EHS_SHUTTING_DOWN:
+
+      // FIXME wait until job queue is empty, then tell them to exit
+
+      send_all_spes(MK_MBOX_MSG(OP_EXIT, 0));
+      set_eh_state(EHS_WAITING_FOR_WORKERS_TO_DIE);
+      break;
+
+    case EHS_WAITING_FOR_WORKERS_TO_DIE:
+      {
+       bool all_dead = true;
+       for (unsigned int i = 0; i < d_options.nspes; i++)
+         all_dead &= d_worker[i].state == WS_DEAD;
+
+       if (all_dead){
+         set_eh_state(EHS_DEAD);
+         if (d_debug)
+           printf("event_handler_loop: exiting\n");
+         return;
+       }
+      }
+      break;
+
+    default:
+      set_eh_state(EHS_DEAD);
+      printf("event_handler_loop(default): exiting\n");
+      return;
+    }
+
+    // block waiting for events...
+    int nevents = spe_event_wait(d_spe_event_handler.ptr,
+                                events, MAX_EVENTS, TIMEOUT);
+    if (nevents < 0){
+      perror("spe_wait_event");
+      // FIXME bail?
+    }
+    for (int i = 0; i < nevents; i++){
+      handle_event(&events[i]);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////////
+// This is the top of the SPE worker threads
+
+static void *
+start_worker(void *arg)
+{
+  worker_ctx *w = (worker_ctx *) arg;
+  spe_stop_info_t      si;
+
+  w->state = WS_RUNNING;
+  if (s_worker_debug)
+    printf("worker[%d]: WS_RUNNING\n", w->spe_idx);
+
+  unsigned int entry = SPE_DEFAULT_ENTRY;
+  int r = spe_context_run(w->spe_ctx,  &entry, 0, w->spu_args, 0, &si);
+
+  if (r < 0){                  // error
+    char buf[64];
+    snprintf(buf, sizeof(buf), "worker[%d]: spe_context_run", w->spe_idx);
+    perror(buf);
+  }
+  else if (r == 0){
+    // spe program called exit.
+    if (s_worker_debug)
+      printf("worker[%d]: SPE_EXIT w/ exit_code = %d\n",
+            w->spe_idx, si.result.spe_exit_code);
+  }
+  else {
+    // called stop_and_signal
+    //
+    // I'm not sure we'll ever get here.  I think the event
+    // handler will catch this...
+    printf("worker[%d]: SPE_STOP_AND_SIGNAL w/ spe_signal_code = 0x%x\n",
+          w->spe_idx, si.result.spe_signal_code);
+  }
+
+  // in any event, we're committing suicide now ;)
+  if (s_worker_debug)
+    printf("worker[%d]: WS_DEAD\n", w->spe_idx);
+
+  w->state = WS_DEAD;
+  return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+gc_client_thread_info *
+gc_job_manager_impl::alloc_cti()
+{
+  for (unsigned int i = 0; i < d_options.max_client_threads; i++){
+    if (d_client_thread[i].d_free){
+      // try to atomically grab it
+      if (_atomic_dec_if_positive(ptr_to_ea(&d_client_thread[i].d_free)) == 0){
+       // got it...
+       gc_client_thread_info *cti = &d_client_thread[i];
+       cti->d_state = CT_NOT_WAITING;
+       bv_zero(cti->d_jobs_done);
+       cti->d_njobs_waiting_for = 0;
+       cti->d_jobs_waiting_for = 0;
+       
+       return cti;
+      }
+    }
+  }
+  return 0;
+}
+
+void
+gc_job_manager_impl::free_cti(gc_client_thread_info *cti)
+{
+  assert((size_t) (cti - d_client_thread.get()) < d_options.max_client_threads);
+  cti->d_free = 1;
+}
+
+int
+gc_job_manager_impl::ea_args_maxsize()
+{
+  omni_mutex_lock      l(d_eh_mutex);
+
+  while (d_ea_args_maxsize == 0)       // wait for it to be initialized
+    d_eh_cond.wait();
+
+  return d_ea_args_maxsize;
+}
+
+void
+gc_job_manager_impl::set_debug(int debug)
+{
+  d_debug = debug;
+  s_worker_debug = debug;
+}
+
+int
+gc_job_manager_impl::debug()
+{
+  return d_debug;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+void
+gc_job_manager_impl::setup_logfiles()
+{
+  if (!d_options.enable_logging)
+    return;
+
+  if (d_options.log2_nlog_entries == 0)
+    d_options.log2_nlog_entries = 12;
+
+  // must end up a multiple of the page size
+
+  size_t pagesize = getpagesize();
+  size_t s = (1 << d_options.log2_nlog_entries) * sizeof(gc_log_entry_t);
+  s = ((s + pagesize - 1) / pagesize) * pagesize;
+  size_t nentries = s / sizeof(gc_log_entry_t);
+  assert(is_power_of_2(nentries));
+
+  for (unsigned int i = 0; i < d_options.nspes; i++){
+    char filename[100];
+    snprintf(filename, sizeof(filename), "spu_log.%02d", i);
+    int fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0664);
+    if (fd == -1){
+      perror(filename);
+      return;
+    }
+    lseek(fd, s - 1, SEEK_SET);
+    write(fd, "\0", 1);
+    void *p = mmap(0, s, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+    if (p == MAP_FAILED){
+      perror("gc_job_manager_impl::setup_logfiles: mmap");
+      close(fd);
+      return;
+    }
+    close(fd);
+    memset(p, 0, s);
+    d_spu_args[i].log.base = ptr_to_ea(p);
+    d_spu_args[i].log.nentries = nentries;
+  }
+}
+
+void
+gc_job_manager_impl::sync_logfiles()
+{
+  for (unsigned int i = 0; i < d_options.nspes; i++){
+    if (d_spu_args[i].log.base)
+      msync(ea_to_ptr(d_spu_args[i].log.base),
+           d_spu_args[i].log.nentries * sizeof(gc_log_entry_t),
+           MS_ASYNC);
+  }
+}
+
+void
+gc_job_manager_impl::unmap_logfiles()
+{
+  for (unsigned int i = 0; i < d_options.nspes; i++){
+    if (d_spu_args[i].log.base)
+      munmap(ea_to_ptr(d_spu_args[i].log.base),
+            d_spu_args[i].log.nentries * sizeof(gc_log_entry_t));
+  }
+}
+
+////////////////////////////////////////////////////////////////////////
+//
+// lookup proc names in d_proc_def table
+
+gc_proc_id_t 
+gc_job_manager_impl::lookup_proc(const std::string &proc_name)
+{
+  for (int i = 0; i < d_nproc_defs; i++)
+    if (proc_name == d_proc_def[i].name)
+      return i;
+
+  return GCP_UNKNOWN_PROC;
+}
+
+std::vector<std::string>
+gc_job_manager_impl::proc_names()
+{
+  std::vector<std::string> r;
+  for (int i = 0; i < d_nproc_defs; i++)
+    r.push_back(d_proc_def[i].name);
+
+  return r;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+worker_ctx::~worker_ctx()
+{
+  if (spe_ctx){
+    int r = spe_context_destroy(spe_ctx);
+    if (r != 0){
+      perror("spe_context_destroy");
+    }
+    spe_ctx = 0;
+  }
+  state = WS_FREE;
+}
diff --git a/gcell/src/lib/runtime/gc_job_manager_impl.h b/gcell/src/lib/runtime/gc_job_manager_impl.h
new file mode 100644 (file)
index 0000000..4689784
--- /dev/null
@@ -0,0 +1,253 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef INCLUDED_GC_JOB_MANAGER_IMPL_H
+#define INCLUDED_GC_JOB_MANAGER_IMPL_H
+
+#include "gc_job_manager.h"
+#include "gc_client_thread_info.h"
+#include "gc_jd_stack.h"
+#include "gc_jd_queue.h"
+#include "gc_spu_args.h"
+#include <libspe2.h>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_array.hpp>
+
+typedef boost::shared_ptr<spe_gang_context> spe_gang_context_sptr;
+typedef boost::shared_ptr<spe_program_handle_t> spe_program_handle_sptr;
+typedef boost::scoped_array<gc_client_thread_info> gc_client_thread_info_sa;
+
+
+enum worker_state {
+  WS_FREE,     // not in use
+  WS_INIT,     // allocated and being initialized
+  WS_RUNNING,  // the thread is running
+  WS_DEAD,     // the thread is dead
+};
+
+struct worker_ctx {
+  volatile worker_state        state;
+  unsigned int         spe_idx;        // [0, nspes-1]
+  spe_context_ptr_t    spe_ctx;
+  pthread_t            thread;
+  gc_spu_args_t                *spu_args;      // pointer to 16-byte aligned struct
+
+  worker_ctx()
+    : state(WS_FREE), spe_idx(0), spe_ctx(0),
+      thread(0), spu_args(0) {}
+  ~worker_ctx();
+};
+
+enum evt_handler_state {
+  EHS_INIT,            // being initialized
+  EHS_RUNNING,         // thread is running
+  EHS_SHUTTING_DOWN,   // in process of shutting down everything
+  EHS_WAITING_FOR_WORKERS_TO_DIE,
+  EHS_DEAD,            // thread is dead
+};
+
+struct spe_event_handler {
+  spe_event_handler_ptr_t      ptr;
+
+  spe_event_handler() : ptr(0) {}
+  ~spe_event_handler(){
+    if (ptr){
+      if (spe_event_handler_destroy(ptr) != 0){
+       perror("spe_event_handler_destroy");
+      }
+    }
+  }
+};
+
+
+/*!
+ * \brief Concrete class that manages SPE jobs.
+ *
+ * This class contains all the implementation details.
+ */
+class gc_job_manager_impl : public gc_job_manager
+{
+  enum { MAX_SPES =  16 };
+
+  int                    d_debug;
+  gc_jm_options                  d_options;
+  spe_program_handle_sptr d_spe_image;
+  spe_gang_context_sptr   d_gang;              // boost::shared_ptr
+
+  worker_ctx            d_worker[MAX_SPES];    // SPE ctx, thread, etc
+  gc_spu_args_t                *d_spu_args;            // 16-byte aligned structs
+  boost::shared_ptr<void> _d_spu_args_boost;   // hack for automatic storage mgmt
+
+  gc_comp_info_t       *d_comp_info;           // 128-byte aligned structs
+  boost::shared_ptr<void> _d_comp_info_boost;  // hack for automatic storage mgmt
+
+  // used to coordinate communication w/ the event handling thread
+  omni_mutex            d_eh_mutex;
+  omni_condition        d_eh_cond;
+  pthread_t             d_eh_thread;           // the event handler thread
+  volatile evt_handler_state   d_eh_state;
+  volatile bool                        d_shutdown_requested;
+  spe_event_handler     d_spe_event_handler;
+  
+
+  // All of the job descriptors are hung off of here.
+  // We allocate them all in a single cache aligned chunk.
+  gc_job_desc_t                *d_jd;                  // [options.max_jobs]
+  boost::shared_ptr<void> _d_jd_boost;         // hack for automatic storage mgmt
+
+  gc_client_thread_info_sa d_client_thread;    // [options.max_client_threads]
+
+  // We use bitvectors to represent the completing state of a job.  Each
+  // bitvector is d_bvlen longs in length.
+  int                   d_bvlen;               // bit vector length in longs
+
+  // This contains the storage for all the bitvectors used by the job
+  // manager.  There's 1 for each client thread, in the d_jobs_done
+  // field.  We allocate them all in a single cache aligned chunk.
+  boost::shared_ptr<void> _d_all_bitvectors;   // hack for automatic storage mgmt
+
+  // Lock free stack where we keep track of the free job descriptors.
+  gc_jd_stack_t                *d_free_list;           // stack of free job descriptors
+  boost::shared_ptr<void> _d_free_list_boost;  // hack for automatic storage mgmt
+
+  // The PPE inserts jobs here; SPEs pull jobs from here.
+  gc_jd_queue_t                *d_queue;               // job queue
+  boost::shared_ptr<void> _d_queue_boost;      // hack for automatic storage mgmt
+
+  int                   d_ea_args_maxsize;
+
+  struct gc_proc_def   *d_proc_def;            // the SPE procedure table
+  uint32_t              d_proc_def_ls_addr;    // the LS address of the table
+  int                   d_nproc_defs;          // number of proc_defs in table
+
+  gc_client_thread_info *alloc_cti();
+  void free_cti(gc_client_thread_info *cti);
+
+  void create_event_handler();
+  void set_eh_state(evt_handler_state s);
+  void set_ea_args_maxsize(int maxsize);
+
+  void notify_clients_jobs_are_done(unsigned int spe_num,
+                                   unsigned int completion_info_idx);
+
+public:
+  void event_handler_loop();   // really private
+
+private:
+  bool send_all_spes(uint32_t msg);
+  bool send_spe(unsigned int spe, uint32_t msg);
+  void print_event(spe_event_unit_t *evt);
+  void handle_event(spe_event_unit_t *evt);
+
+  // bitvector ops
+  void bv_zero(unsigned long *bv);
+  void bv_clr(unsigned long *bv, unsigned int bitno);
+  void bv_set(unsigned long *bv, unsigned int bitno);
+  bool bv_isset(unsigned long *bv, unsigned int bitno);
+  bool bv_isclr(unsigned long *bv, unsigned int bitno);
+
+  void setup_logfiles();
+  void sync_logfiles();
+  void unmap_logfiles();
+
+  friend gc_job_manager *gc_make_job_manager(const gc_jm_options *options);
+  
+  gc_job_manager_impl(const gc_jm_options *options = 0);
+
+public:
+  virtual ~gc_job_manager_impl();
+
+  /*!
+   * Stop accepting new jobs.  Wait for existing jobs to complete.
+   * Return all managed SPE's to the system.
+   */
+  virtual bool shutdown();
+
+  /*!
+   * \brief Return number of SPE's currently allocated to job manager.
+   */
+  virtual int nspes() const;
+
+  /*!
+   * \brief Return a pointer to a properly aligned job descriptor,
+   * or zero if none are available.
+   */
+  virtual gc_job_desc *alloc_job_desc();
+
+  /*
+   *! Return a job descriptor previously allocated with alloc_job_desc()
+   *
+   * \param[in] jd pointer to job descriptor to free.
+   */
+  virtual void free_job_desc(gc_job_desc *jd);
+
+  /*!
+   * \brief Submit a job for asynchronous processing on an SPE.
+   *
+   * \param[in] jd pointer to job description
+   *
+   * The caller must not read or write the job description
+   * or any of the memory associated with any indirect arguments
+   * until after calling wait_job.
+   *
+   * \returns true iff the job was successfully enqueued.
+   * If submit_job returns false, check jd->status for additional info.
+   */
+  virtual bool submit_job(gc_job_desc *jd);
+
+  /*!
+   * \brief Wait for job to complete.
+   *
+   * A thread may only wait for jobs which it submitted.
+   *
+   * \returns true if sucessful, else false.
+   */
+  virtual bool 
+  wait_job(gc_job_desc *jd);
+
+  /*!
+   * \brief wait for 1 or more jobs to complete.
+   *
+   * \param[input] njobs is the length of arrays \p jd and \p done.
+   * \param[input] jd are the jobs that are to be waited for.
+   * \param[output] done indicates whether the corresponding job is complete.
+   * \param[input] mode indicates whether to wait for ALL or ANY of the jobs
+   *   in \p jd to complete.
+   *
+   * A thread may only wait for jobs which it submitted.
+   *
+   * \returns number of jobs completed, or -1 if error.
+   */
+  virtual int
+  wait_jobs(unsigned int njobs,
+           gc_job_desc *jd[], bool done[], gc_wait_mode mode);
+
+  virtual int ea_args_maxsize();
+
+  virtual gc_proc_id_t lookup_proc(const std::string &name);
+  virtual std::vector<std::string> proc_names();
+
+  virtual void set_debug(int debug);
+  virtual int debug();
+};
+
+#endif /* INCLUDED_GC_JOB_MANAGER_IMPL_H */
diff --git a/gcell/src/lib/runtime/gc_proc_def_utils.cc b/gcell/src/lib/runtime/gc_proc_def_utils.cc
new file mode 100644 (file)
index 0000000..c5b9848
--- /dev/null
@@ -0,0 +1,123 @@
+/* -*- 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 <gc_proc_def_utils.h>
+#include <gc_declare_proc.h>
+#include <elf.h>
+#include <stdio.h>
+#include <string.h>
+
+static const unsigned char expected[EI_PAD] = {
+  ELFMAG0,
+  ELFMAG1,
+  ELFMAG2,
+  ELFMAG3,
+  ELFCLASS32,
+  ELFDATA2MSB,
+  EV_CURRENT,
+  ELFOSABI_SYSV,
+  0
+};
+
+
+/*
+ * Basically we're going to find the GC_PROC_DEF_SECTION section
+ * in the ELF file and return a pointer to it.  The only things in that
+ * section are gc_proc_def's
+ */
+bool 
+gcpd_find_table(spe_program_handle_t *handle,
+               struct gc_proc_def **table, int *nentries, uint32_t *ls_addr)
+{
+  if (!handle || !table || !nentries)
+    return false;
+
+  *table = 0;
+  *nentries = 0;
+  
+  Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image;
+  if (!ehdr){
+    fprintf(stderr, "gcpd: No ELF image has been loaded\n");
+    return false;
+  }
+
+  // quick check that we're looking at a SPE EXEC object
+
+  if (memcmp(ehdr->e_ident, expected, EI_PAD) != 0){
+    fprintf(stderr, "gcpd: invalid ELF header\n");
+    return false;
+  }
+
+  if (ehdr->e_machine != 0x17){                // confirm machine type (EM_SPU)
+    fprintf(stderr, "gcpd: not an SPE ELF object\n");
+    return false;
+  }
+
+  if (ehdr->e_type != ET_EXEC){
+    fprintf(stderr, "gcpd: invalid SPE ELF type.\n");
+    fprintf(stderr, "gcpd: SPE type %d != %d\n", ehdr->e_type, ET_EXEC);
+    return false;
+  }
+
+  // find the section header table
+
+  Elf32_Shdr *shdr;
+  Elf32_Shdr *sh;
+
+  if (ehdr->e_shentsize != sizeof (*shdr)){
+    fprintf(stderr, "gcpd: invalid section header format.\n");
+    return false;
+  }
+
+  if (ehdr->e_shnum == 0){
+    fprintf(stderr, "gcpd: no section headers in file.\n");
+    return false;
+  }
+
+  shdr = (Elf32_Shdr *) ((char *)ehdr + ehdr->e_shoff);
+  char *str_table = (char *)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
+
+  // traverse the sections looking for GC_PROC_DEF_SECTION
+  
+  for (sh = shdr; sh < &shdr[ehdr->e_shnum]; sh++){
+    if (0){
+      fprintf(stderr, "section name: %s (start: 0x%04x, size: 0x%04x)\n",
+             str_table + sh->sh_name, sh->sh_offset, sh->sh_size);
+    }
+
+    if (strcmp(GC_PROC_DEF_SECTION, str_table+sh->sh_name) == 0){
+      *table = (struct gc_proc_def *)((char *)ehdr + sh->sh_offset);
+      if (sh->sh_size % (sizeof(struct gc_proc_def)) != 0){
+       fprintf(stderr, "gcpd: %s section has invalid format\n", GC_PROC_DEF_SECTION);
+       return false;
+      }
+      *nentries = sh->sh_size / sizeof(struct gc_proc_def);
+      *ls_addr = sh->sh_addr;
+      return true;
+    }
+  }
+
+  return false;
+}
diff --git a/gcell/src/lib/runtime/gc_proc_def_utils.h b/gcell/src/lib/runtime/gc_proc_def_utils.h
new file mode 100644 (file)
index 0000000..c59e472
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2008 Free Software Foundation, Inc.
+ * 
+ * This file is part of GNU Radio
+ * 
+ * GNU Radio is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3, or (at your option)
+ * any later version.
+ * 
+ * GNU Radio is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_GC_PROC_DEF_UTILS_H
+#define INCLUDED_GC_PROC_DEF_UTILS_H
+
+#include <gc_declare_proc.h>
+#include <libspe2.h>
+
+/*!
+ * \brief find the gc_proc_def table in the SPE program
+ *
+ * \param[in]  program is the handle to the loaded SPE program
+ * \param[out] table points to the table, if it's found
+ * \param[out] nentries is set to the number of entries in the table.
+ * \param[out] ls_addr is set to the Local Store address of the table
+ *
+ * \returns true if successful, else false
+ */
+bool
+gcpd_find_table(spe_program_handle_t *program,
+               struct gc_proc_def **table, int *nentries, uint32_t *ls_addr);
+
+
+#endif /* INCLUDED_GC_PROC_DEF_UTILS_H */
diff --git a/gcell/src/lib/runtime/qa_jd_queue.cc b/gcell/src/lib/runtime/qa_jd_queue.cc
new file mode 100644 (file)
index 0000000..267d4cf
--- /dev/null
@@ -0,0 +1,78 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "qa_jd_queue.h"
+#include <cppunit/TestAssert.h>
+#include "gc_jd_queue.h"
+#include <stdio.h>
+
+
+
+static const int NJDS = 16;
+static gc_jd_queue_t queue;
+static gc_job_desc_t jds[NJDS];
+
+// no brainer, single threaded basic checkout
+void
+qa_jd_queue::t1()
+{
+  // N.B., queue allocated stuff doesn't obey ((aligned (N))) attributes
+  //const int NJDS = 8;
+  //gc_jd_queue_t queue;
+  //gc_job_desc_t jds[NJDS];
+
+  //printf("&queue   = %p\n", &queue);
+  //printf("&jds[0] = %p\n", &jds[0]);
+  //printf("&jds[1] = %p\n", &jds[1]);
+
+  CPPUNIT_ASSERT(((uintptr_t) &queue & 0x7f) == 0);
+  CPPUNIT_ASSERT(((uintptr_t) &jds[0] & 0x7f) == 0);
+  CPPUNIT_ASSERT(((uintptr_t) &jds[1] & 0x7f) == 0);
+
+  gc_jd_queue_init(&queue);
+
+  CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0);
+
+  gc_jd_queue_enqueue(&queue, &jds[0]);
+  CPPUNIT_ASSERT_EQUAL(&jds[0], gc_jd_queue_dequeue(&queue));
+
+  CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0);
+
+  for (int i = 0; i < NJDS; i++)
+    gc_jd_queue_enqueue(&queue, &jds[i]);
+
+  for (int i = 0; i < NJDS; i++)
+    CPPUNIT_ASSERT_EQUAL(&jds[i], gc_jd_queue_dequeue(&queue));
+
+  CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0);
+}
+
+// FIXME multithreaded (running on PPE)
+void
+qa_jd_queue::t2()
+{
+}
+
+// FIXME multithreaded (running on PPE & SPE)
+void
+qa_jd_queue::t3()
+{
+}
diff --git a/gcell/src/lib/runtime/qa_jd_queue.h b/gcell/src/lib/runtime/qa_jd_queue.h
new file mode 100644 (file)
index 0000000..5e1aab8
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_JD_QUEUE_H
+#define INCLUDED_QA_JD_QUEUE_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_jd_queue : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_jd_queue);
+  CPPUNIT_TEST(t1);
+  CPPUNIT_TEST(t2);
+  CPPUNIT_TEST(t3);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void t1();
+  void t2();
+  void t3();
+};
+
+
+#endif /* INCLUDED_QA_JD_QUEUE_H */
diff --git a/gcell/src/lib/runtime/qa_jd_stack.cc b/gcell/src/lib/runtime/qa_jd_stack.cc
new file mode 100644 (file)
index 0000000..67e97c9
--- /dev/null
@@ -0,0 +1,67 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "qa_jd_stack.h"
+#include <cppunit/TestAssert.h>
+#include "gc_jd_stack.h"
+#include <stdio.h>
+
+
+
+static const int NJDS = 8;
+static gc_jd_stack_t stack;
+static gc_job_desc_t jds[NJDS];
+
+// no brainer, single threaded basic checkout
+void
+qa_jd_stack::t1()
+{
+  // N.B., stack allocated stuff doesn't obey ((aligned (N))) attributes
+  //const int NJDS = 8;
+  //gc_jd_stack_t stack;
+  //gc_job_desc_t jds[NJDS];
+
+  //printf("&stack   = %p\n", &stack);
+  //printf("&jds[0] = %p\n", &jds[0]);
+  //printf("&jds[1] = %p\n", &jds[1]);
+
+  CPPUNIT_ASSERT(((uintptr_t) &stack & 0x7f) == 0);
+  CPPUNIT_ASSERT(((uintptr_t) &jds[0] & 0x7f) == 0);
+  CPPUNIT_ASSERT(((uintptr_t) &jds[1] & 0x7f) == 0);
+
+  gc_jd_stack_init(&stack);
+
+  CPPUNIT_ASSERT(gc_jd_stack_pop(&stack) == 0);
+
+  for (int i = 0; i < NJDS; i++)
+    gc_jd_stack_push(&stack, &jds[i]);
+
+  for (int i = 0; i < NJDS; i++)
+    CPPUNIT_ASSERT_EQUAL(&jds[NJDS - i - 1], gc_jd_stack_pop(&stack));
+
+  CPPUNIT_ASSERT(gc_jd_stack_pop(&stack) == 0);
+}
+
+// FIXME multithreaded (running on PPE)
+void
+qa_jd_stack::t2()
+{
+}
diff --git a/gcell/src/lib/runtime/qa_jd_stack.h b/gcell/src/lib/runtime/qa_jd_stack.h
new file mode 100644 (file)
index 0000000..1546bbf
--- /dev/null
@@ -0,0 +1,42 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_JD_STACK_H
+#define INCLUDED_QA_JD_STACK_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_jd_stack : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_jd_stack);
+  CPPUNIT_TEST(t1);
+  CPPUNIT_TEST(t2);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void t1();
+  void t2();
+
+};
+
+
+
+#endif /* INCLUDED_QA_JD_STACK_H */
diff --git a/gcell/src/lib/runtime/qa_job_manager.cc b/gcell/src/lib/runtime/qa_job_manager.cc
new file mode 100644 (file)
index 0000000..3f2780c
--- /dev/null
@@ -0,0 +1,798 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "qa_job_manager.h"
+#include <cppunit/TestAssert.h>
+#include "gc_job_manager.h"
+#include <stdexcept>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#include <malloc.h>
+
+extern spe_program_handle_t gcell_qa;  // handle to embedded SPU executable w/ QA routines
+
+#if 0
+static void
+gc_msleep(unsigned long millisecs)
+{
+  int r;
+  struct timespec tv;
+  tv.tv_sec = millisecs / 1000;
+  tv.tv_nsec = (millisecs - (tv.tv_sec * 1000)) * 1000000;
+  
+  while (1){
+    r = nanosleep(&tv, &tv);
+    if (r == 0)
+      return;
+    if (r == -1 && errno == EINTR)
+      continue;
+    perror("nanosleep");
+    return;
+  }
+}
+#endif
+
+void
+qa_job_manager::leak_check(test_t t, const std::string &name)
+{
+  struct mallinfo before, after;
+
+  before = mallinfo();
+  (this->*t)();
+  after = mallinfo();
+
+  size_t delta = after.uordblks - before.uordblks;
+  if (delta != 0){
+    std::cout << name << " leaked memory\n";
+    printf("  before.uordblks = %6d\n", before.uordblks);
+    printf("  after.uordblks  = %6d\n",  after.uordblks);
+    printf("  delta = %d\n", after.uordblks - before.uordblks);
+  }
+}
+
+void
+qa_job_manager::t0()
+{
+  //leak_check(&qa_job_manager::t1_body, "t1-0");
+}
+
+void
+qa_job_manager::t1()
+{
+  t1_body();           // leaks 800 bytes first time, could be one-time inits
+  leak_check(&qa_job_manager::t1_body, "t1");
+}
+
+void
+qa_job_manager::t2()
+{
+  leak_check(&qa_job_manager::t2_body, "t2");
+}
+
+void
+qa_job_manager::t3()
+{
+  t3_body();           // leaks first time only, could be cppunit
+  leak_check(&qa_job_manager::t3_body, "t3");
+}
+
+void
+qa_job_manager::t4()
+{
+  leak_check(&qa_job_manager::t4_body, "t4");
+}
+
+void
+qa_job_manager::t5()
+{
+  leak_check(&qa_job_manager::t5_body, "t5");
+}
+
+void
+qa_job_manager::t6()
+{
+  leak_check(&qa_job_manager::t6_body, "t6");
+}
+
+void
+qa_job_manager::t7()
+{
+  leak_check(&qa_job_manager::t7_body, "t7");
+}
+
+void
+qa_job_manager::t8()
+{
+  leak_check(&qa_job_manager::t8_body, "t8");
+}
+
+void
+qa_job_manager::t9()
+{
+  leak_check(&qa_job_manager::t9_body, "t9");
+}
+
+void
+qa_job_manager::t10()
+{
+  leak_check(&qa_job_manager::t10_body, "t10");
+}
+
+void
+qa_job_manager::t11()
+{
+  leak_check(&qa_job_manager::t11_body, "t11");
+}
+
+void
+qa_job_manager::t12()
+{
+  leak_check(&qa_job_manager::t12_body, "t12");
+}
+
+void
+qa_job_manager::t13()
+{
+  leak_check(&qa_job_manager::t13_body, "t13");
+}
+
+void
+qa_job_manager::t14()
+{
+  leak_check(&qa_job_manager::t14_body, "t14");
+}
+
+void
+qa_job_manager::t15()
+{
+  leak_check(&qa_job_manager::t15_body, "t15");
+}
+
+// ----------------------------------------------------------------
+
+void
+qa_job_manager::t1_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  mgr = gc_make_job_manager(&opts);
+  delete mgr;
+}
+
+void
+qa_job_manager::t2_body()
+{
+  gc_job_manager *mgr = 0;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 100;
+  opts.gang_schedule = false;
+  mgr = gc_make_job_manager(&opts);
+  delete mgr;
+}
+
+void
+qa_job_manager::t3_body()
+{
+  // This leaks memory the first time it's invoked, but I'm not sure
+  // if it's us or the underlying exception handling mechanism, or
+  // cppunit.  cppunit is the prime suspect.
+
+#if 0
+  gc_job_manager *mgr = 0;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 100;
+  opts.gang_schedule = true;
+  CPPUNIT_ASSERT_THROW(mgr = gc_make_job_manager(&opts), std::out_of_range);
+  delete mgr;
+#endif
+}
+
+static void
+init_jd(gc_job_desc *jd, gc_proc_id_t proc_id)
+{
+  jd->proc_id = proc_id;
+  jd->input.nargs = 0;
+  jd->output.nargs = 0;
+  jd->eaa.nargs = 0;
+}
+
+void
+qa_job_manager::t4_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+  //mgr->set_debug(-1);
+  static const int NJOBS = 32;
+  gc_job_desc *jds[NJOBS];
+  bool done[NJOBS];
+
+  gc_proc_id_t gcp_no_such = mgr->lookup_proc("--no-such-proc-name--");
+  CPPUNIT_ASSERT_EQUAL(GCP_UNKNOWN_PROC, gcp_no_such);
+
+  gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop");
+  CPPUNIT_ASSERT(gcp_qa_nop != GCP_UNKNOWN_PROC);
+
+  for (int i = 0; i < NJOBS; i++){
+    jds[i] = mgr->alloc_job_desc();
+    init_jd(jds[i], gcp_qa_nop);
+  }
+
+  for (int i = 0; i < NJOBS; i++){
+    if (!mgr->submit_job(jds[i])){
+      printf("%d: submit_job(jds[%d]) failed, status = %d\n",
+            __LINE__, i, jds[i]->status);
+    }
+  }
+
+  int n = mgr->wait_jobs(NJOBS, jds, done, GC_WAIT_ALL);
+  CPPUNIT_ASSERT_EQUAL(NJOBS, n);
+
+  for (int i = 0; i < NJOBS; i++){
+    mgr->free_job_desc(jds[i]);
+  }
+
+  delete mgr;
+}
+
+void
+qa_job_manager::t5_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 0;      // use them all
+  mgr = gc_make_job_manager(&opts);
+  //mgr->set_debug(-1);
+  static const int NJOBS = 32;
+  gc_job_desc *jds[NJOBS];
+  bool done[NJOBS];
+
+  gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop");
+
+  for (int i = 0; i < NJOBS; i++){
+    jds[i] = mgr->alloc_job_desc();
+    init_jd(jds[i], gcp_qa_nop);
+  }
+
+  for (int i = 0; i < NJOBS; i++){
+    if (!mgr->submit_job(jds[i])){
+      printf("%d: submit_job(jds[%d]) failed, status = %d\n",
+            __LINE__, i, jds[i]->status);
+    }
+  }
+
+  int n = mgr->wait_jobs(NJOBS, jds, done, GC_WAIT_ALL);
+  CPPUNIT_ASSERT_EQUAL(NJOBS, n);
+
+  for (int i = 0; i < NJOBS; i++){
+    mgr->free_job_desc(jds[i]);
+  }
+
+  delete mgr;
+}
+
+void
+qa_job_manager::t6_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;      
+  mgr = gc_make_job_manager(&opts);
+  gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop");
+  gc_job_desc *jd = mgr->alloc_job_desc();
+
+  
+  // test for success with gcp_qa_nop procedure
+  init_jd(jd, gcp_qa_nop);
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+  }
+
+  // test for JS_UNKNOWN_PROC with bogus procedure
+  init_jd(jd, -2);
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_UNKNOWN_PROC, jd->status);
+  }
+
+  mgr->free_job_desc(jd);
+  delete mgr;
+}
+
+static int
+sum_shorts(short *p, int nshorts)
+{
+  int total = 0;
+  for (int i = 0; i < nshorts; i++)
+    total += p[i];
+
+  return total;
+}
+
+static void
+test_sum_shorts(gc_job_manager *mgr, short *buf, int nshorts)
+{
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts");
+
+  init_jd(jd, gcp_qa_sum_shorts);
+  jd->eaa.nargs = 1;
+  jd->eaa.arg[0].ea_addr = ptr_to_ea(buf);
+  jd->eaa.arg[0].direction = GCJD_DMA_GET;
+  jd->eaa.arg[0].get_size = nshorts * sizeof(short);
+  
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+    int expected = sum_shorts(buf, nshorts);
+    int actual = jd->output.arg[0].s32;
+    CPPUNIT_ASSERT_EQUAL(expected, actual);
+  }
+
+  mgr->free_job_desc(jd);
+}
+
+static const int NS = 32768;
+static short short_buf[NS] _AL128;     // for known alignment
+
+//
+// test all "get" alignments and sizes
+//
+void
+qa_job_manager::t7_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+
+  int ea_args_maxsize = mgr->ea_args_maxsize();
+
+  for (int i = 0; i < NS; i++) // init buffer with known qty
+    short_buf[i] = 0x1234 + i;
+  
+  for (int offset = 0; offset <= 128; offset++){
+    for (int len = 0; len <= 128; len++){
+      test_sum_shorts(mgr, &short_buf[offset], len);
+    }
+  }
+
+  // confirm maximum length
+  for (int offset = 0; offset <= 64; offset++){
+    test_sum_shorts(mgr, &short_buf[offset], ea_args_maxsize/sizeof(short));
+  }
+
+  delete mgr;
+}
+
+//
+// test "get" args too long
+//
+void
+qa_job_manager::t8_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts");
+
+  init_jd(jd, gcp_qa_sum_shorts);
+  jd->eaa.nargs = 1;
+  jd->eaa.arg[0].ea_addr = 0;
+  jd->eaa.arg[0].direction = GCJD_DMA_GET;
+  jd->eaa.arg[0].get_size = 1 << 20;
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_ARGS_TOO_LONG, jd->status);
+  }
+
+  mgr->free_job_desc(jd);
+  delete mgr;
+}
+
+//
+// test MAX_ARGS_EA "get" case
+//
+void
+qa_job_manager::t9_body()
+{
+  static const int N = 127;
+  static const int M = 201;
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts");
+
+  init_jd(jd, gcp_qa_sum_shorts);
+  jd->eaa.nargs = MAX_ARGS_EA;
+  for (int i = 0; i < MAX_ARGS_EA; i++){
+    jd->eaa.arg[i].direction = GCJD_DMA_GET;
+    jd->eaa.arg[i].ea_addr = ptr_to_ea(&short_buf[i * M]);
+    jd->eaa.arg[i].get_size = N * sizeof(short);
+  }
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+    for (int i = 0; i < MAX_ARGS_EA; i++){
+      int expected = sum_shorts(&short_buf[i * M], N);
+      int actual = jd->output.arg[i].s32;
+      CPPUNIT_ASSERT_EQUAL(expected, actual);
+    }
+  }
+
+  mgr->free_job_desc(jd);
+  delete mgr;
+}
+
+static bool
+confirm_const(const unsigned char *buf, size_t len, unsigned char v)
+{
+  bool ok = true;
+
+  for (size_t i = 0; i < len; i++){
+    if (buf[i] != v){
+      ok = false;
+      printf("confirm_const: buf[%6d] = 0x%02x, expected = 0x%02x\n",
+            i, buf[i], v);
+    }
+  }
+
+  return ok;
+}
+
+static bool
+confirm_seq(const unsigned char *buf, size_t len, unsigned char v)
+{
+  bool ok = true;
+
+  for (size_t i = 0; i < len; i++, v++){
+    if (buf[i] != v){
+      ok = false;
+      printf("confirm_seq: buf[%6d] = 0x%02x, expected = 0x%02x\n",
+            i, buf[i], v);
+    }
+  }
+
+  return ok;
+}
+
+static void
+test_put_seq(gc_job_manager *mgr, int offset, int len, int starting_val)
+{
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq");
+
+  unsigned char *buf = (unsigned char *) short_buf;
+  size_t buf_len = sizeof(short_buf);
+  memset(buf, 0xff, buf_len);
+
+  // two cache lines into the buffer, so we can check before and after
+  int fixed_offset = 256;
+
+  init_jd(jd, gcp_qa_put_seq);
+  jd->input.nargs = 1;
+  jd->input.arg[0].s32 = starting_val;
+  jd->eaa.nargs = 1;
+  jd->eaa.arg[0].ea_addr = ptr_to_ea(buf + fixed_offset + offset);
+  jd->eaa.arg[0].direction = GCJD_DMA_PUT;
+  jd->eaa.arg[0].put_size = len;
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+    
+    // check before
+    CPPUNIT_ASSERT(confirm_const(&buf[0], fixed_offset + offset, 0xff)); 
+
+    // check sequence
+    CPPUNIT_ASSERT(confirm_seq(&buf[fixed_offset + offset], len, starting_val));
+
+    // check after
+    CPPUNIT_ASSERT(confirm_const(&buf[fixed_offset + offset + len],
+                                buf_len - fixed_offset - offset - len, 0xff));
+  }
+  mgr->free_job_desc(jd);
+}
+
+//
+// Test all "put" alignments and sizes
+//
+void
+qa_job_manager::t10_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+
+  int starting_val = 13;
+
+  for (int offset = 0; offset <= 128; offset++){
+    for (int len = 0; len <= 128; len++){
+      test_put_seq(mgr, offset, len, starting_val++);
+    }
+  }
+
+  int ea_args_maxsize = mgr->ea_args_maxsize();
+
+  // confirm maximum length
+  for (int offset = 0; offset <= 64; offset++){
+    test_put_seq(mgr, offset, ea_args_maxsize, starting_val++);
+  }
+
+  delete mgr;
+}
+
+//
+// test "put" args too long
+//
+void
+qa_job_manager::t11_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq");
+
+  init_jd(jd, gcp_qa_put_seq);
+  jd->input.nargs = 1;
+  jd->input.arg[0].s32 = 0;
+  jd->eaa.nargs = 1;
+  jd->eaa.arg[0].ea_addr = 0;
+  jd->eaa.arg[0].direction = GCJD_DMA_PUT;
+  jd->eaa.arg[0].put_size = 1 << 20;
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_ARGS_TOO_LONG, jd->status);
+  }
+
+  mgr->free_job_desc(jd);
+  delete mgr;
+}
+
+//
+// test MAX_ARGS_EA "put" case
+//
+void
+qa_job_manager::t12_body()
+{
+  static const int N = 127;
+  static const int M = 201;
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq");
+
+  unsigned char *buf = (unsigned char *) short_buf;
+  size_t buf_len = sizeof(short_buf);
+  memset(buf, 0xff, buf_len);
+
+  // two cache lines into the buffer, so we can check before and after
+  int fixed_offset = 256;
+
+  int starting_val = 13;
+
+  init_jd(jd, gcp_qa_put_seq);
+  jd->input.nargs = 1;
+  jd->input.arg[0].s32 = starting_val;
+  jd->eaa.nargs = MAX_ARGS_EA;
+  for (int i = 0; i < MAX_ARGS_EA; i++){
+    jd->eaa.arg[i].direction = GCJD_DMA_PUT;
+    jd->eaa.arg[i].ea_addr = ptr_to_ea(&buf[i * M + fixed_offset]);
+    jd->eaa.arg[i].put_size = N;
+  }
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+    for (int i = 0; i < MAX_ARGS_EA; i++){
+      CPPUNIT_ASSERT(confirm_seq(&buf[i * M + fixed_offset], N, starting_val));
+      starting_val += N;
+    }
+  }
+
+  mgr->free_job_desc(jd);
+  delete mgr;
+}
+
+//
+// test qa_copy primitive
+//
+void
+qa_job_manager::t13_body()
+{
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+
+  memset(short_buf, 0, sizeof(short_buf));
+  for (int i = 0; i < NS/2; i++)       // init buffer with known qty
+    short_buf[i] = 0x1234 + i;
+
+  int nshorts = NS/2;
+
+  gc_job_desc *jd = mgr->alloc_job_desc();
+  gc_proc_id_t gcp_qa_copy = mgr->lookup_proc("qa_copy");
+
+#if 0
+  printf("gcq_qa_copy = %d\n", gcp_qa_copy);
+  std::vector<std::string> procs = mgr->proc_names();
+  for (unsigned int i = 0; i < procs.size(); ++i)
+    std::cout << procs[i] << std::endl;
+#endif
+
+  init_jd(jd, gcp_qa_copy);
+  jd->eaa.nargs = 2;
+  jd->eaa.arg[0].ea_addr = ptr_to_ea(&short_buf[nshorts]);
+  jd->eaa.arg[0].direction = GCJD_DMA_PUT;
+  jd->eaa.arg[0].put_size = nshorts * sizeof(short);
+  
+  jd->eaa.arg[1].ea_addr = ptr_to_ea(&short_buf[0]);
+  jd->eaa.arg[1].direction = GCJD_DMA_GET;
+  jd->eaa.arg[1].get_size = nshorts * sizeof(short);
+  
+
+  if (!mgr->submit_job(jd)){
+    printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status);
+  }
+  else {
+    mgr->wait_job(jd);
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status);
+    CPPUNIT_ASSERT_EQUAL(0, jd->output.arg[0].s32);
+
+    bool ok = true;
+    for (int i = 0; i < nshorts; i++){
+      if (short_buf[i] != short_buf[i + nshorts])
+       ok = false;
+    }
+    CPPUNIT_ASSERT(ok);
+  }
+  mgr->free_job_desc(jd);
+
+  delete mgr;
+}
+
+/*
+ * Parallel submission of NJOBS "put" jobs will test double buffered puts.
+ */
+void
+qa_job_manager::t14_body()
+{
+  //return;
+
+  //static const int NJOBS = 64;
+  static const int NJOBS = 128;
+  static const int LEN_PER_JOB = 1021;
+  unsigned char    buf[NJOBS * LEN_PER_JOB];
+  gc_job_desc_t          *jd[NJOBS];
+  bool            done[NJOBS];
+
+  static const int STARTING_VAL = 13;
+
+  memset(buf, 0xff, LEN_PER_JOB * NJOBS);
+
+  gc_job_manager *mgr;
+  gc_jm_options opts;
+  opts.program_handle = &gcell_qa;
+  opts.nspes = 1;
+  mgr = gc_make_job_manager(&opts);
+
+
+  gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq");
+
+  // do all the initialization up front
+
+  for (int i = 0, val = STARTING_VAL; i < NJOBS; i++, val += 3){
+    jd[i] = mgr->alloc_job_desc();
+    init_jd(jd[i], gcp_qa_put_seq);
+    jd[i]->input.nargs = 1;
+    jd[i]->input.arg[0].s32 = val;
+    jd[i]->eaa.nargs = 1;
+    jd[i]->eaa.arg[0].ea_addr = ptr_to_ea(&buf[i * LEN_PER_JOB]);
+    jd[i]->eaa.arg[0].direction = GCJD_DMA_PUT;
+    jd[i]->eaa.arg[0].put_size = LEN_PER_JOB;
+  }
+
+  // submit them all
+
+  for (int i = 0; i < NJOBS; i++){
+    if (!mgr->submit_job(jd[i])){
+      printf("%d: submit_job(jd[%2d]) failed, status = %d\n", __LINE__, i, jd[i]->status);
+    }
+  }
+
+  // wait for them all
+
+  int n = mgr->wait_jobs(NJOBS, jd, done, GC_WAIT_ALL);
+  CPPUNIT_ASSERT_EQUAL(NJOBS, n);
+
+  // check results
+
+  for (int i = 0, val = STARTING_VAL; i < NJOBS; i++, val += 3){
+    CPPUNIT_ASSERT_EQUAL(JS_OK, jd[i]->status);
+    CPPUNIT_ASSERT(confirm_seq(&buf[i * LEN_PER_JOB], LEN_PER_JOB, val));
+  }
+  
+  // cleanup
+  for (int i = 0; i < NJOBS; i++)
+    mgr->free_job_desc(jd[i]);
+
+  delete mgr;
+}
+
+void
+qa_job_manager::t15_body()
+{
+}
diff --git a/gcell/src/lib/runtime/qa_job_manager.h b/gcell/src/lib/runtime/qa_job_manager.h
new file mode 100644 (file)
index 0000000..ab3325b
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_JOB_MANAGER_H
+#define INCLUDED_QA_JOB_MANAGER_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+
+class qa_job_manager;
+typedef void (qa_job_manager::*test_t)();
+
+
+class qa_job_manager : public CppUnit::TestCase {
+
+  CPPUNIT_TEST_SUITE(qa_job_manager);
+  CPPUNIT_TEST(t0);
+  CPPUNIT_TEST(t1);
+  CPPUNIT_TEST(t2);
+  CPPUNIT_TEST(t3);
+  CPPUNIT_TEST(t4);
+  CPPUNIT_TEST(t5);
+  CPPUNIT_TEST(t6);
+  CPPUNIT_TEST(t7);
+  CPPUNIT_TEST(t8);
+  CPPUNIT_TEST(t9);
+  CPPUNIT_TEST(t10);
+  CPPUNIT_TEST(t11);
+  CPPUNIT_TEST(t12);
+  CPPUNIT_TEST(t13);
+  CPPUNIT_TEST(t14);
+  CPPUNIT_TEST(t15);
+  CPPUNIT_TEST_SUITE_END();
+
+ private:
+  void leak_check(test_t t, const std::string &name);
+
+  void t0();
+  void t1();
+  void t1_body();
+  void t2();
+  void t2_body();
+  void t3();
+  void t3_body();
+  void t4();
+  void t4_body();
+  void t5();
+  void t5_body();
+  void t6();
+  void t6_body();
+  void t7();
+  void t7_body();
+  void t8();
+  void t8_body();
+  void t9();
+  void t9_body();
+  void t10();
+  void t10_body();
+  void t11();
+  void t11_body();
+  void t12();
+  void t12_body();
+  void t13();
+  void t13_body();
+  void t14();
+  void t14_body();
+  void t15();
+  void t15_body();
+
+};
+
+#endif /* INCLUDED_QA_JOB_MANAGER_H */
diff --git a/gcell/src/lib/runtime/qa_lib.cc b/gcell/src/lib/runtime/qa_lib.cc
new file mode 100644 (file)
index 0000000..d8a8960
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/*
+ * This class gathers together all the test cases for the lib
+ * directory into a single test suite.  As you create new test cases,
+ * add them here.
+ */
+
+#include <qa_lib.h>
+#include <qa_jd_stack.h>
+#include <qa_jd_queue.h>
+#include <qa_job_manager.h>
+
+CppUnit::TestSuite *
+qa_lib::suite()
+{
+  CppUnit::TestSuite   *s = new CppUnit::TestSuite("lib");
+
+  s->addTest(qa_jd_stack::suite());
+  s->addTest(qa_jd_queue::suite());
+  s->addTest(qa_job_manager::suite());
+
+  return s;
+}
diff --git a/gcell/src/lib/runtime/qa_lib.h b/gcell/src/lib/runtime/qa_lib.h
new file mode 100644 (file)
index 0000000..594efcd
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef INCLUDED_QA_LIB_H
+#define INCLUDED_QA_LIB_H
+
+#include <cppunit/TestSuite.h>
+
+//! collect all the tests for the lib directory
+
+class qa_lib {
+public:
+  //! return suite of tests
+  static CppUnit::TestSuite *suite();
+};
+
+
+#endif /* INCLUDED_QA_LIB_H */
diff --git a/gcell/src/lib/runtime/spu/gc_delay.c b/gcell/src/lib/runtime/spu/gc_delay.c
new file mode 100644 (file)
index 0000000..21ee587
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_delay.h"
+#include <compiler.h>
+
+inline static void
+gc_udelay_1us(void)
+{
+  unsigned int i = 158;
+
+  do {  // 20 clocks per iteration of the loop
+    asm ("nop $127; nop $127; nop $127; nop $127; nop $127");
+    asm ("nop $127; nop $127; nop $127; nop $127; nop $127");
+    asm ("nop $127; nop $127; nop $127; nop $127; nop $127");
+    asm ("nop $127; nop $127");
+  } while(--i != 0);
+}
+
+void
+gc_udelay(unsigned int usecs)
+{
+  unsigned int i;
+  for (i = 0; i < usecs; i++)
+    gc_udelay_1us();
+}
+
+void
+gc_cdelay(unsigned int cpu_cycles)
+{
+  if (cpu_cycles < 40) // roughly the amount of overhead
+    return;
+  
+  cpu_cycles >>= 2;    // about 4 cycles / loop
+
+  while (cpu_cycles-- != 0){
+    asm ("nop $127");  // keeps compiler from removing the loop
+  }
+}
+
diff --git a/gcell/src/lib/runtime/spu/gc_logging.c b/gcell/src/lib/runtime/spu/gc_logging.c
new file mode 100644 (file)
index 0000000..65a5375
--- /dev/null
@@ -0,0 +1,77 @@
+/* -*- 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 <gc_logging.h>
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <gc_spu_args.h>
+
+static gc_eaddr_t     log_base_ea;     // base address of log entries in EA
+static uint32_t              log_idx_mask;     // nentries - 1
+static uint32_t              log_idx;          // current log entry index
+static uint32_t              log_seqno;
+
+static int           log_tags;         // two consecutive tags
+static int           tmp_buffer_busy;  // bitmask: buffer busy state
+static int           tmp_buffer_idx;   // 0 or 1
+static gc_log_entry_t tmp_buffer[2];
+
+void
+_gc_log_init(gc_log_t info)
+{
+  spu_write_decrementer(~0);
+
+  log_base_ea = info.base;
+  log_idx_mask = info.nentries - 1;
+  log_idx = 0;
+  log_seqno = 0;
+
+  log_tags = mfc_multi_tag_reserve(2);
+  tmp_buffer_busy = 0;
+  tmp_buffer_idx = 0;
+
+  gc_log_write0(GCL_SS_SYS, 0);
+}
+
+void
+_gc_log_write(gc_log_entry_t entry)
+{
+  if (log_base_ea == 0)
+    return;
+
+  entry.seqno = log_seqno++;
+  entry.timestamp = spu_read_decrementer();
+
+  if (tmp_buffer_busy & (1 << tmp_buffer_idx)){
+    mfc_write_tag_mask(1 << (log_tags + tmp_buffer_idx));
+    mfc_read_tag_status_all();
+  }
+
+  tmp_buffer[tmp_buffer_idx] = entry;  // save local copy
+
+  mfc_put(&tmp_buffer[tmp_buffer_idx],
+         log_base_ea + log_idx * sizeof(entry), sizeof(entry),
+         log_tags + tmp_buffer_idx, 0, 0);
+
+  tmp_buffer_busy |= (1 << tmp_buffer_idx);
+  tmp_buffer_idx ^= 0x1;
+  log_idx = (log_idx + 1) & log_idx_mask;
+}
diff --git a/gcell/src/lib/runtime/spu/gc_main.c b/gcell/src/lib/runtime/spu/gc_main.c
new file mode 100644 (file)
index 0000000..96381fa
--- /dev/null
@@ -0,0 +1,682 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define ENABLE_GC_LOGGING      // define to enable logging
+
+#include <spu_intrinsics.h>
+#include <spu_mfcio.h>
+#include <sync_utils.h>
+#include "gc_spu_config.h"
+#include "gc_spu_args.h"
+#include "gc_job_desc.h"
+#include "gc_mbox.h"
+#include "gc_jd_queue.h"
+#include "gc_delay.h"
+#include "gc_declare_proc.h"
+#include "spu_buffers.h"
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+//! round x down to p2 boundary (p2 must be a power-of-2)
+#define ROUND_DN(x, p2) ((x) & ~((p2)-1))
+
+//! round x up to p2 boundary (p2 must be a power-of-2)
+#define ROUND_UP(x, p2) (((x)+((p2)-1)) & ~((p2)-1))
+
+
+#define USE_LLR_LOST_EVENT     0       // define to 0 or 1
+
+int                    gc_sys_tag;     // tag for misc DMA operations
+static gc_spu_args_t   spu_args;
+
+static struct gc_proc_def *gc_proc_def;        // procedure entry points
+
+// ------------------------------------------------------------------------
+
+// state for DMA'ing arguments in and out
+
+static int get_tag;            // 1 tag for job arg gets
+static int put_tags;           // 2 tags for job arg puts
+
+static int pb_idx = 0;         // current put buffer index (0 or 1)
+
+// bitmask (bit per put buffer): bit is set if DMA is started but not complete
+static int put_in_progress = 0;
+#define PBI_MASK(_pbi_) (1 << (_pbi_))
+
+// ------------------------------------------------------------------------
+
+// our working copy of the completion info
+static gc_comp_info_t  comp_info = {  
+  .in_use = 1,
+  .ncomplete = 0
+};
+
+static int ci_idx = 0;         // index of current comp_info
+static int ci_tags;            // two consecutive dma tags
+
+// ------------------------------------------------------------------------
+
+/*
+ * Wait until EA copy of comp_info[idx].in_use is 0
+ */
+static void
+wait_for_ppe_to_be_done_with_comp_info(int idx)
+{
+  char _tmp[256];
+  char *buf = (char *) ALIGN(_tmp, 128);       // get cache-aligned buffer
+  gc_comp_info_t *p = (gc_comp_info_t *) buf;
+
+  assert(sizeof(gc_comp_info_t) == 128);
+
+  do {
+    mfc_get(buf, spu_args.comp_info[idx], 128, gc_sys_tag, 0, 0);
+    mfc_write_tag_mask(1 << gc_sys_tag);
+    mfc_read_tag_status_all();
+    if (p->in_use == 0)
+      return;
+
+    gc_udelay(5);
+
+  } while (1);
+}
+
+static void
+flush_completion_info(void)
+{
+  // events: 0x3X
+
+  static int total_complete = 0;
+
+  if (comp_info.ncomplete == 0)
+    return;
+  
+  // ensure that PPE is done with the buffer we're about to overwrite
+  wait_for_ppe_to_be_done_with_comp_info(ci_idx);
+
+  // dma the comp_info out to PPE
+  int tag = ci_tags + ci_idx;
+  mfc_put(&comp_info, spu_args.comp_info[ci_idx], sizeof(gc_comp_info_t), tag, 0, 0);
+
+  // we need to wait for the completion info to finish, as well as
+  // any EA argument puts.
+
+  int tag_mask = 1 << tag;             // the comp_info tag
+  if (put_in_progress & PBI_MASK(0))
+    tag_mask |= (1 << (put_tags + 0));
+  if (put_in_progress & PBI_MASK(1))
+    tag_mask |= (1 << (put_tags + 1));
+
+  gc_log_write2(GCL_SS_SYS, 0x30, put_in_progress, tag_mask);
+
+  mfc_write_tag_mask(tag_mask);                // the tags we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+  put_in_progress = 0;                 // mark them all complete
+
+  total_complete += comp_info.ncomplete;
+  gc_log_write4(GCL_SS_SYS, 0x31,
+               put_in_progress, ci_idx, comp_info.ncomplete, total_complete);
+
+  // send PPE a message
+  spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_JOBS_DONE, ci_idx));
+
+  ci_idx ^= 0x1;       // switch buffers
+  comp_info.in_use = 1;
+  comp_info.ncomplete = 0;
+}
+
+// ------------------------------------------------------------------------
+
+static unsigned int backoff;           // current backoff value in clock cycles
+static unsigned int _backoff_start;
+static unsigned int _backoff_cap;
+
+/*
+ * For 3.2 GHz SPE
+ *
+ * 12    4095 cycles    1.3 us
+ * 13    8191 cycles    2.6 us
+ * 14   16383 cycles    5.1 us
+ * 15   32767 cycles   10.2 us
+ * 16                  20.4 us
+ * 17                  40.8 us
+ * 18                  81.9 us
+ * 19                 163.8 us
+ * 20                 327.7 us
+ * 21                 655.4 us
+ */
+static unsigned char log2_backoff_start[16] = {
+// 1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
+// -------------------------------------------------------------
+  12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16
+};
+  
+static unsigned char log2_backoff_cap[16] = {
+// 1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16
+// -------------------------------------------------------------
+  17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21
+};
+  
+static void
+backoff_init(void)
+{
+  _backoff_cap   = (1 << (log2_backoff_cap[(spu_args.nspus - 1) & 0xf])) - 1;
+  _backoff_start = (1 << (log2_backoff_start[(spu_args.nspus - 1) & 0xf])) - 1;
+  
+  backoff = _backoff_start;
+}
+
+static void 
+backoff_reset(void)
+{
+  backoff = _backoff_start;
+}
+
+static void
+backoff_delay(void)
+{
+  gc_cdelay(backoff);
+
+  // capped exponential backoff
+  backoff = ((backoff << 1) + 1) & _backoff_cap;
+}
+
+// ------------------------------------------------------------------------
+
+static inline unsigned int
+make_mask(int nbits)
+{
+  return ~(~0 << nbits);
+}
+
+static unsigned int   dc_work;
+static int            dc_put_tag;
+static unsigned char *dc_ls_base;
+static gc_eaddr_t     dc_ea_base;
+
+// divide and conquer
+static void
+d_and_c(unsigned int offset, unsigned int len)
+{
+  unsigned int mask = make_mask(len) << offset;
+  unsigned int t = mask & dc_work;
+  if (t == 0)          // nothing to do
+    return;
+  if (t == mask){      // got a match, generate dma
+    mfc_put(dc_ls_base + offset, dc_ea_base + offset, len, dc_put_tag, 0, 0);
+  }
+  else {               // bisect
+    len >>= 1;
+    d_and_c(offset, len);
+    d_and_c(offset + len, len);
+  }
+}
+
+// Handle the nasty case of a dma xfer that's less than 16 bytes long.
+// len is guaranteed to be in [1, 15]
+
+static void
+handle_slow_and_tedious_dma(gc_eaddr_t ea, unsigned char *ls,
+                           unsigned int len, int put_tag)
+{
+  // Set up for divide and conquer
+  unsigned int alignment = ((uintptr_t) ls) & 0x7;
+  dc_work = make_mask(len) << alignment;
+  dc_ls_base = (unsigned char *) ROUND_DN((uintptr_t) ls, 8);
+  dc_ea_base = ROUND_DN(ea, (gc_eaddr_t) 8);
+  dc_put_tag = put_tag;
+
+  d_and_c( 0, 8);
+  d_and_c( 8, 8);
+  d_and_c(16, 8);
+}
+
+
+static void
+process_job(gc_eaddr_t jd_ea, gc_job_desc_t *jd)
+{
+  // events: 0x2X
+
+  jd->status = JS_OK;  // assume success
+
+  if (jd->proc_id >= spu_args.nproc_defs)
+    jd->status = JS_UNKNOWN_PROC;
+    
+  else {
+  
+    if (jd->eaa.nargs == 0)
+      (*gc_proc_def[jd->proc_id].proc)(&jd->input, &jd->output, &jd->eaa);
+
+    else {     // handle EA args that must be DMA'd in/out
+
+      gc_job_ea_args_t *eaa = &jd->eaa;
+
+      int NELMS =
+       MAX(MAX_ARGS_EA,
+           (GC_SPU_BUFSIZE + MFC_MAX_DMA_SIZE - 1) / MFC_MAX_DMA_SIZE);
+
+      mfc_list_element_t  dma_get_list[NELMS];
+      //mfc_list_element_t  dma_put_list[NELMS];
+      
+      memset(dma_get_list, 0, sizeof(dma_get_list));
+      //memset(dma_put_list, 0, sizeof(dma_put_list));
+
+      int gli = 0;     // get list index
+      //int pli = 0;   // put list index
+
+      unsigned char *get_base = _gci_getbuf[0];
+      unsigned char *get_t = get_base;
+      unsigned int   total_get_dma_len = 0;
+
+      unsigned char *put_base = _gci_putbuf[pb_idx];
+      unsigned char *put_t = put_base;
+      unsigned int   total_put_alloc = 0;
+      int           put_tag = put_tags + pb_idx;
+
+      // Do we have any "put" args?  If so ensure that previous
+      // dma from this buffer is complete
+
+      gc_log_write2(GCL_SS_SYS, 0x24, put_in_progress, jd->sys.direction_union);
+
+      if ((jd->sys.direction_union & GCJD_DMA_PUT)
+         && (put_in_progress & PBI_MASK(pb_idx))){
+
+       gc_log_write2(GCL_SS_SYS, 0x25, put_in_progress, 1 << put_tag);
+
+       mfc_write_tag_mask(1 << put_tag);       // the tag we're interested in
+       mfc_read_tag_status_all();              // wait for DMA to complete
+       put_in_progress &= ~(PBI_MASK(pb_idx));
+
+       gc_log_write1(GCL_SS_SYS, 0x26, put_in_progress);
+      }
+
+
+      // for now, all EA's must have the same high 32-bits
+      gc_eaddr_t common_ea = eaa->arg[0].ea_addr;
+
+
+      // assign LS addresses for buffers
+      
+      for (unsigned int i = 0; i < eaa->nargs; i++){
+
+       gc_eaddr_t      ea_base = 0;
+       unsigned char  *ls_base;
+       int             offset;
+       unsigned int    dma_len;
+
+       if (eaa->arg[i].direction == GCJD_DMA_GET){
+         ea_base = ROUND_DN(eaa->arg[i].ea_addr, (gc_eaddr_t) CACHE_LINE_SIZE);
+         offset = eaa->arg[i].ea_addr & (CACHE_LINE_SIZE-1);
+         dma_len = ROUND_UP(eaa->arg[i].get_size + offset, CACHE_LINE_SIZE);
+         total_get_dma_len += dma_len;
+
+         if (total_get_dma_len > GC_SPU_BUFSIZE){
+           jd->status = JS_ARGS_TOO_LONG;
+           goto wrap_up;
+         }
+
+         ls_base = get_t;
+         get_t += dma_len;
+         eaa->arg[i].ls_addr = ls_base + offset;
+
+         if (0){
+           assert((mfc_ea2l(eaa->arg[i].ea_addr) & 0x7f) == ((intptr_t)eaa->arg[i].ls_addr & 0x7f));
+           assert((ea_base & 0x7f) == 0);
+           assert(((intptr_t)ls_base & 0x7f) == 0);
+           assert((dma_len & 0x7f) == 0);
+           assert((eaa->arg[i].get_size <= dma_len)
+                  && dma_len <= (eaa->arg[i].get_size + offset + CACHE_LINE_SIZE - 1));
+         }
+
+         // add to dma get list 
+         // FIXME (someday) the dma list is where the JS_BAD_EAH limitation comes from
+
+         while (dma_len != 0){
+           int n = MIN(dma_len, MFC_MAX_DMA_SIZE);
+           dma_get_list[gli].size = n;
+           dma_get_list[gli].eal = mfc_ea2l(ea_base);
+           dma_len -= n;
+           ea_base += n;
+           gli++;
+         }
+       }
+
+       else if (eaa->arg[i].direction == GCJD_DMA_PUT){
+         //
+         // This case is a trickier than the PUT case since we can't
+         // write outside of the bounds of the user provided buffer.
+         // We still align the buffers to 128-bytes for good performance
+         // in the middle portion of the xfers.
+         //
+         ea_base = ROUND_DN(eaa->arg[i].ea_addr, (gc_eaddr_t) CACHE_LINE_SIZE);
+         offset = eaa->arg[i].ea_addr & (CACHE_LINE_SIZE-1);
+
+         uint32_t ls_alloc_len =
+           ROUND_UP(eaa->arg[i].put_size + offset, CACHE_LINE_SIZE);
+
+         total_put_alloc += ls_alloc_len;
+
+         if (total_put_alloc > GC_SPU_BUFSIZE){
+           jd->status = JS_ARGS_TOO_LONG;
+           goto wrap_up;
+         }
+
+         ls_base = put_t;
+         put_t += ls_alloc_len;
+         eaa->arg[i].ls_addr = ls_base + offset;
+
+         if (1){
+           assert((mfc_ea2l(eaa->arg[i].ea_addr) & 0x7f)
+                  == ((intptr_t)eaa->arg[i].ls_addr & 0x7f));
+           assert((ea_base & 0x7f) == 0);
+           assert(((intptr_t)ls_base & 0x7f) == 0);
+         }
+       }
+
+       else
+         assert(0);
+      }
+
+      // fire off the dma to fetch the args and wait for it to complete
+      mfc_getl(get_base, common_ea, dma_get_list, gli*sizeof(dma_get_list[0]), get_tag, 0, 0);
+      mfc_write_tag_mask(1 << get_tag);                // the tag we're interested in
+      mfc_read_tag_status_all();               // wait for DMA to complete
+
+      // do the work
+      (*gc_proc_def[jd->proc_id].proc)(&jd->input, &jd->output, &jd->eaa);
+
+
+      // Do we have any "put" args?  If so copy them out
+      if (jd->sys.direction_union & GCJD_DMA_PUT){
+
+       // Do the copy out using single DMA xfers.  The LS ranges
+       // aren't generally contiguous.
+       
+       bool started_dma = false;
+
+       for (unsigned int i = 0; i < eaa->nargs; i++){
+         if (eaa->arg[i].direction == GCJD_DMA_PUT && eaa->arg[i].put_size != 0){
+           
+           started_dma = true;
+
+           gc_eaddr_t       ea;
+           unsigned char   *ls;
+           unsigned int     len;
+
+           ea = eaa->arg[i].ea_addr;
+           ls = (unsigned char *) eaa->arg[i].ls_addr;
+           len = eaa->arg[i].put_size;
+
+           if (len < 16)
+             handle_slow_and_tedious_dma(ea, ls, len, put_tag);
+           
+           else {
+             if ((ea & 0xf) != 0){
+
+               // printf("1:  ea = 0x%x  len = %5d\n", (int) ea, len);
+               
+               // handle the "pre-multiple-of-16" portion
+               // do 1, 2, 4, or 8 byte xfers as required
+
+               if (ea & 0x1){                          // do a 1-byte xfer
+                 mfc_put(ls, ea, 1, put_tag, 0, 0);
+                 ea += 1;
+                 ls += 1;
+                 len -= 1;
+               }
+               if (ea & 0x2){                          // do a 2-byte xfer
+                 mfc_put(ls, ea, 2, put_tag, 0, 0);
+                 ea += 2;
+                 ls += 2;
+                 len -= 2;
+               }
+               if (ea & 0x4){                          // do a 4-byte xfer
+                 mfc_put(ls, ea, 4, put_tag, 0, 0);
+                 ea += 4;
+                 ls += 4;
+                 len -= 4;
+               }
+               if (ea & 0x8){                          // do an 8-byte xfer
+                 mfc_put(ls, ea, 8, put_tag, 0, 0);
+                 ea += 8;
+                 ls += 8;
+                 len -= 8;
+               }
+             }
+
+             if (1){
+               // printf("2:  ea = 0x%x  len = %5d\n", (int) ea, len);
+               assert((ea & 0xf) == 0);
+               assert((((intptr_t) ls) & 0xf) == 0);
+             }
+
+             // handle the "multiple-of-16" portion
+
+             int aligned_len = ROUND_DN(len, 16);
+             len = len & (16 - 1);
+
+             while (aligned_len != 0){
+               int dma_len = MIN(aligned_len, MFC_MAX_DMA_SIZE);
+               mfc_put(ls, ea, dma_len, put_tag, 0, 0);
+               ea += dma_len;
+               ls += dma_len;
+               aligned_len -= dma_len;
+             }
+
+             if (1){
+               // printf("3:  ea = 0x%x  len = %5d\n", (int)ea, len);
+               assert((ea & 0xf) == 0);
+               assert((((intptr_t) ls) & 0xf) == 0);
+             }
+
+             // handle "post-multiple-of-16" portion
+
+             if (len != 0){
+
+               if (len >= 8){                          // do an 8-byte xfer
+                 mfc_put(ls, ea, 8, put_tag, 0, 0);
+                 ea += 8;
+                 ls += 8;
+                 len -= 8;
+               }
+               if (len >= 4){                          // do a 4-byte xfer
+                 mfc_put(ls, ea, 4, put_tag, 0, 0);
+                 ea += 4;
+                 ls += 4;
+                 len -= 4;
+               }
+               if (len >= 2){                          // do a 2-byte xfer
+                 mfc_put(ls, ea, 2, put_tag, 0, 0);
+                 ea += 2;
+                 ls += 2;
+                 len -= 2;
+               }
+               if (len >= 1){                          // do a 1-byte xfer
+                 mfc_put(ls, ea, 1, put_tag, 0, 0);
+                 ea += 1;
+                 ls += 1;
+                 len -= 1;
+               }
+               if (1)
+                 assert(len == 0);
+             }
+           }
+         }
+       }
+       if (started_dma){
+         put_in_progress |= PBI_MASK(pb_idx);          // note it's running
+         gc_log_write2(GCL_SS_SYS, 0x27, put_in_progress, pb_idx);
+         pb_idx ^= 1;                                  // toggle current buffer
+       }
+      }
+    }
+  }
+
+ wrap_up:;     // semicolon creates null statement for C99 compliance
+
+  // Copy job descriptor back out to EA.
+  // (The dma will be waited on in flush_completion_info)
+  int tag = ci_tags + ci_idx;                  // use the current completion tag
+  mfc_put(jd, jd_ea, sizeof(*jd), tag, 0, 0);
+
+  mfc_sync(tag);       // FIXME this makes it work, but is expensive
+
+  
+  // Tell PPE we're done with the job.
+  //
+  // We queue these up until we run out of room, or until we can send
+  // the info to the PPE w/o blocking.  The blocking check is in
+  // main_loop
+
+  comp_info.job_id[comp_info.ncomplete++] = jd->sys.job_id;
+
+  if (comp_info.ncomplete == GC_CI_NJOBS){
+    gc_log_write0(GCL_SS_SYS, 0x28);
+    flush_completion_info();
+  }
+}
+
+static void
+main_loop(void)
+{
+  // events: 0x1X
+
+  static gc_job_desc_t jd;     // static gets us proper alignment
+  gc_eaddr_t           jd_ea;
+  int                  total_jobs = 0;
+
+  // setup events
+  spu_writech(SPU_WrEventMask, MFC_LLR_LOST_EVENT);
+  gc_jd_queue_getllar(spu_args.queue); // get a line reservation on the queue
+
+  while (1){
+
+#if (USE_LLR_LOST_EVENT)
+
+    if (unlikely(spu_readchcnt(SPU_RdEventStat))){
+      //
+      // execute standard event handling prologue
+      //
+      int status = spu_readch(SPU_RdEventStat);
+      int mask = spu_readch(SPU_RdEventMask);
+      spu_writech(SPU_WrEventMask, mask & ~status);    // disable active events
+      spu_writech(SPU_WrEventAck, status);             // ack active events
+
+      // execute per-event actions
+
+      if (status & MFC_LLR_LOST_EVENT){
+       //
+       // We've lost a line reservation.  This is most likely caused
+       // by somebody doing something to the queue.  Go look and see
+       // if there's anything for us.
+       //
+       if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd))
+         process_job(jd_ea, &jd);
+
+       gc_jd_queue_getllar(spu_args.queue);    // get a new reservation
+      }
+
+      //
+      // execute standard event handling epilogue
+      //
+      spu_writech(SPU_WrEventMask, mask);      // restore event mask
+    }
+
+#else
+
+    // try to get a job from the job queue 
+    if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd)){
+      total_jobs++;
+      gc_log_write2(GCL_SS_SYS, 0x10, jd.sys.job_id, total_jobs);
+
+      process_job(jd_ea, &jd); 
+
+      gc_log_write2(GCL_SS_SYS, 0x11, jd.sys.job_id, total_jobs);
+      backoff_reset(); 
+    }
+    else
+      backoff_delay();
+
+#endif
+
+    // any msgs for us?
+
+    if (unlikely(spu_readchcnt(SPU_RdInMbox))){
+      int msg = spu_readch(SPU_RdInMbox);
+      // printf("spu[%d] mbox_msg: 0x%08x\n", spu_args.spu_idx, msg);
+      if (MBOX_MSG_OP(msg) == OP_EXIT){
+       flush_completion_info();
+       return;
+      }
+      if (MBOX_MSG_OP(msg) == OP_GET_SPU_BUFSIZE){
+       spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_SPU_BUFSIZE, GC_SPU_BUFSIZE_BASE));
+      }
+    }
+
+    // If we've got job completion info for the PPE and we can send a
+    // message without blocking, do it.
+
+    if (comp_info.ncomplete != 0 && spu_readchcnt(SPU_WrOutIntrMbox) != 0){
+      gc_log_write0(GCL_SS_SYS, 0x12);
+      flush_completion_info();
+    }
+  }
+}
+
+
+int
+main(unsigned long long spe_id __attribute__((unused)),
+     unsigned long long argp,
+     unsigned long long envp __attribute__((unused)))
+{
+  gc_sys_tag = mfc_tag_reserve();      // allocate a tag for our misc DMA operations
+  get_tag  = mfc_tag_reserve();
+  ci_tags  = mfc_multi_tag_reserve(2);
+  put_tags = mfc_multi_tag_reserve(2);
+
+#if 0  
+  printf("gc_sys_tag = %d\n", gc_sys_tag);
+  printf("get_tag    = %d\n", get_tag);
+  printf("ci_tags    = %d\n", ci_tags);
+  printf("put_tags   = %d\n", put_tags);
+#endif
+
+  // dma the args in
+  mfc_get(&spu_args, argp, sizeof(spu_args), gc_sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  // initialize pointer to procedure entry table
+  gc_proc_def = (gc_proc_def_t *) spu_args.proc_def_ls_addr;
+
+  // initialize logging
+  _gc_log_init(spu_args.log);
+
+  backoff_init();              // initialize backoff parameters
+
+  main_loop();
+  return 0;
+}
diff --git a/gcell/src/lib/runtime/spu/gc_spu_config.h b/gcell/src/lib/runtime/spu/gc_spu_config.h
new file mode 100644 (file)
index 0000000..997645e
--- /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.
+ */
+#ifndef INCLUDED_GC_SPU_CONFIG_H
+#define INCLUDED_GC_SPU_CONFIG_H
+
+#include <gc_job_desc.h>
+
+#define CACHE_LINE_SIZE             128              // in bytes
+#define        GC_SPU_BUFSIZE_BASE  (32 * 1024)      //  must be multiple of CACHE_LINE_SIZE
+#define        GC_SPU_BUFSIZE (GC_SPU_BUFSIZE_BASE + MAX_ARGS_EA * CACHE_LINE_SIZE)
+
+#define NGETBUFS       1       // single buffer job arg gets
+#define        NPUTBUFS        2       // double buffer job arg puts
+
+#endif /* INCLUDED_GC_SPU_CONFIG_H */
diff --git a/gcell/src/lib/runtime/spu/gc_spu_jd_queue.c b/gcell/src/lib/runtime/spu/gc_spu_jd_queue.c
new file mode 100644 (file)
index 0000000..ba4a1b9
--- /dev/null
@@ -0,0 +1,103 @@
+/* -*- 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 this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "gc_jd_queue.h"
+#include "mutex_lock.h"
+#include "mutex_unlock.h"
+
+extern int gc_sys_tag;
+
+bool
+gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item)
+{
+  gc_jd_queue_t        local_q;
+
+  // Before aquiring the lock, see if it's possible that there's
+  // something in the queue.  Checking in this way makes it easier
+  // for the PPE to insert things, since we're not contending for
+  // the lock unless there is something in the queue.
+
+  // copy in the queue structure
+  mfc_get(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  if (local_q.head == 0){              // empty
+    return false;
+  }
+
+  // When we peeked, head was non-zero.  Now grab the
+  // lock and do it for real.
+
+  _mutex_lock(q + offsetof(gc_jd_queue_t, mutex));
+
+  // copy in the queue structure
+  mfc_get(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  if (local_q.head == 0){              // empty
+    _mutex_unlock(q + offsetof(gc_jd_queue_t, mutex));
+    return false;
+  }
+
+  // copy in job descriptor at head of queue
+  *item_ea = local_q.head;
+  mfc_get(item, local_q.head, sizeof(gc_job_desc_t), gc_sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  local_q.head = item->sys.next;
+  item->sys.next = 0;
+  if (local_q.head == 0)               // now empty?
+    local_q.tail = 0;
+
+
+  // copy the queue structure back out
+  mfc_put(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0);
+  mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in
+  mfc_read_tag_status_all();           // wait for DMA to complete
+
+  // Q: FIXME do we need to order stores in EA or can we just clear the
+  // local copy of the mutex above and blast it out, removing the need
+  // for this explicit unlock?
+  //
+  // A: Manual says it's better to use an atomic op rather than
+  // a normal DMA, and that a putlluc is better than a putllc if
+  // you can use it.
+
+  _mutex_unlock(q + offsetof(gc_jd_queue_t, mutex));
+  return true;
+}
+
+
+void
+gc_jd_queue_getllar(gc_eaddr_t q)
+{
+  // get reservation that includes the tail of the queue
+  gc_eaddr_t   tail = q + offsetof(gc_jd_queue_t, tail);
+    
+  char _tmp[256];
+  char *buf = (char *) ALIGN(_tmp, 128);       // get cache-aligned buffer
+
+  mfc_getllar(buf, ALIGN128_EA(tail), 0, 0);
+  spu_readch(MFC_RdAtomicStat);
+}
diff --git a/gcell/src/lib/runtime/spu/gcell_qa.c b/gcell/src/lib/runtime/spu/gcell_qa.c
new file mode 100644 (file)
index 0000000..51bf38a
--- /dev/null
@@ -0,0 +1,109 @@
+/* -*- 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 <gc_delay.h>
+#include <gc_declare_proc.h>
+#include <string.h>
+
+
+#define _UNUSED __attribute__((unused))
+
+// FIXME move these out of here; only for QA usage
+
+static void
+qa_nop(const gc_job_direct_args_t *input _UNUSED,
+       gc_job_direct_args_t *output _UNUSED,
+       const gc_job_ea_args_t *eaa _UNUSED)
+{
+}
+
+GC_DECLARE_PROC(qa_nop, "qa_nop");
+
+static int
+sum_shorts(short *p, int nshorts)
+{
+  int total = 0;
+  for (int i = 0; i < nshorts; i++)
+    total += p[i];
+
+  return total;
+}
+
+static void
+qa_sum_shorts(const gc_job_direct_args_t *input _UNUSED,
+             gc_job_direct_args_t *output,
+             const gc_job_ea_args_t *eaa)
+{
+  for (unsigned int i = 0; i < eaa->nargs; i++){
+    short *p = eaa->arg[i].ls_addr;
+    int n = eaa->arg[i].get_size / sizeof(short);
+    output->arg[i].s32 = sum_shorts(p, n);
+    //printf("qa_sum_shorts(%p, %d) = %d\n",  p, n, output->arg[i].s32);
+  }
+}
+
+GC_DECLARE_PROC(qa_sum_shorts, "qa_sum_shorts");
+
+static void
+write_seq(unsigned char *p, int nbytes, int counter)
+{
+  for (int i = 0; i < nbytes; i++)
+    p[i] = counter++;
+}
+
+static void
+qa_put_seq(const gc_job_direct_args_t *input,
+          gc_job_direct_args_t *output _UNUSED,
+          const gc_job_ea_args_t *eaa)
+{
+  int counter = input->arg[0].s32;
+
+  for (unsigned int i = 0; i < eaa->nargs; i++){
+    unsigned char *p = eaa->arg[i].ls_addr;
+    int n = eaa->arg[i].put_size;
+    write_seq(p, n, counter);
+    counter += n;
+  }
+}
+
+GC_DECLARE_PROC(qa_put_seq, "qa_put_seq");
+
+static void
+qa_copy(const gc_job_direct_args_t *input _UNUSED,
+       gc_job_direct_args_t *output,
+       const gc_job_ea_args_t *eaa)
+{
+  if (eaa->nargs != 2
+      || eaa->arg[0].direction != GCJD_DMA_PUT
+      || eaa->arg[1].direction != GCJD_DMA_GET){
+    output->arg[0].s32 = -1;
+    return;
+  }
+
+  output->arg[0].s32 = 0;
+  unsigned n = eaa->arg[0].put_size;
+  if (eaa->arg[1].get_size < n)
+    n = eaa->arg[1].get_size;
+  
+  memcpy(eaa->arg[0].ls_addr, eaa->arg[1].ls_addr, n);
+}
+
+GC_DECLARE_PROC(qa_copy, "qa_copy");
diff --git a/gcell/src/lib/runtime/spu/spu_buffers.c b/gcell/src/lib/runtime/spu/spu_buffers.c
new file mode 100644 (file)
index 0000000..58b4059
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- 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 <spu_buffers.h>
+#include <compiler.h>
+
+static unsigned char _getbuf[NGETBUFS][GC_SPU_BUFSIZE] _AL128;
+static unsigned char _putbuf[NPUTBUFS][GC_SPU_BUFSIZE] _AL128;
+
+unsigned char *_gci_getbuf[NGETBUFS] = {
+  _getbuf[0]
+};
+
+unsigned char *_gci_putbuf[NPUTBUFS] = {
+  _putbuf[0],
+  _putbuf[1]
+};
diff --git a/gcell/src/lib/runtime/spu/spu_buffers.h b/gcell/src/lib/runtime/spu/spu_buffers.h
new file mode 100644 (file)
index 0000000..24811dc
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- 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_SPU_BUFFERS_H
+#define INCLUDED_SPU_BUFFERS_H
+
+#include "gc_spu_config.h"
+
+//! pointer to input buffer
+extern unsigned char *_gci_getbuf[NGETBUFS];
+
+//! pointers to output buffers
+extern unsigned char *_gci_putbuf[NPUTBUFS];
+
+#endif /* INCLUDED_SPU_BUFFERS_H */
diff --git a/gcell/src/lib/spu/Makefile.am b/gcell/src/lib/spu/Makefile.am
new file mode 100644 (file)
index 0000000..fac057c
--- /dev/null
@@ -0,0 +1,103 @@
+#
+# 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.
+#
+
+# We're building a single .a file from files in several
+# subdirectories.  We use the "single Makefile, multiple subdirectory"
+# automake alternative. We're doing this because we're faking out
+# automake and getting it to build for 2 architectures at the same
+# time, the PPE (powerpc64) and the SPE.  The easiest way to handle
+# the SPE was to just build a static library using automake's built in
+# rules, since trying to get libtool to handle two architectures in
+# the same tree seemed untenable.
+
+include $(top_srcdir)/Makefile.common.spu
+
+IBM_SPU_SYNC_INCLUDES = -I$(top_srcdir)/gcell/src/ibm/sync/spu_source
+AM_CPPFLAGS = $(GCELL_SPU_INCLUDES) $(IBM_SPU_SYNC_INCLUDES)
+
+lib_LIBRARIES = libgcell_spu.a
+
+# ----------------------------------------------------------------
+# files in the lib/runtime/spu directory
+
+runtime_srcdir = $(srcdir)/../runtime/spu
+
+runtime_spu_sources = \
+       $(runtime_srcdir)/gc_delay.c \
+       $(runtime_srcdir)/gc_spu_jd_queue.c \
+       $(runtime_srcdir)/spu_buffers.c \
+       $(runtime_srcdir)/gc_logging.c \
+       $(runtime_srcdir)/gc_main.c
+
+runtime_spu_headers =
+
+runtime_spu_noinst_headers = \
+       $(runtime_srcdir)/gc_spu_config.h \
+       $(runtime_srcdir)/spu_buffers.h 
+
+# ----------------------------------------------------------------
+# files in the lib/general/spu directory
+
+general_srcdir = $(srcdir)/../general/spu
+
+general_spu_sources =
+
+general_spu_headers =
+
+general_spu_noinst_headers =
+
+
+# ----------------------------------------------------------------
+# files in the lib/procs/spu directory
+
+procs_srcdir = $(srcdir)/../proc/spu
+
+procs_spu_sources =
+
+procs_spu_headers =
+
+procs_spu_noinst_headers =
+
+# ----------------------------------------------------------------
+# build the library from the files in the three directories
+
+libgcell_spu_a_SOURCES = \
+       $(runtime_spu_sources) \
+       $(general_spu_sources) \
+       $(procs_spu_sources)
+
+gcellspuinclude_HEADERS = \
+       $(runtime_spu_headers) \
+       $(general_spu_headers) \
+       $(procs_spu_headers)
+
+noinst_HEADERS = \
+       $(runtime_spu_noinst_headers) \
+       $(general_spu_noinst_headers) \
+       $(procs_spu_noinst_headers)
+
+# ----------------------------------------------------------------
+# SPU executable containing QA code
+
+noinst_PROGRAMS = \
+       gcell_qa
+
+gcell_qa_SOURCES = $(runtime_srcdir)/gcell_qa.c
+gcell_qa_LDADD = libgcell_spu.a
index 38f9362eea19baacba5292686aebb0b2cb6380c7..8035d856570a1672416ba8747c48f7d46d8d672b 100644 (file)
@@ -1,5 +1,5 @@
 //
-// This file is machine generated from fpga_regs_common.h
+// This file is machine generated from ./fpga_regs_common.h
 // Do not edit by hand; your edits will be overwritten.
 //
 
index b88bcddc1d13a28a6bcdf9ef7a848e6ca2d6a5f9..d09aa6116c829916c0cd76353a8f26acc9a35d5e 100644 (file)
@@ -1,5 +1,5 @@
 //
-// This file is machine generated from fpga_regs_standard.h
+// This file is machine generated from ./fpga_regs_standard.h
 // Do not edit by hand; your edits will be overwritten.
 //